编码:Unity Shader CG语言
1.常用的几个内置文件
这些文件通常都被封装在cginc文件中,通过文件的包含来实现对文件中函数及变量的引用,大家可以到unity的安装目录下找到对应的文件,当然我们也可以写一些自己的cginc文件放置到该目录中,方便自己使用,具体方法可以参考Unity着色器代码复用。
A.UnityCG.cginc
1.这里包含了最常使用的帮助函数、宏和结构体。
2.UnityCG.cginc中一些常用的结构体
appdata_base:(用于顶点着色器的输入),包含变量:顶点位置、顶点法线、第一组纹理坐标
appdata_tan:(用于顶点着色器的输入),包含变量:顶点位置、顶点切线、顶点法线、第一组纹理坐标
appdata_full:(用于顶点着色器的输入),包含变量:顶点位置、顶点切线、顶点法线、四组(或更多)纹理坐标
appdata_img:(用于顶点着色器的输入),顶点位置,第一组纹理坐标
v2f_img:(用于顶点着色器的输出),裁剪空间中的顶点坐标、纹理坐标
3.常用的帮助函数,注意这些方向的其实位置都是模型空间的顶点
float3 WorldSpaceViewDir(float4 v): 输入一个模型空间的顶点位置,返回世界空间中从该点到摄像机的观察方向。
float3 ObjSpaceViewDir(float4 v): 输入一个模型空间的顶点位置,返回模型空间中从该点到摄像机的观察方向。
float3 WorldSpaceLightDir(float4 v): 仅用于前向渲染中,输入一个模型空间的顶点位置,返回世界空间中从该点到光源的光照方向,没有归一化。
float3 ObjSpaceLightDir(float4 v): 仅用于前向渲染中,输入一个模型空间的顶点位置,返回模型界空间中从该点到光源的光照方向。,没有归一化
float3 UnityObjectToWorldNormal(float3 normal):把法线方向从模型空间转换到世界空间
float3 UnityObjectToWorldDir(float3 dir):把方向向量从模型空间变换到世界空间中
float3 UnityWorldToObjectDir(float3 dir):把方向向量从世界空间变换到模型空间中
UnityObjectToClipPos:将顶点坐标转换为裁剪空间
4.宏
TRANSFORM_TEX(tex,name) //第一个是顶点的纹理坐标,第二个是纹理名
MainTex_ST:
MainTex_TexelSize:unity提供的用来访问xxx纹理对应的每个纹素的大小,如一张512x512大小的纹理,该值为1/512,在卷积中,我们需要对相邻区域内的纹理进行采样,就需要使用TexelSize计算各个相邻区域的纹理坐标。
B.Lighting.cginc
1.内置变量UNITY_LIGHTMODEL_AMBIENT:得到环境光部分,fixed3 ambient=UNITY_LIGHTMODEL_AMBIENT.xyz;_LightColor0:该内置变量用来访问该pass处理的光源的颜色和强度信息(注意想要得到正确的值需要定义合适的LightMode标签)_WorldSpaceLightPos0:得到光源方向,需要注意的是,在这里,我们假设场景中只有一个光源且该光源是平行光。如果有多个光源并且类型可能是点光源等其它类型,就不能这么处理。
C.UnityShaderVariables.cginc
0.UnityShaderVariables.cginc:这里包含unity内置的用于空间变换和摄像机以及屏幕参数的内置变量
1.变换矩阵
UNITY_MATRIX_MVP:当前的模型观察投影矩阵,用于将顶点/方向矢量从模型空间变换到裁剪空间,模型空间到世界空间到观察空间到投影空间。
UNITY_MATRIX_V / UNITY_MATRIX_P / UNITY_MATRIX_MV / UNITY_MATRIX_VP
_Object2World:当前的模型矩阵,用于将顶点/方向从模型空间变换到世界空间
_World2Object:从世界空间到模型空间。
2.摄像机和屏幕参数
unity提供了一些内置变量让我们访问当前正在渲染的摄像机的参数信息。
_WorldSpaceCameraPos:float3,该摄像机在世界空间中的位置。
2.内置变量
这里主要记录的是一些光照方向和视点方向的向量,这些东西都是很容易自己计算的,在OpenGL中通常都是由自己来计算,不过unity为我们提供了一些封装好的函数, 当你需要光照方向或视点方向的向量或相关转换的时候可以到这里来找一找。
其实根据它的命名规律也非常容易记住的,如果输入模型空间得到模型空间的向量,就是ObjSpaceXXX(),如果是输入模型空间的坐标得到世界空间的向量,就是WorldSpaceXXX(),如果输入世界空间坐标得到世界空间的向量就UnityWorldSpaceXXX()。
3.变换矩阵
mul函数
mul函数,是表示矩阵M和向量V进行点乘,得到一个向量Z,这个向量Z就是对向量V进行矩阵变换后得到的值。
HLSL的mul函数接受mul(V, M)或mul(M, V),要注意通常HLSL要依DirectX计算(V * M)使用mul(V, M)的形式.
特别需要小心的是,V如果是float3,前后行列不等,违反HLSL规范,但shader编译也不报错,直接当成float4(V, 0)处理,而不是当成float4(V, 1).即mul(float3, M)中的float3被当成向量,而不是顶点.
Unity3d 中,若是OpenGL,用的应该是GLSL,mul方法是(M,V)。
矩阵
内置的矩阵(float4x4):
名称 说明
UNITY_MATRIX_MVP 当前模型视图投影矩阵
UNITY_MATRIX_MV 当前模型视图矩阵
UNITY_MATRIX_V 当前视图矩阵
UNITY_MATRIX_P 当前的投影矩阵
UNITY_MATRIX_VP 当前视图投影矩阵
UNITY_MATRIX_T_MV 模型视图矩阵的转置
UNITY_MATRIX_IT_MV 模型视图矩阵的逆转置
unity_ObjectToWorld 当前模型矩阵
unity_WorldToObject 当前世界矩阵的逆矩阵
这里要特别说明一下UnityObjectToClipPos(v.vertex)) 方法,官方网站上说明,在写Instanced Shader时,通常情况下并不用在意顶点空间转换,因为所有内建的矩阵名字在Instanced Shader中都是被重定义过的,如果直接使用UNITY_MATRIX_MVP,会引入一个额外的矩阵乘法运算,所以推荐使用UnityObjectToClipPos / UnityObjectToViewPos函数,它们会把这一次额外的矩阵乘法优化为向量-矩阵乘法。
相机部分,
名称 类型 数值
_WorldSpaceCameraPos float3 世界空间相机的位置
_ProjectionParams float4 x = 1.0(或如果当前使用翻转投影矩阵渲染则为-1.0),y是相机的近平面,z是相机的远平面,w是1 / FarPlane
_ScreenParams float4 x是相机的渲染目标在像素里的宽度,y是相机的渲染目标在像素里的高度,z是1.0 + 1.0 /宽度和w是1.0 + 1.0 /高度
_ZBufferParams float4 用于线性化Z缓冲区的值。x(1-far /near),y(far/near)、z(x /far)和w(y /far)
unity_OrthoParams float4 x是正交的相机的宽度,y是正交的相机的高度,z是未使用的,为正交的相机时w为1.0,透视相机时w为0.0
unity_CameraProjection float4x4 摄像机的投影矩阵
unity_CameraInvProjection float4x4 摄像机的投影矩阵的逆矩阵
unity_CameraWorldClipPlanes[6] float4 相机锥平面世界空间方程,按顺序为:左、右、底部、顶部、近、远
光照部分,
名称 类型 数值
_LightColor0(Lighting.cginc中声明) fixed4 光照颜色
_worldspacelightpos0 float4 方向光:(世界空间方向,0)。其他光:(世界空间位置,1)
_LightMatrix0(AutoLight.cginc声明) float4x4 world-to-light矩阵。用于样品cookie 和衰减纹理
unity_4LightPosX0、unity_4LightPosY0 unity_4lightposz0 float4 (仅ForwardBase通道)前四个不重要的点光源的世界空间坐标
unity_4lightatten0 float4 (仅ForwardBase通道)前四个不重要的点光源的衰减系数,顶点光源用的,例:attenuation = 1 / (1 + dot(lightVec, lightVec) * unity_4LightAtten0.x)
unity_lightcolor half4[4] (仅ForwardBase通过)前四个不重要的点光源的颜色数组,计算顶点光源用的
在Shader的光照通道里的延迟着色和延迟光照(在unitydeferredlibrary.cginc):
名称 类型 数值
_LightColor float4 光照颜色
_LightMatrix0 float4x4 world-to-light矩阵。用于样品cookie 和衰减纹理
多光源下,最多8个光源在顶点通道,排序为从最亮的开始
名称 类型 数值
unity_LightColor half4[8] 光照颜色数组
unity_LightPosition float4[8] 视图空间光源的位置。方向光源的坐标是(-方向,0);(位置,1)用于点/点指示灯,点光源,聚光灯的坐标是(位置,1)
unity_LightAtten half4[8] 光源衰减的系数。X是cos(spotAngle/2)或非聚光灯为-1;Y为1/COS(spotangle / 4)或非聚光灯为-1;Z是衰减的二次方;W是正方形光源的范围
unity_SpotDirection float4[8] 视图空间聚光灯的位置;(0,0,1,0)则非聚光灯。