OpenGL,漫反射着色器

4

我将尝试在GLSL/OpenGL中实现非常简单的漫反射着色器。 以下是我所得到的: 顶点着色器:

#version 130

in vec3 vertPos3D;
in vec3 vertNormal3D;

uniform mat3 transpMatrix;
uniform mat4 projectionMatrix;
uniform mat4 viewMatrix;

uniform vec3 lightPosition;

varying vec3 vertNormal;
varying vec3 lightVector;

void main() 
{ 
    vec4 res_pos = projectionMatrix * viewMatrix * vec4(vertPos3D.xyz, 1.0);
    gl_Position = res_pos;
    mat4 pm = projectionMatrix * viewMatrix;
    vertNormal = (viewMatrix * vec4(vertNormal3D, 0)).xyz;
    lightVector = (viewMatrix * vec4(lightPosition, 1.0)).xyz - (viewMatrix * vec4(vertPos3D.xyz, 1.0)).xyz;
}

片元着色器:

#version 130
out vec4 color; 

varying vec3 lightVector;
varying vec3 vertNormal;
void main()
{
    float dot_product = max(normalize(dot(lightVector, vertNormal)), 0.0);
    color = dot_product * vec4( 1.0, 1.0, 1.0, 1.0 );
}

当我把最终颜色与点积相乘时,什么都不显示。如果我去掉点积,一切正常(除了漫反射光线)。我担心我错过了一些显而易见的东西。

着色器编译/链接日志中有什么信息吗? - genpfault
2个回答

4
一个问题:
normalize(dot(lightVector, vertNormal))
GLSL 1.3中的dot返回一个浮点数。
normalize接受一个向量,而不是一个浮点数。
dot的文档
normalize的文档

至少对于这个问题的解决方案:

在片段着色器中,将代码替换为:

float dot_product = max(normalize(dot(lightVector, vertNormal)), 0.0);

使用

float dot_product = clamp(dot(lightVector, vertNormal), 0., 1.);

看起来你正在使用max和normalize来避免dot返回负数。这正是clamp的用途。这里是clamp文档


谢谢您的建议,我修改了那行代码,但总体上没有任何改变。 :( - user1760770
好的,片段着色器中的 varying 应该改为 attribute,因为它是输入而不是输出。我已经编辑了上面的代码。现在可以工作了吗? - Dylan Holmes
“好的,片段着色器中的变量应该是属性(attribute),因为它是输入而不是输出。” - 不,它不应该是属性(attribute),因为它是一个varying,而不是顶点属性(vertex attribute)。 - Christian Rau
1
实际上1.30版本已经有了in/out,所以不要再使用这些过时的attribute/varying了。 - Christian Rau
@user1760770 如果你想检查你的向量,只需将它们打印出来。这样你就可以看到它们是否正确了。 - djmj
显示剩余3条评论

2

使用

float dot_product = max(dot(normalize(lightVector), normalize(normalVector)), 0.0);

Dylan Holmes 的回答略微不正确:

仍需要对 lightVector 进行归一化!

而且夹紧是不必要的。 max 是正确的。 如果输入向量被归一化,则点积永远不会返回高于 1.0 的值。


1
准确来说:“点积的结果永远不会高于1.0”只有在向量被归一化的情况下才是正确的,而且vertNormal仍然需要被归一化,因为它是插值出来的值,而不是应用程序提供的法线。 - keltar
在你的评论之前,我已经将这些信息添加到了有关点积的答案中。着色器编程对我来说已经是几年前的事情了,所以我不确定是否必要。 - djmj
@djmj,标准化确实是我忘了,感谢你指出clamp/max的问题。 - Dylan Holmes

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