1.1 现代GPU渲染流水线
首先,图形渲染流水线以顶点数据作为开始,当GPU获取到CPU传递的顶点数据之后,整个图形渲染流水线正式开始运作
图形渲染流水线的第一个站点是顶点着色器(Vertex Shader),它允许使用者通过程序进行配置。在顶点着色器中,顶点坐标会从模型空间变换到裁剪空间。除此之外,这个阶段还可以通过Shader程序对顶点进行处理,以实现一些特殊的效果。
装配图元(Primitive Assembly)阶段将顶点着色器输出的顶点数据装配成指定的几何图元,基本图元包括:点、线、面。
光栅化(Rasterization)是将几何图元转变为片段(Fragment)的过程。屏幕上显示的图像都是由像素组成,而3D物体是由点、线、面这些基本图元组成的,要让几何图元能在屏幕上显示为像素就需要经过光栅化处理。该阶段包含两部分工作:
首先,确定屏幕坐标中的哪些整型栅格区域被基本图元占用。
其次,分配颜色值和深度值到各个区域。
片段在经过视锥体裁切之后就会被传递到片段着色器,它最主要目的是计算每一个像素的颜色,这个阶段也可以通过shader程序进行配置。在这个阶段中,片段着色器会计算光照、阴影、纹理等所有的颜色数据,最终计算出像素的颜色
当所有像素的颜色都确定下来以后,会进入到测试(Test)和混合(Blending)阶段。在这个阶段会检测所有像素的深度值,将当前片段的深度值与深度缓存中的数值对比,从而判断这个像素的前面是否有物体对它进行遮挡,进而决定这个像素是否应该被丢弃。
通过测试的像素会与已经绘制好的图像进行混合,从而得到最终的颜色。
帧缓存(Frame Buffer)是图形渲染流水线的最后一个“站点”,帧缓存中存储着用于渲染到屏幕上的像素,等待下一步输出到屏幕上
1.2 什么是shader
shader,着色器。它是通过编写代码实现的,因此本质上也是程序。只不过shader程序和一般程序不一样,它并不是运行在CPU上,而是运行在GPU上,其目的是告诉GPU如何计算和输出图像。
shader所处的阶段只是渲染管线中的一部分,它主要是由顶点着色器(Vertex Shader)和片段着色器(Fragment Shader)组成
编写shader的语言主要有两种:
基于Direct 3D的HLSL,由微软开发,在自家Windows平台兼容性良好,因此成为游戏开发的首选
基于OpenGL的GLSL,具有良好的移植性,可以在不同平台上使用
NIVIDIA希望显卡的程序开发独立于DX和GL的图形库,于是联合微软开发了CG语言,和HLSL愈发极为相似。使用CG编写的Shader拥有跨平台性,因此CG语言是编写Unity Shader的首选语言。
1.3 Shader和材质的关系与区别
shader实际上是一段程序,它负责把输入的顶点数据按照代码里指定的方式进行处理,并对输入的颜色或贴图等进行计算,然后输出数据。图像绘制单元获取到输出的数据便可将图像绘制出来,最终呈现在屏幕上。
Shader程序代码加上开放的参数设置以及关联的贴图等资源,为实现某种效果而打包储存在一起,最终得到的就是材质(material)。材质是shader的实例化资源,一个shader可以实例化为多个材质,并调节为不同的材质效果。最后把材质指定给某个模型就可以渲染初出应的效果。
1.4 Shader的组织架构
shader实际上是一段程序。
无论选择任何语言编写Shader,无论编写的shader是何种类型,Unityshader总是通过ShaderLab语言进行包装并组织结构。通常情况下,Shader的大致结构如下所示:
shader "Name"
{
Properties
{
//开放到材质面板的属性
}
Subshader
{
//顶点片段着色器
//或者表面着色器、固定函数着色器(基本没了)
}
Subshader
{
//更加精简的版本;在旧图形设备上运行
}
……
Fallback "Name"
}
首先,最开始定义的是Shader的名称,然后定义开放出来的所有属性,接下来是真正的Shader代码。Shader中可以编写多个子着色器(Subshader),但至少需要一个。在应用程序运行过程中,GPU会先检测第一个子着色器能否正常运行,如果不能正常运行就会再检测第二个以此类推。假如当前GPU的硬件版本太旧,以至于所有的子着色器都无法正常运行时,则执行最后的回退(Fallback)命令,运行指定的一个基础着色器。
如果编写的是顶点片段着色器,每个子着色器中还会含有一个甚至多个Pass。在运行的过程中,如果某个子着色器能够在当前GPU上运行,那么该子着色器内的所有Pass会依次执行,每个Passde的输出的结果会以指定的方式与上一步的结果进行混合,最终输出。
如果编写的是表面着色器(Surface Shader),着色器的代码也是包含在子着色器中,但与定点片段着色器不同的是,表面着色器不会再嵌套Pass。系统在编译表面着色器的时候会自动生成多个对应的Pass,最终编译出来的shader本质就是顶点片段着色器。
标签:片段,渲染,Shader,实时,shader,unity,顶点,像素,着色器 From: https://blog.51cto.com/u_136836/6318744