我一直在透视投影的眼睛空间坐标中的片段着色器中进行光照计算(同时连接了顶点着色器和片段着色器),并且效果很好。
但是当正投影或(FOV)使用相同的着色器时,透视投影(10度FOV)的视场会减小,则效果不佳。阴影变得怪异。
到目前为止,我的理解是,由于正交投影的工作方式,因此在fragemt着色器中眼坐标导数的计算变得毫无意义,并且眼坐标位置的导数始终为零(在边缘除外)(如果我错了,请更正我,因为我在使用计算机图形和OpenGL方面经验有限。 我也无法弄清楚如何正确地做到这一点。如果有人可以指出我正确的信息来源,那就太好了。
顶点着色器
#version 330 core
layout (location = 0) in vec3 vertex_position;
uniform mat4 transform_matrix;
uniform mat4 view_matrix;
uniform mat4 model_matrix;
out vec3 ec_pos;
void main()
{
gl_Position = (view_matrix*transform_matrix*model_matrix*vec4(vertex_position, 1.0));
ec_pos = gl_Position.xyz;
}
片段着色器
#version 330 core
out vec4 FragColor;
uniform vec3 objectColor;
in vec3 ec_pos;
void main()
{
vec3 lightColor = vec3(0.99,0.96,0.89);
vec3 lightPos = vec3(0,0,0,1);
vec3 ec_normal = normalize(cross(dFdx(ec_pos), dFdy(ec_pos)));
float diff = max(dot(ec_normal, lightPos), 0.0);
vec3 diffuse = diff * lightColor;
vec3 result = diffuse * objectColor;
FragColor = vec4(result, 1.0);
}
答案 0 :(得分:1)
我已经解决了自己的问题,方法是在相机坐标空间中进行计算(即在应用投影变换之前)。这是正确的代码:
顶点着色器:
void main()
{
vec4 mcPos = model_matrix*vec4(vertex_position, 1.0);
vec4 wcPos = transform_matrix*vec4(mcPos);
gl_Position = view_matrix*wcPos;
mc_pos = mcPos.xyz;
wc_pos = wcPos.xyz;
}
片段着色器:
#version 330 core
out vec4 FragColor;
uniform vec3 objectColor;
in vec3 mc_pos;
in vec3 wc_pos;
void main()
{
vec3 lightColor = vec3(0.99,0.96,0.89);
vec3 lightPos = vec3(0,0,1);
vec3 wc_normal = normalize(cross(dFdx(wc_pos), dFdy(wc_pos)));
float diff = max(dot(wc_normal, lightPos), 0.0);
vec3 diffuse = (diff) * lightColor;
vec3 result = ( diffuse ) * objectColor;
FragColor = vec4(result, 1.0);
}
正确的阴影