math计算一个简单的graphicspipe道

我正在尝试/理解graphicspipe道中所需的所有基本math计算,以便从VRML等3D场景描述中渲染简单的2D图像。 是否有一个很好的例子,如模型转换 (对象坐标到世界坐标), 视图转换 (从世界坐标到视图坐标), 计算顶点法线照明, 裁剪计算视图内的对象的屏幕坐标创build2D投影来计算具有颜色的单个像素。

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

首先来解释一下:

  1. 变换matrix

    表示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轴的单位vector,
    • Y(yx,yy,yz)GCSY轴的单位向量
    • Z(zx,zy,zz)GCSZ轴的单位vector
    • P(x0,y0,z0)是GCS中表示坐标系的原点

    变换matrix用于变换GCSLCS (局部坐标系)之间的坐标,

    • GCS -> LCS: Al = Ag * m;
    • GCS <- LCS: Ag = Al * (m^-1);
    • Al (x,y,z,w=1)是在均匀坐标系下的LCS …中的三维
    • Ag (x,y,z,w=1)GCS …中的三维

    加上同质坐标w=1 ,所以我们可以乘以4×4matrix的3D向量

    • m变换matrix
    • m^-1逆变换matrix

在大多数情况下是m正交,这意味着X,Y,Zvector彼此垂直 ,并且具有单位大小,这可以用于在旋转,平移等之后恢复matrix精度。

有关更多信息,请参阅了解4×4均匀变换matrix

  1. 渲染matrix

    通常使用这些matrix:

    • model – 表示实际渲染的对象坐标系
    • view – 表示摄像机坐标系( Z轴是视图方向)
    • modelview视图 – 模型和视图相乘在一起
    • normal – 与modelview相同,但对于法向量计算x0,y0,z0 = 0
    • texture – 操纵纹理坐标以便于纹理animation,通常影响单位matrix
    • projection – 代表摄像机视图( 透视 ,正视)的投影,它不应该包含任何旋转或平移,更像是相机传感器校准(否则,雾和其他效果将失败…)
  2. 渲染math

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

    • Z缓冲区是很容易的,本地到现在的gfx HW
    • Zsorting是由CPU完成的,所以它的速度较慢,需要额外的内存,但是正确的透明表面渲染是必须的。

所以pipe道是这样的:

  1. 从模型中获取实际呈现的数据

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

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

    这一步并不是必须的,但是为了加快屏幕渲染的速度,并且通常在这里进行扑杀。 如果呈现的“三angular形”的法向vector相反,则多边形缠绕规则集忽略“三angular形”

  4. 渲染3D / 2D数据

    只使用vx,vy坐标进行屏幕渲染,vz进行z-buffertesting/值也在这里进行透视投影的透视分割

    • vx/=vz,vy/=vz

    Z缓冲区是这样工作的: Z缓冲区zed )是与屏幕( scr )具有相同大小(分辨率)的二维数组。 在这种情况下,任何像素 scr[y][x]if (zed[y][x]>=z)的情况下被渲染scr[y][x]=color; zed[y][x]=z; scr[y][x]=color; zed[y][x]=z; if条件可以不同(可以改变)

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

3D渲染

[笔记]

变换matrix是可乘的,所以如果需要由Mmatrix变换N个点,则可以创build单个matrix = m1*m2*...mM并仅由此结果matrix转换N个点(对于速度)。 有时使用3x3变换matrix+ shift vector而不是4x4matrix。 在某些情况下速度会更快,但是不能将更多的转换放在一起如此简单。 对于转换matrix操作,寻找像旋转或平移这样的基本操作,在LCS内部也有用于旋转的matrix,它们更适合于人类的控制input,但是它们不像OpenGLDirectX那样是原生的。 (因为他们使用逆matrix)

你可以看一下Hughes等人的“ Computer Graphics:Principles and Practice – Third Edition ”一书的第15章 。 那一章

推导出光线投射和光栅化algorithm,然后为软件光线跟踪器,软件光栅化器和硬件加速栅格化渲染器构build完整的源代码。