我正在使用 OpenGL + GLSL 着色器编写图形引擎。目前,我在我的场景中管理多个灯光(每像素照明模式)。所以,我有一个循环来访问场景中每个像素的所有灯光的属性。如果我将光计数值直接放在循环条件中没有问题,但如果我想通过从我的 C++ 代码发送一个整数统一变量以动态方式完成这项工作,它就不起作用。但是我在片段着色器中检查了变量的值,这个值是正确的。在下面的示例中,我的灯列表的大小为 1。
这是我的 C++ 代码:
ShaderProgram *program = (*Ite).second->getShaderProgram();
program->bind();
program->setUniform("spotCount", (int)this->m_Scene->getLightList().size()); //1 in my example
我的顶点着色器代码:
#version 400
layout (location = 0) in vec3 VertexPosition;
layout (location = 1) in vec3 VertexNormal;
layout (location = 2) in vec2 VertexTexture;
uniform mat4 ProjectionMatrix;
uniform mat3 NormalMatrix;
uniform mat4 ModelViewMatrix;
uniform mat4 MVP;
out vec3 VPosition;
out vec3 VNormal;
out vec2 VTexCoords;
void main(void)
{
VTexCoords = VertexTexture;
VNormal = normalize(NormalMatrix * VertexNormal);
VPosition = vec3(ModelViewMatrix * vec4(VertexPosition, 1.0f));
gl_Position = MVP * vec4(VertexPosition, 1.0f);
}
最后,我的片段着色器代码:
#version 400
in vec3 Position;
in vec3 Normal;
in vec2 TexCoords;
layout (location = 0) out vec4 FragColor;
uniform sampler2D Tex1;
uniform int spotCount;
struct Light
{
vec4 Position;
vec3 La, Ld, Ls;
};
uniform Light LightInfos[1];
struct Material
{
vec3 Ka, Kd, Ks, Ke;
float Shininess;
};
uniform Material MaterialInfos;
vec3 ADS_Phong_Shading(int idx, vec3 n, vec3 s)
{
vec3 v = normalize(vec3(-Position));
vec3 h = normalize(v + s);
vec3 Ambient = LightInfos[idx].La * MaterialInfos.Ka;
vec3 Diffuse = LightInfos[idx].Ld * MaterialInfos.Kd * max(dot(s, n), 0.0f);
vec3 Specular = LightInfos[idx].Ls * MaterialInfos.Ks * pow(max(dot(h, n), 0.0f), MaterialInfos.Shininess);
vec3 Emissive = MaterialInfos.Ke;
return (Ambient + Diffuse + Specular + Emissive);
}
void main(void)
{
vec4 TexColor = texture(Tex1, TexCoords);
vec3 LightIntensity = vec3(0.0f);
vec3 position = vec3(0.0f);
if (spotCount == 1) { //Here a stupid condition proving that spotCount = 1
for (int idx = 0; idx < spotCount; idx++)
{
vec3 tnorm = (gl_FrontFacing ? -normalize(Normal) : normalize(Normal));
if (LightInfos[idx].Position.w == 0.0f)
position = normalize(vec3(LightInfos[idx].Position));
else if (LightInfos[idx].Position.w == 1.0f)
{
position = normalize(vec3(LightInfos[idx].Position) - Position);
}
LightIntensity += ADS_Phong_Shading(idx, -tnorm, position);
}
}
if (TexColor != 0)
FragColor = vec4(LightIntensity, 1.0f) * TexColor;
else
FragColor = vec4(LightIntensity, 1.0f);
}
如果我替换代码,在片段着色器代码中:
for (int idx = 0; idx < spotCount; idx++)
通过以下代码:
for (int idx = 0; idx < 1; idx++)
我的场景正确显示。
如果我使用指令,这是一张图片: for (int idx = 0; idx < spotCount; idx++) (NOT CORRECT) -> spotCount == 1 :
并使用 (int idx = 0; idx < 1; idx++) (CORRECT) 的指令:
总之,对于这两种情况,我的迭代次数相同,但结果不同。
有人可以帮助我吗?非常感谢您的帮助。