我正在尝试在基于体素的网格上实现环境光遮挡,并在面部边缘获得这些闪烁的白色像素:
这是我的片段着色器:
#version 120
varying vec4 color;
varying vec4 normal;
void main(void)
{
float light = normal.w + max(0.15*dot(normal.xyz, vec3(1,1,1)), 0.0);
gl_FragColor = vec4(color.xyz * light, 1.0);
}
如果我删除
light
来自 gl_FragColor
vec4
然后神器消失。 light
值是根据环境光遮挡值 (normal.w
) 和镜面反射分量计算得出的。似乎是镜面反射导致了问题。为什么角落和边缘会突然变成这样?当网格旋转时,白色像素看起来会闪烁。但是在较大的表面上,镜面反射高光看起来是正常的,并且会跟随光源,而不是时断时续地闪烁。
最佳答案
既然你提到了它,如果你遵循 T 型结消除的正常解决方案,即在 T 型结点插入顶点,你基本上会取消贪婪网格划分的好处。我看到这已经讨论过了 here没有提出实际的解决方案。显然,那里的论点是该问题在大多数硬件上不足以支持任何进一步调查。
在您的情况下,问题似乎几乎不会在多边形边缘的实际光栅化(T 型连接错误)期间出现,而是在您尝试计算依赖于每个顶点插值的片段着色器中的值时出现。我看到您正在将颜色缓冲区清除为红色,因此在这种情况下,这些是光栅化过程中的子像素 T 型连接错误的可能性更小。仔细检查后,我注意到对角三角形边缘有些不连续(法线似乎翻转了一半的脸)。也许这个问题实际上与某些输入顶点属性的巨大差异有关。我会先尝试修复照明以在整个面部产生平滑的效果,也许是什么原因也会导致 T 型接头出现问题。
事实上,是否可以在问题中包含您的顶点着色器?我很想知道如何normal.w
被计算。
更新:
我将您的代码移植到 OS X(比您想象的更难:P),结果相同:
OpenGL 渲染器字符串:NVIDIA GeForce GT 330M OpenGL Engine
OpenGL 版本字符串:2.1 NVIDIA-1.6.36
OpenGL 着色语言版本字符串:1.20
对顶点着色器进行以下更改后:
//正常 = v_normal;
normal = vec4 (normalize (v_normal.xyz), v_normal.w);
和片段着色器:
//float light = normal.w * max (0.15*dot(normal.xyz, vec3 (1,1,1)), 0.0);
float 光 = normal.w * max (1.5*dot(normal.xyz, vec3 (1,1,1)), 0.0);
Spark 消失,结果如下:
但是,对于一半的三角面,您的环境遮挡术语似乎仍然相反。
关于OpenGL 闪烁的像素伪像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18523231/