1

我正在使用 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) 的指令:

在此处输入图像描述

总之,对于这两种情况,我的迭代次数相同,但结果不同。

有人可以帮助我吗?非常感谢您的帮助。

4

0 回答 0