6

我正在尝试在基于体素的网格上实现环境遮挡,并在面部边缘获取这些闪烁的白色像素:

闪烁的像素

这是我的片段着色器:

#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) 和镜面反射分量计算得出的。似乎是导致问题的镜面反射。为什么角落和边缘会突然像这样闪烁?当网格旋转时,白色像素会闪烁。但在较大的表面上,镜面高光看起来很正常,并跟随光源而不是闪烁。

4

1 回答 1

2

既然您提到了它,如果您遵循消除 T-Junction 的常规解决方案,即在 T-Junction 处插入顶点,您基本上会取消贪婪网格划分的好处。我看到这已经在这里讨论过,但没有提出实际的解决方案。显然,那里的论点是该问题在大多数硬件上都不足以支持任何进一步的调查。

在您的情况下,似乎在多边形边缘的实际光栅化(T-Junction 错误)期间不会出现该问题,而是在您尝试在片段着色器中计算依赖于每个顶点插值的值时出现问题。我看到您正在将颜色缓冲区清除为红色,因此在这种情况下,这些是光栅化过程中的子像素 T-Junction 错误的可能性更小。仔细检查后,我注意到沿对角三角形边缘的一些不连续性(法线似乎翻转了一半脸)。也许这个问题实际上与某些输入顶点属性中的大差异有关。我会尝试修复照明以首先在整个面部产生平滑的效果,也许是什么导致了 T-Junctions 的问题。

实际上,是否可以在问题中包含您的顶点着色器?我很想知道如何normal.w计算。


更新:

我将您的代码移植到 OS X(比您想象的要难:P),结果相同:

OpenGL 渲染器字符串:NVIDIA GeForce GT 330M OpenGL 引擎
OpenGL 版本字符串:2.1 NVIDIA-1.6.36
OpenGL着色语言版本字符串:1.20

OSX 截图

对顶点着色器进行以下更改后:

//正常 = v_normal;
正常 = vec4(归一化(v_normal.xyz),v_normal.w);

和片段着色器:

//float light = normal.w * max (0.15*dot(normal.xyz, vec3 (1,1,1)), 0.0);
浮光 = normal.w * max (1.5*dot(normal.xyz, vec3 (1,1,1)), 0.0);

闪光消失了,结果如下:

在此处输入图像描述

但是,对于一半的三角面,您的环境遮挡项似乎仍然是相反的。

于 2013-09-01T03:36:00.243 回答