问题描述
我正在尝试在基于体素的网格上实现环境光遮挡,并使这些闪烁的白色像素出现在脸部边缘:
I'm trying to implement ambient occlusion on a voxel-based mesh and get these flickering white pixels at the edges of faces:
这是我的片段着色器:
#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);
}
如果我从gl_FragColor
vec4
中删除了light
,则工件消失了. light
值是根据环境光遮挡值(normal.w
)和镜面反射分量计算得出的.似乎是引起问题的镜面反射.为什么拐角和边缘会突然像这样闪烁?随着网格旋转,白色像素似乎会闪烁.但是在较大的表面上,镜面反射高光看起来很正常,并跟随光源,而不是在闪烁时闪烁.
If I remove the light
from the gl_FragColor
vec4
then the artifact disappears. The light
value is calculated from the ambient occlusion value (normal.w
) and a specular component. It seems like it's the specular that's causing the problem. Why would corners and edges suddenly flash like this? The white pixels appear to shimmer as the mesh is rotated. But on larger surfaces, the specular highlights appear normal and follow the light source rather than flicker on and off.
推荐答案
现在您提到它了,如果您遵循消除T型结的常规解决方案,即在T型结处插入顶点,则基本上可以消除好处.贪婪的啮合.我看到已经在此处中进行了讨论没有提出实际的解决方案.显然有一种说法是,该问题在大多数硬件上都不足以支持任何进一步的调查.
Now that you mention it, if you followed the normal solution for T-Junction elimination, which is to insert vertices at T-Junctions you would basically undo the benefits of greedy meshing. I see this has already been discussed here with no actual solution proposed. Apparently the argument there was that the issue doesn't prop up enough on most hardware to warrant any further investigation.
在您的情况下,似乎几乎没有在多边形边界的实际栅格化期间出现此问题(T型连接错误),而是当您尝试在片段着色器中计算依赖于每个顶点插值的值时.我看到您将颜色缓冲区清除为红色,因此在这种情况下,这些错误更不可能是在光栅化过程中出现的亚像素T型结错误.仔细检查后,我发现您的对角三角形边缘有些不连续(法线似乎被翻转了您一半的脸).也许该问题实际上与某些输入顶点属性中的较大差异有关.我会尝试先修复照明,以使整个脸部产生平滑的结果,也许是什么原因也导致了T型交界处的问题.
In your case, it almost seems that the issue does not pop up during the actual rasterization of polygon edges (T-Junction errors), but rather when you try to compute values in your fragment shader that rely on per-vertex interpolation. I see that you are clearing your color buffer to red, so it is even less likely that these are sub-pixel T-Junction errors during rasterization in that case. Upon closer inspection, I notice some discontinuities along your diagonal triangle edges (the normals seem to be flipped for half of your face). Perhaps the issue is actually related to large discrepancies in some input vertex attribute. I'd try to fix-up the lighting to produce smooth results across the entire face first, maybe whatever is causing that is also causing the issues at T-Junctions.
实际上,是否可以在问题中包含您的顶点着色器?我很好奇如何计算normal.w
.
In fact, would it be possible to include your vertex shader in the question? I am curious to see how normal.w
is computed.
我将您的代码移植到OS X(比您想象的要硬:P),结果相同:
I ported your code to OS X (harder than you'd think :P), with the same results:
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
对顶点着色器进行以下更改之后:
After making the following changes to the vertex shader:
//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);
火花消失了,这是结果:
The sparklies disappear and this is the result:
但是,您的三角面中,您的周围环境遮挡项似乎仍然相反.
Your ambient occlusion term still seems to be reversed for half of your triangulated faces, however.
这篇关于OpenGL闪烁像素伪像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!