以数学方式计算简单的图形管道

han*_*ans 5 math 3d graphics

我正在尝试/理解图形管道中所需的所有基本数学计算,以从3D场景描述(如VRML)渲染简单的2D图像.是否有一个很好的示例所需的步骤,如模型转换(对象坐标到世界坐标),视图转换(从世界坐标到视图坐标),计算顶点法线用于照明,剪裁,计算视图内对象的屏幕坐标平截头体并创建2D投影以计算具有颜色的各个像素.

Spe*_*tre 8

我习惯了OpenGL风格的渲染数学,所以我坚持下去(所有的渲染都使用几乎相同的数学)

首先解释一下:

  1. 变换矩阵

    表示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;
    
    Run Code Online (Sandbox Code Playgroud)

    哪里:

    • X(xx,xy,xz)GCS(全局坐标系)X中轴的单位向量
    • Y(yx,yy,yz)GCSY中轴的单位矢量
    • Z(zx,zy,zz)GCSZ中轴的单位矢量
    • P(x0,y0,z0)GCS中代表坐标系的起源

    变换矩阵用于变换GCSLCS(局部坐标系)之间的坐标

    • GCS ->LCS: Al = Ag * m;
    • GCS <-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同质变换矩阵

  2. 渲染矩阵

    通常使用这些矩阵:

    • model - 表示实际渲染的对象坐标系
    • view- 表示摄像机坐标系(Z轴是视图方向)
    • modelview - 模型和视图相乘
    • normal-相同modelviewx0,y0,z0 = 0对于法线向量的计算
    • texture - 操纵纹理坐标以便于纹理动画,并通常影响单位矩阵
    • projection- 表示摄像机视图的投影(透视,正射,...),它不应包括任何旋转或平移,而更像是相机传感器校准(否则雾和其他效果将失败......)
  3. 渲染数学

    要渲染3D场景,您需要2D渲染例程,如绘制2D纹理三角形...渲染将3D场景数据转换为2D并渲染它.有更多的技术,但最常见的是使用边界模型表示 + 边界渲染(仅表面)3D ->2D转换通过投影(正交或透视)和Z缓冲或Z排序完成.

    • Z-buffer很容易并且是现在的gfx HW的原生
    • Z-sortingCPU完成,因此速度较慢,需要额外的内存,但是正确的透明表面渲染是必要的.

所以管道是这样的:

  1. 从模型中获取实际渲染数据

    • 顶点 v
    • 正常 n
    • 纹理坐标t
    • 颜色,雾坐标等...
  2. 将其转换为适当的空间

    • v=projection*view*model*v ...相机空间+投影
    • n=normal*n ......全球空间
    • t=texture*t ...纹理空间
  3. 将数据剪辑到屏幕

    这个步骤不是必需的,但是阻止渲染屏幕的速度以及面部剔除通常在这里完成.如果渲染的"三角形"的法线向量相反,那么多边形缠绕规则集则忽略"三角形"

  4. 渲染3D/2D数据

    仅使用v.x,v.y坐标进行屏幕渲染,使用vz进行z-buffer测试/值也是透视投影的透视划分

    • v.x/=v.z,vy/=v.z

    Z缓冲区的工作方式如下:Z-buffer(zed)是2D数组,其大小(分辨率)与screen(scr)相同.仅在这种情况下呈现任何像素 if条件可以不同(可以更改)scr[y][x]if (zed[y][x]>=z)scr[y][x]=color; zed[y][x]=z;

    在使用三角形或更高基元进行渲染的情况下,生成的2D基元将被转换为称为光栅化的过程中的像素,例如:

为了更清楚,这是它的样子:

3D渲染

[笔记]

变换矩阵是乘法的,所以如果你需要矩阵变换N点,M你可以创建单个matrix = m1*m2*...mM和转换N点,这只得到matrix(速度).有时使用3x3变换矩阵+ shift vector而不是4x4矩阵.在某些情况下它更快,但你不能将更多的转换成倍增加.对于变换矩阵操作,查找旋转或平移等基本操作,还有LCS内部旋转的矩阵,这些矩阵更适合人类控制输入,但这些矩阵不像OpenGLDirectX那样是原生的.(因为他们使用逆矩阵)

现在所有上述内容都是标准的多边形渲染(对象的表面边界表示).还有其他渲染器,如体积渲染或(后)射线追踪器和混合方法.此外,场景可以具有任何维度,而不仅仅是3D.这里有一些相关的QAs涵盖了这些主题: