读UnityShader编程入门精要 总结

时间:2022-05-06 10:21:23

一本不错的书,值得推荐


空间概念

绘制屏幕要将每个物体从自己所属的物体空间依次经过世界空间,摄像机空间,裁剪空间,标准设备空间进行变换。最终到达实际窗口空间。


渲染流水线

  1. 应用阶段
    通常由cpu负责实现,
    首先准备好场景的数据,
    其次做一个粗粒度剔除工作(culling),把那些看不见的物体剔除出去
    设置好每个模型的渲染状态,
    输出渲染所需的几何信息。即渲染元

  2. 几何阶段
    通常由gpu负责实现。
    负责和每个渲染元打交道,们进行逐定点,逐多边形的操作。
    把定点坐标变换到屏幕空间中,再交给光栅器记性处理。出书屏幕空间的二维定点坐标,每个定点对应的深度值 着色等相关信息

  3. 光栅化阶段
    使用上个阶段传递的数据来产生屏幕上的像素。并渲染最终的图像。
    在gpu上运行
    需要对上一个阶段得到的逐定点数据进行插值,然后再进行逐像素处理


shader和material

shader负责将输入的mesh以指定的方式和输入的贴图或颜色等组合作用,然后输出。绘图单元可以根据这个输出来将图像绘制到屏幕上。输入的贴图或者颜色等,加上对应的shader,以及对shader的特定的参数设置,将这些内容打包存储到一起,就得到material。将material赋予合适的renderer来进行渲染输出

在ccprogram…endcg这样一个代码块中,同样是一段cg程序,要访问在properties中所定义的变量,必须使用和之前变量相同的名字进行申明。
再次声明sample2D _mainTe就是再次声明并连接了_MainTex使得接下来的cg程序能够使用这个变量。


GPU

所有渲染所需的数据都需要从硬盘中加载到系统内存。然后网格和纹理等数据又被加载到显卡上的存储空间-显存。显卡对于显存的访问都督更快,而且大多数显卡对于ram没有直接的访问权限。

drawcall是一个命令,发起方是cpu,接收方是gpu。
这个命令仅仅会指向一个需要被渲染的图元列表。

gpu的渲染流水线接受顶点数据作为输入,这些顶点数据是由应用阶段加载到显存中,再由drawcall指定。这些数据随后被传递给顶点着色器。

顶点着色器(是完全可编程的,它同城用于实现顶点的空间变换,
输入来自cpu

裁剪culling,将那些不在摄像机视野内的顶点裁减掉。并剔除某些三角图元的面片。

屏幕映射,不可配置和编程,负责把每个图片的坐标转换到屏幕坐标系中。

顶点着色器本身不可以创建或销毁任何顶点,而且无法得到顶点和顶点之间的关系。相互独立性,所以gpu可以利用本身的特性并行化处理每一个顶点,意味着这一阶段的处理速度回很快。

opengl使用NDC(normalized device coordinates)z分量在【-1,1】之间

完全在视野内的图元就继续传递给下一个流水线阶段。完全在视野外的图元不会继续向下传递。部分在视野内的图元需要进行一个处理就是裁剪。
无法通过编程来控制裁剪的过程,这是硬件上的固定操作。

屏幕映射是吧每个图元的x和y坐标转换到屏幕坐标系中。

显卡驱动把opengl和directx调用翻译成了gpu能够听懂的语言。
因为显卡驱动的存在,几乎所有的gpu都能同事opengl和directx。

cpu向命令缓存区添加命令,而由gpu从中读取命令。
每次调用drawcall之前,cpu需要向gpu发送很多内容,包括数据 状态和命令等,cpu需要完成很多内容,包括数据 状态和命令。
gpu的渲染命令是很强的。渲染速度往往快于cpu提交命令的速度。
如果drawcall的数量太多,cpu就会把大量时间花费在提交drawcall上,造成cpu的过载。

批处理,提交大量很小的drawcall会造成cpu的性能瓶颈,cpu把时间都花费在准备drawcall上,批处理就是把很多小的drawcall合并成一个大的drawcall


光栅化

计算每个图元覆盖了哪些像素,以及为这些像素计算他们的颜色。

三角形设置
计算光栅化一个三角形网格所需的信息。
获得整个三角网格像素的覆盖情况,计算每条边上的像素坐标。
为了能够计算边界像素的坐标信息,需要三角形边界的表示方式。这个过程就叫三角形设置。

三角形遍历
会检查每个像素是否被一个三角网格所覆盖,如果覆盖,就会生成一个片元(Fragment)。这样一个找到那些像素被三角形所覆盖的过程就是三角形遍历。
片元是对三个顶点的信息进行插值得到的。

片元着色器在directx被称为像素着色器。
片元着色器的输入是上一个阶段对顶点信息插值得到的结果。其中最重要的就是纹理采集。

逐片元操作
在directx中,成为输出合并阶段。
模板测试:
gpu会首先读取模板缓冲区中该片元位置的模板值,然后将该值和读取(使用读取掩码)的参考值进行比较,如果片元没有通过测试,该片元就会被舍弃。
深度测试
gpu把该片元和已经存在于深度缓存区中的深度值进行比较。

双重缓冲
对场景的渲染是在后置缓冲,一旦场景已经渲染到了后置缓冲中,gpu就会交换后置缓冲区和前置缓冲区

混合是指是否将新的像素点直接覆盖旧的像素点,导致透明像素也会覆盖下方的像素


标准光照模型

自发光 emissive Cmissive
高光反射 specular Specular
漫反射 diffuse
环境光 ambient