OpenGL 闪烁的像素伪像

标签 opengl glsl specular ambient

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

shimmering pixels

这是我的片段着色器:

#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

OSX Screenshot
对顶点着色器进行以下更改后:
//正常 = 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 消失,结果如下:
enter image description here
但是,对于一半的三角面,您的环境遮挡术语似乎仍然相反。

关于OpenGL 闪烁的像素伪像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18523231/

相关文章:

opengl - 在 wxWidgets 中调整窗口大小时,视口(viewport)或投影无法正确调整大小

c++ - 用opengl绘制子像素

macos - 有没有办法确定 CGLFlushDrawable 对后台缓冲区做了什么?

c++ - GLSL 将 gl_FragCoord.xy 映射到正交投影中的坐标

javascript - 纹理是将音频数据传输到 GLSL 的唯一方法吗?

macos - Mac OS X 10.6 中的 OpenGL 对象有光泽/ Shiny ,但 10.5 则不然。为什么?

c++ - 通过纹理四边形的 OpenGL 字体

c++ - 如何正确绑定(bind)2个纹理

opengl - 蓬照明 : add specular lighting separately or with ambient and diffuse?

performance - Matlab计算Vector的反射