我正在OpenGL GLSL中实现一个简单的Phong着色器,并且测试对象是犹他州茶壶。但是,在底部有一个红色的实心圆圈,在顶部有一些尖锐的扇区,这些扇区的颜色不正确。

有什么办法可以解决这些问题?首先是什么问题?




评论

实心红色可能是一个洞吗?

不,我已经检查过了,不是

您可以将代码上传到某处(要点,pastebin等)并进行链接吗?我们也许可以在代码中发现错误。

在您的正常计算中最有可能出现问题。最后是参量形状的奇异点,如果您不知道自己在做什么,可能会产生不好的结果。在这些情况下,可见的伪影数字2很常见。

如果您包含了代码的相关部分,那么您的问题肯定会更加容易回答。

#1 楼

我可以肯定地说,您的问题在于无法正确处理所谓的退化Bezier面片,尤其是(如Joojaa所述)表面法线的计算。我之所以说“退化”,是因为从几何学上讲,这些表面通常表现得很好。只是人们经常对参数方程式所作的一些假设可能不成立。我将尝试总结两个简单的情况。现在假设您的贝塞尔曲线被定义为$ \ bar {B}(u,v)$,则常见的两个原因是:

零导数:通常在$(a,b)$处(双关语)计算两个导数,

$ \ frac {\ partial} {\ partial v} \ bar {B}(a,b) $和$ \ frac {\ partial} {\ partial u} \ bar {B}(a,b)$

或其缩放版本,获得两个切线,然后取叉积。

(实施注意:由于我们可以在计算中使用切线的缩放版本,因此我们实际上不必计算实际导数。例如,特别是在拐角处,控制点的差异可以产生缩放的切线。但是为了简洁起见,我们将假定实际的导数)。

一个常见的现象是,至少在拐角处,该位置的一阶偏导数可以为零,这会导致不正确的法线(即零向量)。

在茶壶的顶部和底部,许多(方形)贝塞尔曲线片的整个边缘已经塌陷为一个点,即所有4个控制点都相同,因此说

$ \ bar {B}(0,v)== \ bar {B}(1,v)$和$ \ frac {\ partial} {\ partial u} \ bar {B}(0,0)= \ bar {0} $。

但是,曲面的行为完全良好,因此您可以选择从该折叠点开始的另一个导数。例如,在这种情况下,选择

$ \ frac {\ partial} {\ partial v} \ bar {B}(1,0)$

用于第二个切线。

话虽如此,由于其他原因(例如2或3个重合的控制点),您必须检查您的一阶导数不为零,在这种情况下,您可以在第二个数(如果为零,则即使是零,

平行切线:

如果两个切线平行,则可能会出现另一个类似的问题。 -Farin在他的书中有一个很好的例子。

在这种情况下,我认为您可能需要使用$ \ frac {\ partial ^ 2} {\ partial u \ partial v} \ bar {B} $之类的东西,或者可能只是回到使用小的UV偏移量来近似向量。