我试图理解并完成从 3D 场景描述(如 VRML)渲染简单 2D 图像所需的基本数学计算。是否有一个好的例子展示了所需的步骤,例如模型变换(从物体坐标到世界坐标),视图变换(从世界坐标到视图坐标),计算用于光照的顶点法线,裁剪,计算在视锥体内的对象的屏幕坐标以及创建 2D 投影来计算具有颜色的各个像素。
我试图理解并完成从 3D 场景描述(如 VRML)渲染简单 2D 图像所需的基本数学计算。是否有一个好的例子展示了所需的步骤,例如模型变换(从物体坐标到世界坐标),视图变换(从世界坐标到视图坐标),计算用于光照的顶点法线,裁剪,计算在视锥体内的对象的屏幕坐标以及创建 2D 投影来计算具有颜色的各个像素。
我习惯于使用OpenGL风格的渲染数学,因此我坚持使用它(所有的渲染几乎都使用相同的数学)
首先解释一些术语:
表示3D空间中的坐标系
double m[16]; // it is 4x4 matrix stored as 1 dimensional array for speed
m[0]=xx; m[4]=yx; m[ 8]=zx; m[12]=x0;
m[1]=xy; m[5]=yy; m[ 9]=zy; m[13]=y0;
m[2]=xz; m[6]=yz; m[10]=zz; m[14]=z0;
m[3]= 0; m[7]= 0; m[11]= 0; m[15]= 1;
其中:
X(xx,xy,xz)
是GCS(全局坐标系)中X
轴的单位向量Y(yx,yy,yz)
是GCS中Y
轴的单位向量Z(zx,zy,zz)
是GCS中Z
轴的单位向量P(x0,y0,z0)
是在GCS中表示的坐标系的原点变换矩阵用于在GCS和LCS(本地坐标系)之间转换坐标
->
LCS:Al = Ag * m;
<-
LCS:Ag = Al * (m^-1);
Al(x,y,z,w = 1)
是LCS中的3D点...在齐次坐标下Ag(x,y,z,w = 1)
是GCS中的3D点...在齐次坐标下添加齐次坐标w=1
,以便我们可以将3D向量乘以4x4矩阵
m
转换矩阵m^-1
逆转换矩阵在大多数情况下,m
正交,这意味着X,Y,Z
向量相互垂直且具有单位大小,这可用于在旋转、平移等操作后恢复矩阵的准确性...
更多信息请参见了解4x4齐次变换矩阵
通常使用以下矩阵:
model
- 表示实际渲染对象的坐标系view
- 表示相机坐标系统(Z
轴是视图方向)modelview
- 模型和视图相乘的结果normal
- 与modelview
相同,但用于法线向量计算时x0,y0,z0=0
texture
- 操纵纹理坐标以实现纹理动画和效果,通常为单位矩阵projection
- 表示相机视图的投影(透视,正交等),不应包括任何旋转或平移,它更像相机传感器校准(否则雾化和其他效果将失败...)要呈现3D场景,您需要像绘制2D纹理三角形之类的2D呈现例程。渲染会将3D场景数据转换为2D并呈现出来。还有更多的技术,但最常见的是使用边界模型表示 + 边界呈现(仅表面)。通过投影(正交或透视)和Z缓冲区或Z排序来完成3D->
2D转换。
因此,流水线是这样的:
v
n
t
v = projection * view * model * v
...相机空间+投影n = normal * n
...全局空间t = texture * t
...纹理空间这一步不是必要的,但可以提高速度并且通常在这里进行面剔除。如果呈现的“三角形”的法向量相反,则忽略该多边形绕序规则。
屏幕渲染只使用v.x,v.y
坐标,而v.z
用于z-buffer测试/值,透视投影需要进行透视除法。
v.x/=v.z,vy/=v.z
Z-buffer的工作原理如下: Z-buffer (zed
)是与屏幕(scr
)大小(分辨率)相同的2D数组。任何像素scr[y][x]
仅在if (zed[y][x]>=z)
时呈现,此时scr[y][x]=color; zed[y][x]=z;
if条件可以不同(可更改)。
如果使用三角形或更高级别的基元进行渲染,则将得到的2D基元转换为像素,这个过程称为光栅化,例如:
以下是其外观:
[注]
变换矩阵是可乘的,因此如果您需要通过M
矩阵转换N
点,则可以创建单个matrix = m1*m2*...mM
并仅通过此结果的matrix
转换N
点以提高速度。有时会使用3x3
变换矩阵+平移向量
代替4x4
矩阵。在某些情况下,这样更快,但您不能很容易地将多个变换相乘。对于变换矩阵操作,请查找基本操作,例如旋转或平移,还有一些用于LCS内部旋转的矩阵,这些对于人类控制输入更合适,但这些不是渲染器(如OpenGL或DirectX)的本土矩阵。(因为它们使用逆矩阵)
现在所有上述内容都是用于标准多边形渲染(对象表面边界表示)。还有其他渲染器,如体积渲染或(背部)光线追踪器和混合方法。场景也可以具有任意维度,而不仅仅是3D。这里有关于这些主题的相关问答: