一. Unity中三种着色器书写格式
- surface shaders 表面着色器
- vertex and fragment shaders and 顶点和片段着色器
- fixed function shaders 固定功能着色器
二. 顶点着色器和片段着色器
三维空间中任何复杂的模型都是由若干个三角形组成,顶点(Vertex)就是指这些三角形的顶点,而片段(fragment)就是指三角形的填充区域
三. 表面着色器(Surface Shader)的标准输出结构
struct SurfaceOutput
{
half3 Albedo;//反射率
half3 Normal;//法线
half3 Emission;//自发光,用于增强物体自身的亮度,使之看起来好像可以自发光
half Specular;//镜面
half Gloss;//光泽
half Alpha;//透明
};
四. 表面着色器使用 #pragma surface surfaceFunction lightModel[optionalparams]
指令,以声明它是一个表面着色器
surfaceFunction
:表示Cg函数中表面着色器(surface shader)代码.这个函数的格式应该是这样:void surf(Input IN,inout SurfaceOutput o)
,Input
是你自己定义的结构.Input
结构中应该包含所有纹理坐标(texture coordinates)和表面函数(surfaceFunction)所需要的额外的必须变量.lightModel
:在光照模式中使用.内置的是Lambert(diffuse)和BlinnPhong(specular).
五. 表面着色器附加输入结构
float3 viewDir
:视图方向(view direction)值.为了计算视差效果(Parallax effexts),边缘光照(rim lighting)等,需要包含视图方向(view direction)值.float4 COLOR
:每个顶点(per-vertex)颜色的插值float4 screenPos
: 屏幕空间中的位置.为了反射效果,需要包含屏幕空间中的位置信息float3 worldPos
: 世界空间中的位置float3 worldRefl
: 世界空间中的反射向量.如果表面着色器(surface shader)不写入法线(o.Normal)参数,将包含这个参数.float3 worldNormal
:世界空间中的法线向量(normal vector).如果表面着色器(surface shader)不写入法线(o.Normal)参数,将包含这个参数.float3 worldRefl (INTERNAL_DATA)
:世界空间中的反射向量,如果表面着色器(surface shader)不写入法线(o.Normal)参数,将包含这个参数.为了获得基于每个顶点法线贴图(per-pixel normal map)的反射向量(reflection vector)需要使用世界反射向量(WorldReflectionVector(IN,o.Normal)).float3 worldNormal(INTERNAL_DATA)
:世界空间中的法线向量(normal vector).如果表面着色器(surface shader)不写入法线(o.Narmal)参数,将包含这个参数,为了获得基于每个顶点法线贴图(per-pixel normal map)的法线向量(normal vector)需要使用世界法线向量(WorldNormalVector(IN,o.Normal)).
六. 光照模式声明
光照模式是一个以Lighting开头与名字组合在一起的合乎规范的函数.你可以在你的着色器文件(shader file)或导入文件(included filed)中任何一个地方声明它.这个函数是:
1. half4 LightingName_DirLightmap(SurfaceOutput s,fixed4 color,fixed4 scale,bool surfFuncWritesNormal)
:这个使用的不依赖视图方向(view direction)的光照模式(light model).
2. half4 LightingName_DirLightmap(SurfaceOutput s,fixed4 color,fixed4 scale,half3 viewDir,bool surfFuncWritesNormal,out half3 specColor)
:这是使用的依赖与视图方向(view direction)的光照模式(light model).