OpenGL / GLSL变化向量:如何避免顶点周围的爆炸?

时间:2011-12-31 21:16:34

标签: opengl glsl phong

在OpenGL 2.1中,我将位置和法线向量传递给我的顶点着色器。然后顶点着色器将varying设置为法线向量,因此理论上它是对每个三角形的法线进行线性插值。 (据我所知,这是Phong着色的基础。)

在片段着色器中,我使用法线和Lambert定律来计算漫反射。这可以按预期工作,除了顶点之间的插值看起来很有趣。具体来说,我看到了一个星暴影响,其中顶点之间的边缘有明显的“热点”。

这是一个例子,不是来自我自己的渲染,而是展示完全相同的效果(请参阅页面中间的黄金球体): http://pages.cpsc.ucalgary.ca/~slongay/pmwiki-2.2.1/pmwiki.php?n=CPSC453W11.Lab12

Wikipedia says这是Gauraud阴影的问题。但正如我所理解的那样,通过插入法线并运行每个片段的光照计算,我使用的是Phong模型,而不是Gouraud。是吗?

如果我使用更精细的网格,我认为这些星暴会更不明显。但是添加更多三角形是解决这个问题的唯一方法吗?我认为有一种方法可以在没有爆炸效果的情况下进行平滑插值。 (我确实在其他地方的粗糙网格上看到了非常平滑的阴影,例如在3D Studio Max中。但也许他们正在做一些比插入法线更复杂的东西。)

2 个答案:

答案 0 :(得分:5)

完全不是同样的效果。你所看到的是两件事之一。

  1. 在片段着色器中使用法线前不规范化法线的结果。

  2. 由三角形边缘上的线性渐变碰撞产生的视错觉。真。

    "Gradient Matters" section at the bottom of this page(注意:为了完全披露,这是我的教程)详细解释了这一现象。使用插值法线的简单朗伯漫反射有效地在三角形上产生或多或少的线性光。具有不同法线组的三角形将具有不同的梯度。它将是C0连续(沿边缘的颜色相同),但不是C1连续(两个渐变的颜色以不同的速率变化)。

    人类视觉汲取了这些梯度差异,使它们脱颖而出。因此,我们认为它们是硬边缘,而事实上它们并非如此。

    这里唯一真正的解决方案是进一步细分网格或使用从更精细版本的网格创建的法线贴图而不是插值法线。

答案 1 :(得分:2)

您没有显示您的代码,因此无法分辨,但最可能的问题是片段着色器中的非标准化法线。在顶点着色器中计算的法线是内插的,这会导致向量不是单位长度 - 因此您需要在计算片段光照之前在片段着色器中对它们进行重新规范化。