在gouraud阴影中,什么是T-junction发布以及如何使用OpenGL进行演示

时间:2014-02-06 04:06:44

标签: opengl graphics shader gouraud

我在Gouraud Shading部分注意到here,它说“与相邻多边形的T形连接有时会导致视觉异常。一般来说,应该避免T形连接”。

看起来T型交叉点是下图中的三个表面共享边缘,而点A可能具有不同的法向量,因为它属于不同的表面。

enter image description here

但T-junction发生时的效果是什么以及如何使用OpenGL来实现它?我尝试为每个矩形的每个顶点设置不同的法线并在场景中放置一个灯光,但是,我没有在交点A看到任何奇怪的东西。

这是我的代码:

glColor3f(1.0f, 0.0f, 0.0f);
glBegin(GL_QUADS);
glNormal3f(0, 0,1);
glVertex3f(-5.0f, 5.0f, 0.0f);
glNormal3f(0, 1,1);
glVertex3f(5.0f, 5.0f, 0.0f);
glNormal3f(1, 1,1);
glVertex3f(5.0f, 0.0f, 0.0f);
glNormal3f(0, -1,1);
glVertex3f(-5.0f, 0.0f, 0.0f);
glEnd();

glColor3f(0.0f, 1.0f, 0.0f);
glBegin(GL_QUADS);
glNormal3f(1, 0,1);
glVertex3f(-5.0f, 0.0f, 0.0f);
glNormal3f(1, 2,1);
glVertex3f(0.0f, 0.0f, 0.0f);
glNormal3f(0, 0,1);
glVertex3f(0.0f, -5.0f, 0.0f);
glNormal3f(0, 1, 2);
glVertex3f(-5.0f, -5.0f, 0.0f);
glEnd();

glColor3f(0.0f, 0.0f, 1.0f);
glBegin(GL_QUADS);
glNormal3f(1, 1, 3);
glVertex3f(0.0f, 0.0f, 0.0f);
glNormal3f(0, -2, 5);
glVertex3f(5.0f, 0.0f, 0.0f);
glNormal3f(-1, 1, 1);
glVertex3f(5.0f, -5.0f, 0.0f);
glNormal3f(1, -2, 0);
glVertex3f(0.0f, -5.0f, 0.0f);
glEnd();

点光源在(0,0,10)以及相机中。我认为下面的结果没有视觉异常。也许法线应该有点特别吗?

我做错了吗?任何人都可以给我一些提示来实现这个目标吗?

enter image description here

2 个答案:

答案 0 :(得分:3)

T-Junction对于Gouraud shading和一般的几何结构都不好。

首先要记住,goraud着色是一种在固定管道时代使用的光插值方法,其中光在顶点内插,使得顶点的网格细分(数量和连通性)直接影响着色。具有t结将使最终插值颜色的外观突然不连续(请记住,Gouraud着色还有其他问题,例如欠采样)。

与Phong着色不同,Gouraud着色直接使用顶点法线,并且作为注释不要将Phong着色与Phong光照混淆,它们是不同的

请注意,您呈现的情况是T型交叉点,但您不会注意到任何着色问题,因为网格没有经过细分,并且(看起来)您没有使用任何光线。尝试在带有T形接头的球体上进行测试。

关于几何t型连接被认为是简并的情况。因为在该边缘/多边形处,几何网格会失去一致性,您不再在其末端连接两条边,并且您将失去多边形循环属性(读取:有向边)。这通常是一个难以解决的问题,解决方案可能是对多边形进行三角测量,以便现在正确连接t-juction边缘。

http://en.wikipedia.org/wiki/Gouraud_shading

答案 1 :(得分:1)

你处理这种情况越多,其核心问题就越明显。有一个坚实的例子,花一些时间看着它,你可能会去“啊哈!”它会点击。

理论上,问题通常被描述为这样一种情况,即t-vert的直接和相邻区域中的像素基于单独且有时不同的输入(阴影中的法线与相邻顶点的法线)进行着色。 )。你可以通过将t-vert的法线设置为与相邻顶点法线非常不同的东西(例如,与它们的平均值非常不同)来夸大问题作为插图。

练习中,除了角落情况之外,您通常会处理顶点之间法线的平滑渐变,因此问题更加微妙。我因此而以不同的方式查看问题:作为示例数据传播问题。这种情况导致样本之间的插值不会以均匀的方式在表面上传播样本数据。在您的示例中,t-vert光样本输入不向上传播,仅向左/向右/向下传播。这是t-vertices存在问题的一个原因,它们代表了网格网络中的不连续性,导致了这样的问题。

您可以通过在曲面上的每个法线点上描绘光线值来想象它,然后考虑给定光线位置的所有颜色在面部的颜色。使用您的示例,但法线渐变更平滑,对于顶面,您会看到一个长线性颜色插值。但是对于底部的两个面,您会看到由t顶点法线驱动的两种颜色线性插值。根据光角度,t顶点法线可以拾取与相邻法线不同的光量。这将驱动它上面和下面的颜色插值,你会看到一个阴影缝。

为了说明你的例子,我只使用一种颜色,调整法线,使它们形成一个更均匀的相对角度分布(类似于我将在下面投射的集合),然后使用不同的光线查看它位置(特别是靠近t-vertex的位置)。

top left normal: [-1, 1, 1]
top right normal: [1, 1, 1]
middle left normal: [-1, 0, 1]
t-vert normal: [0, 0, 1]
middle right normal: [1, 0, 1]
bottom left normal: [-1, -1, 1]
bottom middle normal: [0, -1, 1]
bottom right normal: [1, -1, 1]

因为这是由采样数据的不均匀传播驱动的问题 - 并且传播就是插值所做的 - 顺便说一下,其他插值技术(如Phong着色)也会发生类似的异常。