我正在尝试在基于体素的网格上实现环境遮挡,并在面的边缘处获得这些闪烁的白色像素:
这是我的片段着色器:
#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
)和镜面反射分量计算得出的。似乎这是导致问题的镜面反射。为什么角落和边缘会突然闪现?当网格旋转时,白色像素看起来会闪烁。但是在较大的表面上,镜面高光看起来是正常的并且跟随光源而不是闪烁开关。
答案 0 :(得分:2)
现在您提到它,如果您遵循T-Junction消除的常规解决方案,即在T-Junction处插入顶点,您基本上可以消除贪婪网格划分的好处。我看到已经讨论过here而没有提出实际的解决方案。显然,有人认为这个问题在大多数硬件上都不足以支持任何进一步的调查。
在您的情况下,几乎看起来在多边形边缘的实际光栅化(T-Junction错误)期间不会弹出问题,而是当您尝试计算片段着色器中依赖于每顶点插值的值时。我看到你正在将颜色缓冲区清除为红色,因此在这种情况下光栅化期间这些是子像素T-Junction错误的可能性更小。经过仔细检查,我发现沿对角线三角形边缘出现了一些不连续性(法线似乎翻了一半脸)。也许问题实际上与某些输入顶点属性中的大差异有关。我会尝试修复照明,以便首先在整个面部产生平滑的结果,也许是导致T-Junction问题的原因。
事实上,是否可以在问题中包含顶点着色器?我很想知道如何计算normal.w
。
我将您的代码移植到OS X(比您想象的更难:P),结果相同:
OpenGL renderer string: NVIDIA GeForce GT 330M OpenGL Engine OpenGL version string: 2.1 NVIDIA-1.6.36 OpenGL shading language version string: 1.20
对顶点着色器进行以下更改后:
//normal = 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 light = normal.w * max (1.5*dot(normal.xyz, vec3 (1,1,1)), 0.0);
火花消失了,结果就是:
然而,对于你的三角形脸部,你的环境遮挡术似乎仍然可以逆转。