在用gouroud算法给3d图形进行渲染时。大致思路是将三角形分成三种结构, 第一是top, 第二种是bottom,第三种则是其他情况
如图
对于第三种情况,结合作者在实现过程中遇到的问题,进行以下几点总结分析 (以下用加粗红色字母“c”指代非正规三角形)
1 : 在绘制c的时候, 会出现一下这种情况。请看图(1-1)
(1-1) (1 - 2)
图(1-2)是一个c, 而在绘制的时候人工的将其分成两个三角形进行绘制,
结合(1-1)(1-2)
很容易发现m区的颜色渲染明显和n区不相融合,那么究竟是哪里出了问题呢?
解析:
为了方便说明,我将自己实现的部分代码截图粘贴在下面(1-3)
(1 - 3)
第一:c的绘制思路。
我们能从代码上得到一条信息,
DrawTopTriangle_Gouroud
DrawBottomTriangle_Gouroud
这两个接口他们是共用同样的三个顶点的。
c本身是非正规的,但通过(1-2)我们可以发现他的实现是可以通过两个正规三角形组合绘制而成。
第二:分析问题出现原因。
根据gouroud的绘制原理,在y坐标不变的情况下,计算出x轴方向的深度斜率dz, 红色斜率dr,绿色斜率dg和蓝色斜率db,用来实现图形渲染。
具体代码如下所示:
在此对dr进行举例说明问题原因。在作者的程序,绘制top,永远假定middle.x > bottom.x。
fSize的结果是对x_mt,x_bt比较之后,用较大的减去较小的,从而保证了fSize > 0.那么如果
middle.x < bottom.x 那么在计算dr的时候人工手动改变了fsize的正负值,那么为了保证dr的正确性,
应该手动将redtm,redtb二者的数值进行互换。
其次,结合图(1-1),(1-2)观察c,可以发现,m区和n区他们是共享y = middle.y这个横线的(接下来用红色粗体字母d指代这条直线).那么当top的绘制,
由于middle.x < bottom.x,进行颜色斜率和深度斜率交换,此时d已经被绘制(理解这句很重要!:))。
此时top已经绘制完毕,[假定](d左定点的颜色是1,右定点的颜色是2, 即d的颜色是从做到右逐渐加深的)。接下来根据代码截图(1-3),要绘制bottom。而bottom此时的绘制如果不进行斜率互换,那么就会出现图(1-1)的结果.
拿[假定]来进行简单的分析,在top中由于斜率互换,d的颜色随着x的增加而加深。如果bottom不进行
斜率互换,那么就会造成d的颜色左定点是2,右定点是1,导致深度变化和top方向相反. 这就是作者最初犯错误的原因,即导致图(1-1)绘制效果的原因。
fSize = (fxmax - fxmin) + 1;
有的小伙伴可能会问了, 为什么要手动改变fSize的正负值呢? 如果不改变直接写成
dr = (redtm - redtb) / (x_tm - x_tb)不就得了。这样写乍一看没啥问题,但细细想来,如果x_tm == x_tb呢?
由于我们此时并不知道x_tm和x_tb的大小,后面的那个1不知道怎么加上去。(加1是为了保证党x_tm == x_tb的时候则应绘制一个像素点,即这条长度为零的直线的左端点)。所以最后还是要对x_tm, x_tb比较大小。然后将二者比较后的绝对者 + 1.
常见问题解答 :
1 ,在代码中为什么要对1/z1操作处理,而不是直接用z?
(z-buffer的原理公式)
解析:
ax + by + cz + d = 0; (1-1)
在绘制3d图形的时候我们最后用的都是透视坐标
根据透视坐标共识
xp = x *d/ z;(1-2)
yp = y * d /z;(1-3)
可以推出
x = xp * z / d;
y = yp * z / d;
然后将x, y带入(1-1)中,得到(a/dc)*xp + (b/dc)*yp = (-1) * (1/z + 1) .
所以最后得出的结论是xp, yp, (-1)*(1/z)成线性关系。
解析:
ax + by + cz + d = 0; (1-1)
在绘制3d图形的时候我们最后用的都是透视坐标
根据透视坐标共识
xp = x *d/ z;(1-2)
yp = y * d /z;(1-3)
可以推出
x = xp * z / d;
y = yp * z / d;
然后将x, y带入(1-1)中,得到(a/dc)*xp + (b/dc)*yp = (-1) * (1/z + 1) .
所以最后得出的结论是xp, yp, (-1)*(1/z)成线性关系。
2, 在接口drawtop_gouroud和drawbottom_gouroud中都用到了
long midX =
(long)( top.x +
(middle. y - top .y)
* dx_bt);
这个公式的意义是什么,依据的又是什么原理呢?
他的意义在于判断,middle.x是否在d线的左侧,如果不是,则根据作者在设计程序时的假定,对颜色斜率值
进行互换。
原理是相似三角形公式。请看图(1-4)

具体代码实现,我放到了代码片段里面,需要的小伙伴可以作为参考。
邮箱 : matrix_zxf@yahoo.com
邮箱 : matrix_zxf@yahoo.com