写在前面的话:

一.表面着色器的工作方式

在表面着色器中,把需要的数据作为”表面函数”的输入,计算后用来初始化结构SurfaceOutput。下面就先来看看它的结构是什么样的

特别说明一下: 在unity5中,表面着色器也可以使用基于物理的光照模型。内置的标准光照和标准镜面反射模型会使用下面的输出结构

二.表面着色器的编译指令

表面着色器是放在CGPROGRAM..ENDCG代码块中的,和其他shader 所不同的主要有以下两点:

  • 必须被放置在SubShader代码块中,而不是在Pass块中
  • 必须使用#pragma surface ...指令来指定它的surface函数

#pragma surface指令的具体格式如下面所示:

下面将会来细致介绍参数

必选参数
  • surfaceFunction: 这个参数就是我们的表面函数了,它的函数签名是void surf (Input IN, inout SurfaceOutput o)。这里的Input类型是一个需要自己去定义的结构体(需要遵循它的标准,准确地说是去定制)。这个结构里面应该包含纹理坐标和表面函数所需要的一些额外字段。
  • lightModel: 光照模型,就是指定shader所使用的光照模型。内置的有基于物理的StandardStandardSpecular,当然,也可以使用不基于物理的Lambert(diffuse)BlinnPhong(specular)
可选参数

可选参数比较多,这里不一一列出来,需要点我查看

表面着色器的输入结构

表面着色器的输入结构Input通常有一个shader所需要的纹理。需要注意的是,纹理坐标字段的名字必须以"uv"开头(或者以"uv2"开头标识第二个纹理坐标)。
下面的列表展示了Input结构的可选额外字段

  • float3 viewDir: 顾名思义,这个字段表示了当前视角方向,即表示摄像机的正前方的向量。通常用来计算一些视差效果和边缘光的效果等。
  • float4 : COLOR: 带有COLOR语义的字段,表示每个顶点的颜色,顶点之间采用差值来确定颜色。
  • float4 screenPos: 表示屏幕空间的位置,主要用来反射效果或者屏幕空间的效果实现。
  • float3 wordPos: 在世界空间的位置。
  • float3 worldRefl: 如果surface shader不写o.Normal那么将表示世界空间中的反射向量。
  • float3 worldNormal: 如果surface shader不写o.Normal,那么用来表示世界空间中的法向量。
  • float3 wroldRefl: 如果surface shader写了o.Normal, 那么这个字段表示世界空间中的反射向量。如果想要获取逐像素法线贴图的反射向量,使用WorldReflectionVector (IN, o.Normal)
  • float3 worldNormal: 如果surface shader写了o.Normal, 那么这个字段表示世界空间的法向量。如果想获取逐像素法线贴图的法向量,使用WorldNormalVector (IN, o.Normal)

(未完,待续)

01-22 11:01