Archive for the ‘计算机图形学’ Category
三角形光栅化是传统图形渲染管线的最后一步,也是最重要的一步,需要插值计算出三角形内部每个像素的颜色值,并根据z值进行深度测试以决定像素的远近关系。
光栅化的算法用掉了我好几天的时间,一开始是用Barycentric Coordinates算法进行的,结果帧率只有杯具的3,想办法把很多的乘除法改成了加减法还是没有起色,看来浮点数运算还是坑爹啊,于是决定用经典的Bresenham算法了。但是Bresenham算法是用来画线的,对于光栅化三角形来说还要考虑三角形内部针对顶点颜色的插值,于是我将其变成了Bresenham插值算法……
纹理映射是光栅化过程中重要的一步。由于众所周知的原因,透视投影是非线性变换,因此顶点原始的uv坐标在变换之后不可以直接使用线性插值计算新的uv坐标。例如,矩形四个顶点的uv坐标分别为(0,0),(0,1),(1,0),(1,1),矩形中点的uv坐标按照线性插值的话等于(0.5,0.5),但是若矩形不是正对观察点的话,透视变换后中点的uv坐标就不一定等于(0.5,0.5)。
例如:
纹理贴图:
线性插值结果->错误:
透视矫正插值结果->正确:
Barycentric Coordinates算法,即“重心坐标系插值算法”,本质是通过计算2D空间中任意一点到三角形三边的相对距离,来确定点是否在三角形内部。这个算法比起常见的扫描线插值算法,编程更容易(不需要判断三角形类型),而且具有更高的精确度(避免了计算斜率时带来的误差)。Barycentric Coordinates算法不但可以判断像素点是否需要绘制,而且可以直接插值计算出需要绘制的像素点的颜色或纹理映射坐标。不过,我不知道计算量是否要比扫描线插值算法大,希望有感兴趣的朋友能比较一下。
本文首先简单讲一下算法的原理,然后给出代码实现。
在3D渲染管线的透视变换(prospective transformation)中,远近裁剪面的取值不同,会对变换的结果造成一定的影响,主要体现在变换后z值的密度上。这次图形学作业有关于这方面的一道讨论题,顺便就把我的分析结果放上来吧。
网上有很多“绕任意轴的旋转矩阵”的文章,不过要么限定了所谓“任意轴”必须经过原点,要么只有推导没有结论。最近在完成图形学作业的时候正好用到了这个算法,通过Google娘找到了一篇名叫Glenn Murray的老外的文章,于是直接拿来用了。以下直接放结论,详细推导过程可以参考原文[1]。
算法的输入参数分别是旋转轴上的任意一点P(a,b,c),单位化后的旋转轴方向向量V(u,v,w),旋转角度θ。