基础知识
Float 32位高精度浮点数
Half 16位中精度浮点数
Fixed 11位低精度浮点数
渲染过程
1. 对在三维世界坐标3D模型投影到以摄像机为坐标中心的二维坐标
2. 图元的装配(光栅化、格栅化)
3. 插值填充颜色
步骤一:投影
一个3D模型想要显示在二维平面上 首先进行的过程就是投影。投影的过程是将模型的世界坐标转成二维的屏幕坐标。这一过程分三个步骤----M、V、P。这些变换都属于矩阵计算,能够做到旋转、缩放、位移。这一过程在shader中叫VertexShader(顶点处理)。
例如如下缩放位移矩阵:
M:Matrix 在世界坐标中的矩阵变换
例如我们在unity中创建一个cube
我们从正面看到的 能确定的八个顶点进行投影计算
用上说的矩阵来存储这个cube的每个顶点的数据
V:坐标归一化 使得模型顶点坐标以摄像机的坐标轴
如图要变换的八个顶点
我们需要通过计算 将这些点转换为摄像机拍到的平面的二维坐标
P:视锥挤压 使得模型达到透视投影(空间上同样大小的事情,越远离投影面越小)的效果
例如我们在unity中创建一个cube
不管这个cube的世界坐标如何 最后都要渲染在二维屏幕上
所以我们对cube的八个顶点进行投影的坐标变换
首先我们能确定摄像机看到的视角 然后对这个物体做透视投影
从侧面看 在y轴上进行一个压缩
从摄像机正面看 z轴被压缩
这个压缩后的值范围在[0,1] 而不是压成0
这样做的目的是为了从摄像机的角度看过去有远近效果
就能体现出3D场景的样子 例如:景深效果
顶点处理公式
Pos(proj) = MVPxPos(3D)
M V P是三个不同的矩阵
Shader代码:
float4 vert(float4 v:POSITION):SV_POSITION{
return mul(UNITY_MATRIX_MVP,v);
}
步骤二:图元装配(格栅化)
例如一个正方形图片 有4个顶点
我们对其渲染前需要把这张sprite分出一个一个像素点
而格栅化的最小单元需要3个顶点 也就构成了一个三角形
像这样我们可以把一张巨大的图转换成bitpic去进行渲染每个小图形
所以细分的程度决定了锯齿明显程度
步骤三:颜色插值采样
根据贴图来对模型进行一个颜色的插值取样,也就是给现有的像素点进行上色,这一过程在shader中叫PixelShader。
根据uv贴图和mesh 来进行一个插值取样渲染,uv的坐标精度越低,图像连续采样就可能出现重复,这样就可能造成马赛克的效果了。
差值计算方法:
Fixed4 frag(v2f IN):SV_Target{
采样 贴图 UV值
Half4 color = tex2D(_MainTex,IN.texcoord);
Return color;
}
相关
1.DirectX9前是固定渲染管线,VertexShader代码几乎是不可更改的,这也就导致了模型变换的阻碍。
2.当然没有VS也能做UI,不过这样就需要在摄像机拍摄的二维平面上直接参与了。
3.为什么不能实时取模型的定点坐标?
因为这一过程都是交给GPU去处理的。
那为什么要交给GPU去处理呢?
这是因为点的渲染过程都是并行的,相对于CPU的几个core,GPU的并行能力可谓强大,例如GTX 1080 有1920个CUDA core,而且cpu计算再upload到GPU上的代价相比十分的大。
举个例子:
GPU显存中会存储顶点数据、索引数据、贴图、shader代码参数等,RAM当然也能存储这些。
那么一张1024x1024的图
顶点数据大小:1024*3*4 byte = 12k
索引数据大小:1022*3*2 byte = 5k
贴图数据大小:1024*1024*4 byte = 4M
代码和参数大小:几K
这是一张图的传输,如果是整个场景,那么upload到GPU的代价是巨大的。
本文地址:https://www.stanwind.com/post/33
版权声明:若无注明,本文皆为“Make it Better”原创,转载请保留文章出处。