UnityShader(一)
背景小插曲:
1999年,第一个CPU产生。有基于OpenGL的ShaderLanguage GLSL(依赖硬件,但能跨很多平台),基于DirectX的ShaderLanguage HLSL(不依赖硬件,不能跨很多平台),还有两者混合的Cg:真正意义上的跨平台,语法像HLSL,但无法完全发挥出OpenGL的最新特性。
渲染流水:
分为应用阶段,几何阶段,光栅化阶段,如下图:
应用阶段
是Cpu全权负责,主要做三件事:1.将数据从硬盘经内存加载到显存 2.不可见剔除 3.调用drawcall,设置渲染状态,所谓的drawcall是一系列指令组成的队列,Cpu控制他们入队,到了该出队的时候会出队交给Gpu执行这些指令。
几何阶段:
顶点数据依次经过顶点着色器,曲面细分着色器和几何着色器,还要进行一个裁剪操作,最后会被转换成屏幕坐标,+未被处理的z轴构成了窗口坐标系,这些值会被传到光栅化阶段。
其中:1.顶点着色器:处理单位是顶点。每输入一个顶点,它就会处理一次。无法得到顶点与顶点的关系,无法创建顶点。功能:坐标变换,逐顶点光照。2.裁剪:一个图元与摄像机的关系有三种:完全在视野内,部分在视野内,完全在视野外。只有部分在视野内的才进行裁剪。3.屏幕映射:齐次坐标转换到屏幕坐标,这实际上是一个缩放的过程,在这个过程里z轴不被处理。屏幕坐标和z轴构成了窗口坐标系,这些值会被传到光栅化阶段。
光栅化阶段:
1.三角形设置:需要得到三角形网格对像素的覆盖情况,就必须计算每条边上的像素坐标,有了这些像素坐标,就能得到三角形边界的表示方式。2.三角形遍历:如果一个像素被三角形网格覆盖,就会产生一个片元。这样一个找到哪些像素被覆盖的过程叫做三角形遍历。3.片元着色器:输入是从顶点着色器输出的数据插值得到的。输出是一个或多个颜色值。顶点着色器会输出每个顶点的纹理坐标,经过光栅化对三角网格的三个顶点对应纹理坐标进行插值后,就可得到所覆盖片元的纹理坐标。4.逐片元操作是OpenGL中的说法,DX中成为输出合并阶段。(1)决定每个片元的可见性,深度测试,模板测试。(2)如果一个片元通过了所有测试后,就需要将这个片元和已经存在颜色缓冲区中的色彩进行合并。 模板测试:Gpu读取模板缓冲区中该片元位置的模板值,然后与参考值进行比较。深度测试:该片元深度值与缓冲区深度值比较。(一般是小于等于算通过)。合并混合:本次渲染得到的颜色可以覆盖也可以混合之前的颜色。(一般不透明的物体要关闭混合操作)
GPU会使用双缓冲区(前置和后置),对场景的渲染是在后置缓冲区中进行。一旦场景已经被渲染到后缓冲区中,GPU就会交换前后缓冲区中的内容,前置缓冲区是我们看到的图像,因此,我们看到的图像是连续的。