Make it Better
了解3D渲染 揭开shader神秘面纱
2016-10-10 StanWind


基础知识



Float           32位高精度浮点数



Half             16位中精度浮点数



Fixed           11位低精度浮点数



渲染过程



1.     对在三维世界坐标3D模型投影到以摄像机为坐标中心的二维坐标



2.     图元的装配(光栅化、格栅化)



3.     插值填充颜色



步骤一:投影



           一个3D模型想要显示在二维平面上 首先进行的过程就是投影。投影的过程是将模型的世界坐标转成二维的屏幕坐标。这一过程分三个步骤----MVP。这些变换都属于矩阵计算,能够做到旋转、缩放、位移。这一过程在shader中叫VertexShader(顶点处理)



例如如下缩放位移矩阵:



2016-10-10



 



MMatrix  在世界坐标中的矩阵变换






例如我们在unity中创建一个cube



 



2016-10-10



我们从正面看到的
能确定的八个顶点进行投影计算



2016-10-10



用上说的矩阵来存储这个cube的每个顶点的数据



V:坐标归一化 使得模型顶点坐标以摄像机的坐标轴



2016-10-10



如图要变换的八个顶点



我们需要通过计算
将这些点转换为摄像机拍到的平面的二维坐标



P:视锥挤压 使得模型达到透视投影(空间上同样大小的事情,越远离投影面越小)的效果



2016-10-10



例如我们在unity中创建一个cube



不管这个cube的世界坐标如何
最后都要渲染在二维屏幕上



所以我们对cube的八个顶点进行投影的坐标变换



2016-10-10



首先我们能确定摄像机看到的视角
然后对这个物体做透视投影



从侧面看
y轴上进行一个压缩



2016-10-10



从摄像机正面看 z轴被压缩



2016-10-10



这个压缩后的值范围在[0,1] 而不是压成0



2016-10-10



这样做的目的是为了从摄像机的角度看过去有远近效果



就能体现出3D场景的样子
例如:景深效果



 



顶点处理公式



Pos(proj) = MVPxPos(3D)



M V P是三个不同的矩阵



 



Shader代码:



float4 vert(float4 v:POSITION):SV_POSITION{



           return
mul(UNITY_MATRIX_MVP,v);



}



 



 



 



 



 



步骤二:图元装配(格栅化)



2016-10-10



例如一个正方形图片
4个顶点



我们对其渲染前需要把这张sprite分出一个一个像素点



而格栅化的最小单元需要3个顶点
也就构成了一个三角形



像这样我们可以把一张巨大的图转换成bitpic去进行渲染每个小图形



所以细分的程度决定了锯齿明显程度



2016-10-10



步骤三:颜色插值采样



           根据贴图来对模型进行一个颜色的插值取样,也就是给现有的像素点进行上色,这一过程在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的几个coreGPU的并行能力可谓强大,例如GTX 1080 1920CUDA core,而且cpu计算再uploadGPU上的代价相比十分的大。



举个例子:



GPU显存中会存储顶点数据、索引数据、贴图、shader代码参数等,RAM当然也能存储这些。



那么一张1024x1024的图



顶点数据大小:1024*3*4 byte = 12k



索引数据大小:1022*3*2 byte = 5k



贴图数据大小:1024*1024*4 byte = 4M



代码和参数大小:几K



 



这是一张图的传输,如果是整个场景,那么uploadGPU的代价是巨大的。

发表评论:
昵称

邮件地址 (选填)

个人主页 (选填)

内容