Hey guys, thank u for all reply.
English is not my native language and I find it difficult to express myself.
But come on, following the learnopengl tutorial:
https://learnopengl.com/Advanced-Lighting/Deferred-Shading
the author leaves fixed the amount of light (32 lights) as shown by the GLSL:
#version 330 core
out vec4 FragColor;
in vec2 TexCoords;
uniform sampler2D gPosition;
uniform sampler2D gNormal;
uniform sampler2D gAlbedoSpec;
struct Light {
vec3 Position;
color;
};
const int NR_LIGHTS = 32;
uniform Light lights [NR_LIGHTS];
uniform vec3 viewPos;
void main ()
{
// retrieve data from G-buffer
vec3 FragPos = texture (gPosition, TexCoords) .rgb;
vec3 Normal = texture (gNormal, TexCoords) .rgb;
vec3 Albedo = texture (gAlbedoSpec, TexCoords) .rgb;
float Specular = texture (gAlbedoSpec, TexCoords) .a;
// then calculate lighting as usual
vec3 lighting = Albedo * 0.1; // hard-coded ambient component
vec3 viewDir = normalize (viewPos - FragPos);
for (int i = 0; i <NR_LIGHTS; ++ i)
{
// diffuse
vec3 lightDir = normalize (lights [i] .Position - FragPos);
vec3 diffuse = max (dot (Normal, lightDir), 0.0) * Albedo * lights [i] .Color;
lighting + = diffuse;
}
FragColor = vec4 (lighting, 1.0);
}
And when it comes to applying the lights:
glBindFramebuffer (GL_FRAMEBUFFER, 0);
// 2. lighting pass: calculate lighting by iterating over screen filled quad pixel-by-pixel using the gbuffer's content.
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
shaderLightingPass.use ();
glActiveTexture (GL_TEXTURE0);
glBindTexture (GL_TEXTURE_2D, gPosition);
glActiveTexture (GL_TEXTURE1);
glBindTexture (GL_TEXTURE_2D, gNormal);
glActiveTexture (GL_TEXTURE2);
glBindTexture (GL_TEXTURE_2D, gAlbedoSpec);
// send light relevant uniforms
for (unsigned int i = 0; i <lightPositions.size (); i ++)
{
shaderLightingPass.setVec3 ("lights [" + std :: to_string (i) + "] .Position", lightPositions [i]);
shaderLightingPass.setVec3 ("lights [" + std :: to_string (i) + "] .Color", lightColors [i]);
// update attenuation parameters and calculate radius
const float constant = 1.0; // note that we do not send this to the shader, we assume it is always 1.0 (in our case)
const float linear = 0.7;
const float quadratic = 1.8;
shaderLightingPass.setFloat ("lights [" + std :: to_string (i) + "] .Linear", linear);
shaderLightingPass.setFloat ("lights [" + std :: to_string (i) + "] .Quadratic", quadratic);
}
shaderLightingPass.setVec3 ("viewPos", camera.Position);
// finally render quad
renderQuad ();
I wish I could do this:
uniform Light lights;
uniform vec3 viewPos;
void main ()
{
// retrieve data from gbuffer
vec3 FragPos = texture (gPosition, TexCoords) .rgb;
vec3 Normal = texture (gNormal, TexCoords) .rgb;
vec3 Diffuse = texture (gAlbedoSpec, TexCoords) .rgb;
float Specular = texture (gAlbedoSpec, TexCoords) .a;
// then calculate lighting as usual
vec3 lighting = Diffuse * 0.1; // hard-coded ambient component
vec3 viewDir = normalize (viewPos - FragPos);
// diffuse
vec3 lightDir = normalize (lights.Position - FragPos);
vec3 diffuse = max (dot (Normal, lightDir), 0.0) * Diffuse * lights.Color;
// specular
vec3 halfwayDir = normalize (lightDir + viewDir);
float spec = pow (max (dot (Normal, halfwayDir), 0.0), 16.0);
vec3 specular = lights.Color * spec * Specular;
// attenuation
float distance = length (lights.Position - FragPos);
float attenuation = 1.0 / (1.0 + lights.Linear * distance + lights.Quadratic * distance * distance);
diffuse * = attenuation;
specular * = attenuation;
lighting + = diffuse + specular;
FragColor = vec4 (lighting, 1.0);
}
And in C ++:
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
shaderLightingPass.use();
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, gPosition);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, gNormal);
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, gAlbedoSpec);
// send light relevant uniforms
for (unsigned int i = 0; i < lightPositions.size(); i++)
{
shaderLightingPass.setVec3("lights.Position", lightPositions[i]);
shaderLightingPass.setVec3("lights.Color", lightColors[i]);
// update attenuation parameters and calculate radius
const float constant = 1.0; // note that we don't send this to the shader, we assume it is always 1.0 (in our case)
const float linear = 0.7;
const float quadratic = 1.8;
shaderLightingPass.setFloat("lights.Linear", linear);
shaderLightingPass.setFloat("lights.Quadratic", quadratic);
shaderLightingPass.setVec3("viewPos", camera.Position);
//My doubt is here
}
renderQuad();
My doubt is here, as I apply the lights above in the framebuffer, as if it were:
configures light, persists in framebuffer, configures light, persists in framebuffer, configures light, persists in framebuffer, configures light, persists in framebuffer ....
I'm sorry if I'm bothering too much, but this is very complicated to understand only in theory.