預定義shader預處理宏:
Target platform:
SHADER_API_OPENGL - desktop OpenGL SHADER_API_D3D9 - Direct3D 9 SHADER_API_XBOX360 - Xbox 360 SHADER_API_PS3 - PlayStation 3 SHADER_API_D3D11 - desktop Direct3D 11 SHADER_API_GLES - OpenGL ES 2.0 (desktop or mobile), use presence of SHADER_API_MOBILE to determine. SHADER_API_FLASH - Flash Stage3D SHADER_API_D3D11_9X - Direct3D 11 target for Windows RT
Surface shader pass indicators:
UNITY_PASS_FORWARDBASE - 前向渲染的base pass(主方向光、lightmaps、SH) UNITY_PASS_FORWARDADD - 前向渲染的add pass(沒盞燈一個pass) UNITY_PASS_PREPASSBASE - 延遲渲染base pass(renders normals & specular exponent). UNITY_PASS_PREPASSFINAL - 延遲渲染final pass (applies lighting & textures). UNITY_PASS_SHADOWCASTER - 陰影投射渲染pass. UNITY_PASS_SHADOWCOLLECTOR - 陰影手機pass for directional light shadows.
內置全局狀態變量:
內置的矩陣:
UNITY_MATRIX_MVP float4x4 Current model * view * projection matrix. UNITY_MATRIX_MV float4x4 Current model * view matrix. UNITY_MATRIX_V float4x4 Current view matrix. UNITY_MATRIX_P float4x4 Current projection matrix. UNITY_MATRIX_VP float4x4 Current view * projection matrix. UNITY_MATRIX_T_MV float4x4 Transpose of model * view matrix. UNITY_MATRIX_IT_MV float4x4 Inverse transpose of model * view matrix. UNITY_MATRIX_TEXTURE0 to UNITY_MATRIX_TEXTURE3 float4x4 Texture transformation matrices. _Object2World float4x4 Current model matrix. _World2Object float4x4 Inverse of current world matrix. _WorldSpaceCameraPos float3 World space position of the camera. unity_Scale float4 xyz components unused; w contains scale for uniformly scaled objects.
內置的向量:
UNITY_LIGHTMODEL_AMBIENT: Current ambient color.
光照相關的:
_ModelLightColor float4 Material’s Main * Light color _SpecularLightColor float4 Material’s Specular * Light color _ObjectSpaceLightPos float4 Light’s position in object space. w component is 0 for directional lights, 1 for other lights _Light2World float4x4 Light to World space matrix _World2Light float4x4 World to Light space matrix _Object2Light float4x4 Object to Light space matrix
變量:
_Time float4 Time (t/20, t, t*2, t*3), use to animate things inside the shaders. _SinTime float4 Sine of time: (t/8, t/4, t/2, t). _CosTime float4 Cosine of time: (t/8, t/4, t/2, t). unity_DeltaTime float4 Delta time: (dt, 1/dt, smoothDt, 1/smoothDt). _ProjectionParams float4 x is 1.0 (or –1.0 if currently rendering with a flipped projection matrix), y is the camera’s near plane, z is the camera’s far plane and w is 1/FarPlane. _ScreenParams float4 x is the current render target width in pixels, y is the current render target height in pixels, z is 1.0 + 1.0/width and w is 1.0 + 1.0/height.
內置光照參數:
對於不同的Rendering Path和Pass Tag,可以使用的光照參數是不一樣的。(當然所有參數你都可以在shader中使用,但並不能保證其一定會存儲有效的值)。
Forward rendering(ForwardBase和PorwardAdd標記的pass)支持的變量:
LightColor0 (declared in Lighting.cginc) | fixed4 |Light color. | |WorldSpaceLightPos0 float4 Directional lights: (world space direction, 0). Other lights: (world space position, 1). _LightMatrix0 (declared in AutoLight.cginc) float4x4 World-to-light matrix. Used to sample cookie & attenuation textures. unity_4LightPosX0, unity_4LightPosY0, unity_4LightPosZ0 float4 (ForwardBase pass only) world space positions of first four non-important point lights. unity_4LightAtten0 float4 (ForwardBase pass only) attenuation factors of first four non-important point lights. unity_LightColor half4[4] (ForwardBase pass only) colors of of first four non-important point lights.
說明:
(1)_LightColor0在ForwardBass里面表示:主光,一定是Pixel(Important)、Directional光源,沒有的話則改值不可用;
(2)_LightColor0在ForwardAdd里面表示:當前執行的ForwardAdd的pixel光;
_WorldSpaceLightPos0的意義和_LightColor類似,也是在Base里表示主光,Add里表示像素光。
(3)unity_LightColor是距離物體最近的4個point光,也就是說同一個場景中每個物體的這4個光不一樣,注意這4個point光的選擇非常有意思;
(a)當shader中沒有ForwardAdd Pass的時候,unity_LightColor記錄了4盞vertex point光源,無視pixel光;
(b)當shader中包含ForwardAdd Pass的時候,unity_LightColor記錄了4盞point光源,pixel比vertex優先。
(4)如果場景中有多個pixel光,則對每一個物體,所有的非主光的pixel光都會執行一遍ForwardAdd Pass,按照強度大小、平行光優先的順序來執行;
(5)不要在ForwardAdd Pass里面使用unity4LightPosX/Y/Z等數據,因為它們就是給ForwardBase Pass使用的,而且如果其中有pixel光,它們本身就會對ForwardAdd執行一遍;
(6)可以使用Shade4PointLights函數在ForwardBase中計算Vertex光源的照明。
Deferred shading:
LightColor | float4 | Light color. | |LightMatrix0 float4x4 World-to-light matrix. Used to sample cookie & attenuation textures.
Vertex-lit rendering(Vertex標記的pass):
頂點光照可以使用最多8盞光源,這些光源按照亮度排序,按順序存儲在一下這些數據結構中,如果光源數量少於8,那么多出來的都將黑色:
unity_LightColor half4[8] Light colors. unity_LightPosition float4[8] View-space light positions. (-direction,0) for directional lights; (position,1) for point/spot lights. unity_LightAtten half4[8] Light attenuation factors. x is cos(spotAngle/2) or –1 for non-spot lights; y is 1/cos(spotAngle/4) or 1 for non-spot lights; z is quadratic attenuation; w is squared light range. unity_SpotDirection float4[8] View-space spot light positions; (0,0,1,0) for non-spot lights.
說明:
(1)_LightColor0表示unity_LightColor[0]
(2)unity_LightPosition是MV空間中的位置
(3)逐頂點光照函數float4 ShadeVertexLights(float4 vertex, float3 normal)
注意:
(1)_LightColor0變量不代表某個具體含義,它在不同的Render Path和Pass里面是有不同的意義的
(2)ShaderLab里面的內置變量是不會及時清理的,這是Unity處於性能方面的考慮,因為在CPU和GPU之間頻繁傳遞數據是很耗資源的
Fog和Ambient環境光信息:
UNITY_LIGHTMODEL_AMBIENT fixed4 Ambient lighting color (Equator ambient in three-color lighting case). unity_AmbientSky fixed4 Sky ambient lighting color in three-color lighting case. unity_AmbientGround fixed4 Ground ambient lighting color in three-color lighting case. unity_FogColor fixed4 Fog color. unity_FogParams float4 Parameters for fog calculation: (density / sqrt(ln(2)), density / ln(2), –1/(end-start), end/(end-start)). x is useful for Exp2 fog mode, y for Exp mode, z and w for Linear mode.
使用multi_compile編譯Shader的多個版本:
有時候我們希望保留一個shader的大多數實現,而只是做一些細節的修改,此時我們就可以通過該方式來生成shader的多個版本,然后在代碼中控制使用哪個版本。
命令:
#pragma multi_compile FANCY_STUFF_OFF FANCY_STUFF_ON
控制:
Material.EnableKeyword(keyword: string)/DisableKeyword(keyword: string)
Shader.EnableKeyword(keyword: string)/DisableKeyword(keyword: string)
在shader中根據定義好的關鍵字處理具體顯示方案:
float4 frag(vertOut i):COLOR { float4 c = float4(0, 0, 0, 0); #ifdef MY_multi_1 c = float4(0, 1, 0, 0); #endif #ifdef MY_multi_2 c = float4(0, 0, 1, 0); #endif return c; }
注意不要在shader中大量使用此命令,因為關鍵字的個數是有上限的,而多條multi_complie會交叉匹配產生很多種結果。
GLSL shader編程
在Shader中,除了Cg/HLSL以外,GLSL(OpenGL Shading Languate)也可以直接使用。
一般不建議使用GLSL,除非你確定你的目標平台只有Max OS X或兼容OpenGL ES 2.0的移動設備。
Unity默認都會將Cg/HLSL交叉編譯出優化過得GLSL,以此來支持多平台。在desktop平台下可以通過打開#pragma glsl選項來支持。
平台特性相關的渲染差異:
Unity封裝了大多數的平台問題,但有些時候還是需要自己處理一下的。
紋理坐標:
Direct3D里面是左上角為原點;
OpenGL和OpenGL ES是左下角為原點。
多數時候都ok,除了在Render To Texture時。但是在RTT時,Unity對於D3D平台會自動將渲染的貼圖上下翻轉一下,以此隱藏了各平台的差異。
D3D平台下,有一種情況不需要Unity自動翻轉渲染貼圖,那就是使用Image Effects和Anti-Aliasing時,因為直接渲染到Screen了,
需要手動處理的情況:但同時使用screen texture和RenderTexture時,有可能會得到不一致的坐標朝向,此時就需要在shader里面通過代碼處理了:
// On D3D when AA is used, the main texture and scene depth texture // will come out in different vertical orientations. // So flip sampling of the texture when that is the case (main texture // texel size will have negative Y). #if UNITY_UV_STARTS_AT_TOP if (_MainTex_TexelSize.y < 0) uv.y = 1-uv.y; #endif
AlphaTest:
在OpenGL ES 2.0和Direct3D 11中,沒有alpha testing的固定函數。所以在編寫programmable shader時,建議在pixel shader中使用CG/HLSL clip()函數來替代。
D3D 11 shader編譯器比較挑剔:
D3D 9和OpenGL使用NVIDIA的Cg來編譯shader,但D3D 11使用微軟的HLSL來編譯,此時就會產生一些差異化。
OpenGL ES 2.0只支持部分GLSL原生的東西,所以Unity實現了一些內置的參數,讓其以OpenGL的方式工作,但是也有一些參數是沒有的。
_WorldSpaceLightPos0:
在UnityCG.cginc里,提供了獲取世界空間下的光照方向的函數
// Computes world space light direction inline float3 WorldSpaceLightDir( in float4 v ) { float3 worldPos = mul(_Object2World, v).xyz; #ifndef USING_LIGHT_MULTI_COMPILE return _WorldSpaceLightPos0.xyz - worldPos * _WorldSpaceLightPos0.w; #else #ifndef USING_DIRECTIONAL_LIGHT return _WorldSpaceLightPos0.xyz - worldPos; #else return _WorldSpaceLightPos0.xyz; #endif #endif }
其中,由於平行光的方向不隨頂點位置發生變化,因此直接使用_WorldSpaceLightPos0.xyz即可,此時里面存儲的其實就是平行光的方向,而非位置。同時,
_WorldSpaceLightPos0.w可以表明該光源的類型,如果為0表示是平行光,為1表示是點光源或者聚光燈光源。
TANGENT_SPACE_ROTATION:
創建一個正切空間的旋轉矩陣,TANGENT_SPACE_ROTATION由下面兩行組成
等同於如下兩行代碼:
float3 binormal = cross( v.normal, v.tangent.xyz ) * v.tangent.w;
float3x3 rotation = float3x3( v.tangent.xyz, binormal, v.normal );
CSDN博客:http://blog.csdn.net/candycat1992/article/details/47284289