数学计算一个简单的图形管道

7

我试图理解并完成从 3D 场景描述(如 VRML)渲染简单 2D 图像所需的基本数学计算。是否有一个好的例子展示了所需的步骤,例如模型变换(从物体坐标到世界坐标),视图变换(从世界坐标到视图坐标),计算用于光照的顶点法线裁剪计算在视锥体内的对象的屏幕坐标以及创建 2D 投影来计算具有颜色的各个像素。


你需要什么样的示例?是一个为显式场景执行所有这些步骤的示例吗?还是在一个明确的编程框架中?或者是像你发布的那些步骤列表一样的示例? - MvG
我正在寻找一个明确的场景示例,展示所有计算并解释数学。我想要理解渲染的数学步骤 :-) - Hans Sperker
POV光线追踪器是开源的。 - Felix Castor
@FelixCastor - 感谢您的回复,但我正在寻找数学计算和示例,而不是软件 :-) - Hans Sperker
1
这是针对机器人的,但它使用了同质变换矩阵的相同原理。几何变换第98页及以后。可能会有用。 - Felix Castor
@jstr 给我的回答添加了图片。 - Spektre
2个回答

14

我习惯于使用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;

其中:

  • 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齐次变换矩阵

  1. 渲染矩阵

通常使用以下矩阵:

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

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

  • Z缓冲区很容易且本地化在现今计算机图形硬件中
  • Z排序CPU执行,因此速度较慢且需要额外的内存,但对于正确的透明表面渲染是必要的。

因此,流水线是这样的:

  1. 从模型获取实际渲染数据
  • 顶点 v
  • 法向量 n
  • 纹理坐标t
  • 颜色,雾坐标等...
  1. 将其转换为适当的空间
  • v = projection * view * model * v...相机空间+投影
  • n = normal * n ...全局空间
  • t = texture * t ...纹理空间
  1. 将数据剪辑到屏幕上

这一步不是必要的,但可以提高速度并且通常在这里进行面剔除。如果呈现的“三角形”的法向量相反,则忽略该多边形绕序规则。

  • 渲染3D/2D数据
  • 屏幕渲染只使用v.x,v.y坐标,而v.z用于z-buffer测试/值,透视投影需要进行透视除法。

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

    Z-buffer的工作原理如下: Z-bufferzed)是与屏幕(scr)大小(分辨率)相同的2D数组。任何像素scr[y][x]仅在if (zed[y][x]>=z)时呈现,此时scr[y][x]=color; zed[y][x]=z; if条件可以不同(可更改)。

    如果使用三角形或更高级别的基元进行渲染,则将得到的2D基元转换为像素,这个过程称为光栅化,例如:

    以下是其外观:

    3D rendering

    [注]

    变换矩阵是可乘的,因此如果您需要通过M矩阵转换N点,则可以创建单个matrix = m1*m2*...mM并仅通过此结果的matrix转换N点以提高速度。有时会使用3x3变换矩阵+平移向量代替4x4矩阵。在某些情况下,这样更快,但您不能很容易地将多个变换相乘。对于变换矩阵操作,请查找基本操作,例如旋转或平移,还有一些用于LCS内部旋转的矩阵,这些对于人类控制输入更合适,但这些不是渲染器(如OpenGLDirectX)的本土矩阵。(因为它们使用逆矩阵)

    现在所有上述内容都是用于标准多边形渲染(对象表面边界表示)。还有其他渲染器,如体积渲染或(背部)光线追踪器和混合方法。场景也可以具有任意维度,而不仅仅是3D。这里有关于这些主题的相关问答


    0
    你可以查看书籍《计算机图形学原理与实践-第三版》Hughes等人的第15章。该章节推导了射线投射和光栅化算法,然后构建了软件光线追踪器、软件光栅化器和硬件加速光栅化渲染器的完整源代码。

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接