GLSL每像素点光照明。

4

VC++, OpenGL, SDL

我想知道是否有一种方法可以在单个几何体的四边形上实现更加平滑的着色。目前,我的点光源下着色看起来很平滑,但是沿着面的 [/] 对角线细分的强度上升。在顶点之间,光线基本上是不可见的。

enter image description here

enter image description here

enter image description here

当光线从左到右移动时会发生这种情况

当我将光源移动到表面上时,它会一直保持这种状态。在每个顶点处最亮,并在那里逐渐消失。

我是否需要增加细分才能实现更平滑、更径向的阴影?还是有其他方法可以解决这个问题?

以下是我使用的着色器:

vert

varying vec3 vertex_light_position;
varying vec3 vertex_normal;

void main() 
{            
    vertex_normal = normalize(gl_NormalMatrix * gl_Normal);
    vertex_light_position = normalize(gl_LightSource[0].position.xyz);

    gl_FrontColor = gl_Color;
    gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}

frag

varying vec3 vertex_light_position;
varying vec3 vertex_normal;

void main() 
{
    float diffuse_value = max(dot(vertex_normal, vertex_light_position), 0.0);
    gl_FragColor = gl_Color * diffuse_value;
}

如果有人想知道我的几何形状:

glBegin(GL_QUADS);
    glNormal3f(0.0f, 0.0f, 1.0f);
    glTexCoord2f(0.0f, 1.0f); glVertex3f(pos_x, pos_y - size_y, depth);
    glTexCoord2f(1.0f, 1.0f); glVertex3f(pos_x + size_x, pos_y - size_y, depth);
    glTexCoord2f(1.0f, 0.0f); glVertex3f(pos_x + size_x, pos_y, depth);
    glTexCoord2f(0.0f, 0.0f); glVertex3f(pos_x, pos_y, depth);
glEnd();

那张图片太小了。你能放一张更大的图片吗? - BЈовић
这是一对一的。我会上传一系列,这样更有意义。 - grep
你的着色器似乎使用了定向光。在平面表面上(没有衰减),定向光应该产生均匀的照明(表面上每个点的光强度相同)。既然这不是发生了,那么肯定有什么问题。 - Nicol Bolas
@Headspin: 你确定那些着色器实际上被绑定了吗?从图片上看,它看起来更像是固定功能的照明。 - datenwolf
是的,我确信它们正在被绑定,因为我可以复制/粘贴其他有效的着色器并看到结果。这只是默认功能。 - grep
如果您将正常值写成颜色,会发生什么?只需执行 gl_FragColor = vec4(vertex_normal, 1.0);。调试着色器的最佳方法是将值编写为颜色,并查看您得到的结果是否合理。 - Nicol Bolas
3个回答

5

我看到可能会存在一些问题。

除非我弄错了,你正在使用 normalize(gl_LightSource[0].position.xyz); 来计算光照向量,但它仅基于光源的位置而不是你正在操作的顶点。这意味着对于每个顶点,该值将是相同的,并且仅会根据当前模型视图矩阵和光源位置发生变化。我认为通过执行像 normalize(glLightSource[0].position.xyz - (gl_ModelViewMatrix * gl_Vertex).xyz) 这样的操作来计算光照向量更接近你想要的结果。

其次,在片元着色器中,你应该像在顶点着色器中一样归一化向量,因为两个单位向量的插值不能保证本身也是一个单位向量。


2
我认为问题出在光矢量上...
我建议使用:
vec3 light_vector = normalize(gl_LightSource[0].position.xyz - vertex_pos)

可以通过以下方式计算vertex_pos:

vertex_pos = gl_ModelViewMatrix * gl_Vertex

请注意,所有向量应该在同一空间中(相机、世界、物体)。

1
我是否必须提高细分程度才能获得更平滑、更径向的阴影?还是有其他方法可以解决这个问题?
不,你可以自由地做任何想做的事情。你需要改变的唯一代码是片段着色器。尝试调整它并查看是否获得更好的结果。
例如,你可以这样做:
diffuse_value = pow(diffuse_value, 3.0);

如此处所述这里


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