Ree*_*Law 5 opengl glsl specular ambient
我正在尝试在基于体素的网格上实现环境遮挡,并在面的边缘处获得这些闪烁的白色像素:

这是我的片段着色器:
#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);
}
Run Code Online (Sandbox Code Playgroud)
如果我light从中删除了gl_FragColor vec4那么神器就会消失.该light值根据环境遮挡值(normal.w)和镜面反射分量计算得出.似乎这是导致问题的镜面反射.为什么角落和边缘会突然闪现?当网格旋转时,白色像素看起来会闪烁.但是在较大的表面上,镜面高光看起来是正常的并且跟随光源而不是闪烁.
既然您提到了这一点,如果您遵循消除 T 形接头的正常解决方案,即在 T 形接头处插入顶点,您基本上会抵消贪婪网格划分的好处。我看到这里已经讨论过这个问题,但没有提出实际的解决方案。显然,争论的焦点是这个问题在大多数硬件上都没有得到足够的支持,以至于无法进行进一步的调查。
在您的情况下,问题似乎不会在多边形边的实际光栅化期间出现(T 形连接错误),而是在您尝试计算依赖于逐顶点插值的片段着色器中的值时出现。我发现您正在将颜色缓冲区清除为红色,因此在这种情况下,这些是光栅化过程中的子像素 T 形连接错误的可能性更小。经过仔细检查,我注意到沿对角三角形边缘有一些不连续性(法线似乎翻转了半张脸)。也许该问题实际上与某些输入顶点属性的巨大差异有关。我会首先尝试修复照明,以在整个面部产生平滑的效果,也许无论是什么原因造成的,也会导致丁字路口的问题。
事实上,是否可以将您的顶点着色器包含在问题中?我很好奇是如何normal.w计算的。
我将你的代码移植到 OS X(比你想象的更难:P),得到了相同的结果:
OpenGL 渲染器字符串:NVIDIA GeForce GT 330M OpenGL 引擎 OpenGL 版本字符串:2.1 NVIDIA-1.6.36 OpenGL 着色语言版本字符串:1.20

对顶点着色器进行以下更改后:
//正常= v_normal; 法线= vec4(归一化(v_normal.xyz),v_normal.w);
和片段着色器:
//浮动光=法线.w * max(0.15*dot(法线.xyz, vec3(1,1,1)), 0.0); 浮动光 = 法线.w * max (1.5*dot(法线.xyz, vec3 (1,1,1)), 0.0);
闪光消失,结果如下:

然而,对于一半的三角面,您的环境光遮挡术语似乎仍然相反。