首页 > 代码库 > Unity Shader入门精要读书笔记(一)序章
Unity Shader入门精要读书笔记(一)序章
本系列的博文是笔者读《Unity Shader入门精要》的读书笔记,这本书的章节框架是:
第一章:着手准备。
第二章:GPU流水线。
第三章:Shader基本语法。
第四章:Shader数学基础。
第五章:利用简单的顶点/片元着色器来实现辅助技巧。
第六章:基本光照模型。
第七章:法线纹理、遮罩纹理等基础纹理。
第八章:透明度测试和透明度混合。
第九章:复杂光照实现。
第十章:高级纹理(立方体纹理等)。
第十一章:纹理动画、顶点动画。
第十二章:屏幕特效。
第十三章:深度纹理。
第十四章:非真实感的渲染算法。
第十五章:噪声在游戏渲染中的应用。
第十六章:优化技巧。
第十七章:表面着色器实现渲染。
第十八章:物理渲染技术。
第十九章:Unity5中的可能出现的问题。
第二十章:更深入的大门。
本书的主旨:原理+使用技巧。
第一篇的笔记:
第二篇到第四篇没有动手编程,都是理论知识。
第二篇《渲染流水线》的笔记:
1.渲染流水线是为了在屏幕上渲染二维图像;
2.渲染流水线的输入是虚拟摄像机、光源、shader和纹理;
3.渲染流程的三个阶段:应用阶段、几何阶段、光栅化阶段;
4.应用阶段是CPU负责实现的,开发者主导此阶段;
5.开发者在应用阶段下的任务有:a准备好场景如摄像机的位置和朝向、光源等,b粗粒度剔除工作,是为了将不可见的物体剔除,不让它们传到几何阶段,c设置好每一个模型的渲染状态如材质、纹理、shader等;
6.渲染图元包括点、线、三角面等需要被绘制的几何信息;
7.几何阶段在GPU上进行,它决定图元以何种方式绘制,在哪里绘制等,和每一个渲染图元打交道,输入的渲染图元经过多步处理后,输出屏幕空间中的而为顶点坐标、深度值、着色细节等信息;
8.光栅化阶段是为了利用上一个阶段产生的信息产生屏幕上的像素,渲染出最终图像的,在GPU上进行本阶段。对顶点的数据进行插值,得到最终的像素。
9.三个阶段都会有更加细的流水线划分;
10.CPU是渲染流水线的起点;
11.应用阶段a将数据加载到显存中,b设置渲染状态(也就是shader、纹理等),c调用drawcall;
12.渲染所需数据从硬盘HDD加载到内存RAM中,再被加载到显存VRAM中;
13.显卡对显存的访问更加快,比起对内存,更不用说比起HDD;
14.渲染状态规定了场景中的网格是如何被渲染的,例如使用了何种顶点着色器(VertexShader)片元着色器(FragmentShader)、光源属性和材质等;
15.CPU将渲染状态准备好后,通过调用DrawCall让GPU进行渲染,如果一直不改动此渲染状态,那么GPU将会一直以这个渲染状态来进行绘制;
16.DrawCall的调用不需要指定任何材质信息(原因上一点也说了),一次DrawCall命令针对一个图元Primitives的列表;
17.顶点数据由CPU加载到显存上去,然后DrawCall交由顶点着色器处理;
18.顶点着色器完全可编程,通常为顶点做空间变换,顶点着色等功能;
19.曲面细分着色器用于细分图元;
20.几何着色器用于逐图元着色,或者用于产生更多的图元;
21.裁剪将不再摄像机内的顶点裁掉,剔除某些三角形面;
22.屏幕映射将图元的坐标切换到屏幕坐标系下;
23.几何阶段的流水线为:顶点数据》顶点着色器》曲面细分着色器(可选)》几何着色器(可选)》裁剪》屏幕映射;
24.片元着色器可以编程,负责逐片元操作,逐片元操作为了执行颜色修改、深度缓冲、混合等,逐片元操作是可配置而不可编程的;
25.光栅化阶段的流水线是:三角形设置》三角形遍历》片元着色器》逐片元操作;
26.顶点着色器处理单元是顶点,每进来一个顶点就会调用一次顶点着色;
27.顶点着色器本身不知道顶点之间的拓扑关系,也不销毁或创建顶点;
28.顶点着色器能够并行处理顶点,因为顶点之间相互独立;
29.顶点着色器主要完成坐标变换和逐顶点光照计算;
30.顶点着色器必须要完成的一个工作:把顶点坐标从模型空间转换到齐次裁剪空间,这个空间是视野空间,这个空间也是为了做裁剪运算的,比如把不在(-1,-1,-1)到(1,1,1)里的点裁剪掉;
31.术语:归一化设备坐标NDC;
32.OpenGL和Unity的NDC中的z分量是-1到1的,而DX是0到1的;
33.在NDC单位立方体内进行裁剪时,在视野内的部分保留,因而可能产生新顶点,效果如下:
34.裁剪是硬件决定的,无法编程;
35.屏幕映射将图元的x和y转换到屏幕坐标系下,屏幕映射不处理z,z和映射后的xy合称窗口坐标系;
36.DX的屏幕坐标系原点在左上角(和UE一样),OpenGL的原点在左下角;
37.经过了几何阶段的屏幕映射的处理,将会传来关于顶点的额外信息如深度值,法线,视角方向等;
38.光栅化的两个重要目标:a图元覆盖了哪些像素,b计算这些像素的颜色;
39.三角形设置是为了计算三角形三条边处在哪些像素上的;
40.三角形遍历是为了计算某一个像素是否被一个三角形覆盖,如果是的话,这些像素称为“片元”fragment,这个遍历过程也称为扫描变换;注意片元和像素并不完全一致;
41.在所有的量上,比如深度、颜色等,为片元进行插值计算;
42.片元着色器接受三角形遍历得到的对顶点插值的结果,输出是一个或者多个颜色值;
43.片元着色器还能够完成重要的渲染技术如纹理采样;
44.真正对像素产生影响的阶段是逐片元操作;
45.逐片元操作PerFragmentOperations是OpenGL的说法,在DX中称为OutputMerger输出合并阶段;
46.逐片元操作a决定每个片元的可见性,如深度测试等,b将片元和已经储存在颜色缓冲区的颜色进行合并,或者说混合;
47.逐片元操作是可配置的;
48.逐片元操作的流程:片元》模板测试》深度测试》混合》颜色缓冲区;
49.模板测试是自定义的测试,当一个片元的某个指标值和缓冲区中的此指标值做比较,通过测试的话,就可以进入下一个测试,没有通过的话就被舍弃;不管有没有通过,都可以设置缓冲区中的指标值;
50.深度测试常常用来做前后遮挡的测试,如当前片元的深度比缓冲区中的深度小(靠近屏幕),那么它就通过测试,并有权利修改缓冲区中的深度指标;
51.通过了所有测试的进入混合操作,如果没有开启混合(也就是完全遮挡的),那么直接使用该片元的颜色,更新到缓冲区中的颜色值;如果开启了的话,将缓冲区和本片元的颜色做一个数学运算得到新值写入给缓冲区;
52.逐片元操作中的测试往往会被移到更加早的步骤上进行测试,为了节省计算;深度测试提早做,EarlyZ技术;
53.避免我们看到光栅化中的图像,将会进行双重缓冲,即当下一帧画面的内容准备好后,才登上屏幕;
54.OpenGL和DX是计算机图像的API,由APP调用,GL和DX则会去调用显卡驱动,显卡驱动真正去调用硬件设备;
55.SL着色语言是用来编写着色器代码的,从而避免写汇编语句,HLSL是DX的着色语言,GLSL是OpenGL的着色语言,CG(C for Graphic)是NVIDIA的着色语言;
56.UnityShader语言和CG、HLSL和GLSL不完全一样是着色器语言;
57.CPU和GPU是如何一起工作的?有一个命令缓冲队列,CPU向其中塞入命令如DrawCall或者改变渲染状态,而GPU则是从中获取命令并执行;
58.渲染速度往往快于提交命令的速度,也就是说CPU提交DrawCall数目太多将会导致效率低(复制10000个1kb文件和复制一个10M文件的比喻,即提交大量很小的DrawCall会导致效率低下);
59.如何减少DrawCall?尽量让一次DrawCall做很多活,也就是批处理思想;
60.固定函数流水线也称为固定管线,通常指在较旧的GPU上实现的渲染流水线;(只可以配置而不可以完全控制,就好像只能使用开关控制而不能修改布局的电路);注:管线是管道线的简称,也就是封闭的流水线,无法完全操控内部;
61.Shader是GPU流水线上一些课高度编程的阶段,最终代码在GPU上运行,有特定类型的着色器(顶点着色器、片元着色器),利用着色器控制流水线中的渲染细节如顶点着色器进行变换等;
Unity Shader入门精要读书笔记(一)序章