聚光灯效果在使用GLSL着色器时无法正常工作。

4

我正在开发一个个人图形引擎,并开始开发聚光灯。问题是渲染不太合理。为了简单起见,我在以下着色器示例中清除了有关光线和纹理管理的所有信息。

以下是顶点着色器代码:

#version 400

layout (location = 0) in vec3 VertexPosition;

uniform mat4 ModelViewMatrix;
uniform mat4 MVP;

out vec3 VPosition;

void main(void)
{
    VPosition = vec3(ModelViewMatrix * vec4(VertexPosition, 1.0f));     //Eye coordinates vertex position
    gl_Position = MVP * vec4(VertexPosition, 1.0f);
}

这是片段着色器的代码:

#version 400

in vec3 Position;   //IN EYE COORDINATES

layout (location = 0) out vec4 FragColor;

uniform int lightCount;

struct SpotLight
{
    vec4 Position;      //ALREADY IN EYE COORDINATES
    vec3 La, Ld, Ls;
    vec3 direction;
    float exponent;
    float cutoff;
};

uniform SpotLight LightInfos[1];

vec3 getLightIntensity(void)
{
    vec3 LightIntensity = vec3(0.0f);

    for (int idx = 0; idx < lightCount; idx++)
    {
        vec3 lightDirNorm = normalize(vec3(LightInfos[idx].Position) - Position);
        vec3 spotDirNorm = normalize(LightInfos[idx].direction);
        float angle = acos(dot(-lightDirNorm, spotDirNorm));
        float cutoff = radians(clamp(LightInfos[idx].cutoff, 0.0f, 90.0f));

        vec3 ambient = vec3(0.1f, 0.1f, 0.8f);      //Color out of the spotlight's cone.
        vec3 spotColor = vec3(0.1f, 0.8f, 0.1f);    //Color within the spotlight's cone.

        if (angle < cutoff)
        {
            LightIntensity = spotColor;
        }
        else
        {
            LightIntensity = ambient;
        }
    }
    return (LightIntensity);
}

void main(void)
{
    FragColor = vec4(getLightIntensity(), 1.0f);
}

以下是我发送光源位置属性的 C++ 代码:
glm::vec4 lightPositionVec = viewMatrix * glm::vec4(lightPosition[0], lightPosition[1], lightPosition[2], lightPosition[3]);

program->setUniform(std::string("LightInfos[").append(Utils::toString<int>(idx)).append("].Position").c_str(), lightPositionVec);

这是聚光灯的属性:
<position x="0.0" y="2.0" z="0.0" w="1" />
<direction x="0.0" y="-1.0" z="0.0" />
<exponent>3.0</exponent>
<cutoff>50.0</cutoff>

视图属性:
<camera name="cam1">
  <perspective fovy="70.0" ratio="1.0" nearClipPlane="0.1" farClipPlane="1000.0"/>
  <lookat>
     <eye x="0.0" y="50.0" z="50.0" />
     <target x="0.0" y="0.0" z="0.0" />
     <up x="0.0" y="1.0" z="0.0"/>
  </lookat>
</camera>

在将这些信息发送到C++代码中的着色器程序之前,我已经检查了它们,并且它们是正确的。

这是结果:

enter image description here

如果我将摄像机靠近平面,并使用以下摄像机属性:

 <camera name="cam1">
      <perspective fovy="70.0" ratio="1.0" nearClipPlane="0.1" farClipPlane="1000.0"/>
      <lookat>
         <eye x="0.0" y="10.0" z="20.0" />
         <target x="0.0" y="0.0" z="0.0" />
         <up x="0.0" y="1.0" z="0.0"/>
      </lookat>
    </camera>

结果如下(更接近现实但仍不正确): enter image description here 如您所见,这是不合逻辑的:我在x=0,y=1,z=0处有一个点,一个向下的聚光灯方向(x=0,y=-1,z=0),所以我不明白这个结果。另外,所有我的向量都是在眼坐标系中。我有一种感觉,聚光灯效果取决于相机的位置。有人可以帮助我吗?

你在哪里将光参数转换为眼坐标? - Nico Schertler
在我的C++代码中,我更新了问题。但是聚光灯的位置是正确的,因为在开始聚光灯之前,我从点光源开始,并且一切都是正确的。这里的问题似乎来自片段着色器中“角度”和“截止”变量的计算。 - user1364743
glm::vec4 lightPositionVec = viewMatrix * glm::vec4... 这里应该是modelView矩阵,将光源位置转换为眼坐标。顺便说一下,你可以使用LightInfos[idx].Position.xyz代替vec3(LightInfos[idx].Position),这通常更易读 :) - Jaa-c
谢谢你的回答。我已经使用modelViewMatrix修改了我的代码,但显示仍然是一样的! - user1364743
2
你是否也转换光线方向? - Nico Schertler
非常感谢!我忘记转换它了。再见。 - user1364743
2个回答

1

避免发布仅包含链接的答案。虽然它们可能是正确的,但如果链接发生更改/中断,答案的完整性将会受到损害。尝试包含您所发布链接中的任何相关代码。 - Tim Lewis
尽管Tim所说的是真的,但感谢第二个链接,这正是我在寻找的! - elect
Tim Lewis:好的,下次会做到。 - Jesse Stone

0

问题在于两者之间的差异吗?

out vec3 VPosition;

并且

in vec3 Position;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接