multiple lights

Below, you'll find code snippets that outline a basic approach to dynamic light management. These examples are intended to inspire and guide you as you implement your own solutions.

before you get started read this article: https://learnopengl.com/Lighting/Multiple-lights

1. Maximum Number of Lights

Start by defining the maximum number of point lights your system will support:

#define MAX_POINT_LIGHTS 4

2. Light Structure

Here’s a structure to define light properties:


struct Light {
    vec3 position;   // Light position
    vec3 ambient;    // Ambient color component
    vec3 diffuse;    // Diffuse color component
    vec3 specular;   // Specular color component
    float constant;  // Attenuation constant
    float linear;    // Attenuation linear coefficient
    float quadratic; // Attenuation quadratic coefficient
};
            

3. Updating Light Information

Use this function to update light properties based on their distance from the camera:


void UpdateLights(float maxLightDistance) {
    for (int i = 0; i < numLights; i++) {
        Light light = lights[i];
        
        // Calculate distance from the camera
        float distance = length(cameraPosition - light.position);
        
        if (distance > maxLightDistance) {
            // Light is too far; ignore it
            lightIntensity[i] = 0.0;
        } else {
            // Calculate attenuation factor
            float attenuation = 1.0 / (light.constant + light.linear * distance + light.quadratic * distance * distance);
            lightIntensity[i] = attenuation;
        }
        
        // Update shader with light data
        UpdateShaderLightData(i, light);
    }
}
            

4. Updating Shader Light Data

This function sends updated light data to the shader:


void UpdateShaderLightData(int index, Light light) {
    glUseProgram(shaderProgram);
    
    // Update light properties in the shader
    std::string uniformName = "pointLights[" + std::to_string(index) + "].position";
    glUniform3fv(glGetUniformLocation(shaderProgram, uniformName.c_str()), 1, &light.position[0]);
    
    uniformName = "pointLights[" + std::to_string(index) + "].ambient";
    glUniform3fv(glGetUniformLocation(shaderProgram, uniformName.c_str()), 1, &light.ambient[0]);
    
    uniformName = "pointLights[" + std::to_string(index) + "].diffuse";
    glUniform3fv(glGetUniformLocation(shaderProgram, uniformName.c_str()), 1, &light.diffuse[0]);
    
    uniformName = "pointLights[" + std::to_string(index) + "].specular";
    glUniform3fv(glGetUniformLocation(shaderProgram, uniformName.c_str()), 1, &light.specular[0]);
    
    uniformName = "pointLights[" + std::to_string(index) + "].constant";
    glUniform1f(glGetUniformLocation(shaderProgram, uniformName.c_str()), light.constant);
    
    uniformName = "pointLights[" + std::to_string(index) + "].linear";
    glUniform1f(glGetUniformLocation(shaderProgram, uniformName.c_str()), light.linear);
    
    uniformName = "pointLights[" + std::to_string(index) + "].quadratic";
    glUniform1f(glGetUniformLocation(shaderProgram, uniformName.c_str()), light.quadratic);
    
    uniformName = "pointLights[" + std::to_string(index) + "].intensity";
    glUniform1f(glGetUniformLocation(shaderProgram, uniformName.c_str()), lightIntensity[index]);
}
            

5. Main Rendering Loop

Incorporate light updates into your main rendering loop:


void RenderScene() {
    UpdateLights(maxLightDistance);
    
    // Proceed with rendering the scene
}
            

edit this page