(一)unity自帶的着色器源碼剖析之——————UnityShaderVariables.cginc文件

unityShaderVariables.cginc文件中包含大量的工具宏和函數,如變換操作用的矩陣、與攝像機相關的函數、與光照和陰影相關的函數,以及與霧效果相關的函數等。下面依次分析這些工具函數和宏。

 

一、進行變換操作用的矩陣

1.1 判斷 USING_DIRECTIONAL_LIGHT宏是否定義並分析與立體渲染相關的宏

代碼段如下,從第3行開始,14行結束:

#ifndef UNITY_SHADER_VARIABLES_INCLUDED
#define UNITY_SHADER_VARIABLES_INCLUDED

#include "HLSLSupport.cginc"

#if defined (DIRECTIONAL_COOKIE) || defined (DIRECTIONAL)
#define USING_DIRECTIONAL_LIGHT
#endif
//           是否啓用了單程立體渲染              判斷立體多例化支持宏是否啓用
#if defined(UNITY_SINGLE_PASS_STEREO) || defined(UNITY_STEREO_INSTANCING_ENABLED) || defined(UNITY_STEREO_MULTIVIEW_ENABLED)
#define USING_STEREO_MATRICES
#endif

在上面代碼中,首先根據單程立體渲染(single pass stereo rendering)相關的預處理宏UNITY_SINGLE_PASS_STEREO、立體多例化渲染(stereo instancing rendering)預處理宏UNITY_STEREO_INSTANCING_ENABLED、多視角立體渲染(multi-view stereo rendering)預處理宏UNITY_STEREO_MULTIVIEW_ENABLED的啓用情況決定宏USING_STEREO_MATRICES是否開啓。如果上面三個宏有任意一個是開啓的,那麼宏USING_STEREO_MATRICES即開啓,表示要使用與立體渲染相關的矩陣。

立體多例化渲染的預處理宏UNITY_STEREO_INSTANCING_ENABLED是否啓用,在HLSLSupport.cginc文件中有定義。這個宏根據另外的預處理宏的設置決定啓用與否。立體多例化渲染技術的核心思想是一次向渲染管道上提交兩份待渲染的幾何體數據,減少繪製調用(draw call)的次數,提升渲染性能。

單程立體渲染是一種高效的支持VR效果的方式,用於PC或者PlayStation4平臺上的VR應用。這種技術同時把要顯示在左右眼的圖像打包渲染進一張可渲染紋理中,這也意味着整個場景只需要渲染一次即可。否則就需要左右眼各渲染一次。此技術將大幅度地提升渲染性能。要使用單程立體渲染,選擇Edit | Project Settings | Player選項,在PlayerSetting面板中選擇Other Setting選項選中Virtual Reality Supported複選框,然後選中Single-Pass Stereo Rendering複選框便可。設置完畢後,宏UNITY_SINGLE_PASS_STEREO將會被啓用。

1.2 和立體渲染相關的一系列矩陣 1

下面代碼用於定義一系列與立體渲染相關的矩陣:

#if defined(USING_STEREO_MATRICES)
    #define glstate_matrix_projection unity_StereoMatrixP[unity_StereoEyeIndex]
    #define unity_MatrixV unity_StereoMatrixV[unity_StereoEyeIndex]
    #define unity_MatrixInvV unity_StereoMatrixInvV[unity_StereoEyeIndex]
    #define unity_MatrixVP unity_StereoMatrixVP[unity_StereoEyeIndex]

    #define unity_CameraProjection unity_StereoCameraProjection[unity_StereoEyeIndex]
    #define unity_CameraInvProjection unity_StereoCameraInvProjection[unity_StereoEyeIndex]
    #define unity_WorldToCamera unity_StereoWorldToCamera[unity_StereoEyeIndex]
    #define unity_CameraToWorld unity_StereoCameraToWorld[unity_StereoEyeIndex]
    #define _WorldSpaceCameraPos unity_StereoWorldSpaceCameraPos[unity_StereoEyeIndex]
#endif

在上面的代碼段中,出現了帶有unity_Stereo前綴命名數組變量,如unity_StereoMatrixV等,以及用來索引數組的索引值變量unity_StereoEyeIndex,然後用一個#define把帶有"unity_Stereo"的變量名替換成unity_前綴即可。

1.3 和立體渲染相關的一系列矩陣 2

帶有unity_Stereo前綴的變量和unity_StereoEyeIndex也定義在UnityShaderVariables.cginc文件中,如以下代碼所示。

#if defined(USING_STEREO_MATRICES)
GLOBAL_CBUFFER_START(UnityStereoGlobals)
    float4x4 unity_StereoMatrixP[2];   //每個眼鏡的投影矩陣
    float4x4 unity_StereoMatrixV[2]; //左、右眼的觀察矩陣
    float4x4 unity_StereoMatrixInvV[2];//左、右眼的觀察矩陣的逆矩陣
    float4x4 unity_StereoMatrixVP[2]; //左、右眼的觀察矩陣與投影矩陣的乘積

    float4x4 unity_StereoCameraProjection[2];  //攝像機的投影矩陣
    float4x4 unity_StereoCameraInvProjection[2]; //攝像機的投影矩陣的逆矩陣
    float4x4 unity_StereoWorldToCamera[2];   //從世界空間變換到攝像機觀察空間的矩陣
    float4x4 unity_StereoCameraToWorld[2];  //從攝像機觀察空間變換到世界空間的矩陣

    float3 unity_StereoWorldSpaceCameraPos[2]; //攝像機在世界空間中的座標值
	//進行單程立體渲染時,和普通渲染不同,並不是直接把渲染效果寫入對應屏幕的顏色緩衝區,而是把渲染結果寫入對應於
	//左右眼的兩個圖像(image)中,然後把兩個圖像合併到一張可渲染紋理中再顯示。
	//變量unity_StereoScaleOffset維護了把兩個圖像合併進一張紋理中要用到的平鋪值(tiling)和偏移值(offset)
    float4 unity_StereoScaleOffset[2];
GLOBAL_CBUFFER_END
#endif

#if defined(USING_STEREO_MATRICES) && defined(UNITY_STEREO_MULTIVIEW_ENABLED)
GLOBAL_CBUFFER_START(UnityStereoEyeIndices)
    float4 unity_StereoEyeIndices[2];
GLOBAL_CBUFFER_END
#endif
//如果啓用了多視角立體渲染,unity_StereoEyeIndex的值就是UNITY_VIEWID
//而UNITY_VIEWID的值就是gl_viewID值(HLSLSupport.cginc文件中定義)
#if defined(UNITY_STEREO_MULTIVIEW_ENABLED) && defined(SHADER_STAGE_VERTEX)
//把立體渲染的左右眼索引值變量定義別名爲UNITY_VIEWID
    #define unity_StereoEyeIndex UNITY_VIEWID
    UNITY_DECLARE_MULTIVIEW(2);
//如果啓用了立體多實例化渲染,定義一個靜態的當前使用的眼鏡索引
//此值在編譯期間要明確指定,運行時不可改變
#elif defined(UNITY_STEREO_INSTANCING_ENABLED) || defined(UNITY_STEREO_MULTIVIEW_ENABLED)
    static uint unity_StereoEyeIndex;
//如果啓用的是單程立體渲染,把索引值定義爲int類型,並且是作爲一個着色器常用緩衝區中定義的變量,也即可以由CPU在運行期傳遞
//具體的數值去改變當前使用的眼睛索引
#elif defined(UNITY_SINGLE_PASS_STEREO)
    GLOBAL_CBUFFER_START(UnityStereoEyeIndex)
        int unity_StereoEyeIndex;
    GLOBAL_CBUFFER_END
#endif

依據不同的編譯條件,unity_StereoEyeIndex的定義方式也有所不同,如上面代碼所示。此變量表徵了當時使用的左右眼索引。

 

1.4 UNITY_DECLARE_MULTIVIEW宏的定義

代碼中的UNITY_DECLARE_MULTIVIEW在HLSLSupport.cginc文件中定義,展開如下。

第262行:

#define UNITY_DECLARE_MULTIVIEW(number_of_views) GLOBAL_CBUFFER_START(OVR_multiview) uint gl_ViewID; uint numViews_##number_of_views; GLOBAL_CBUFFER_END

1.5 一系列用來進行變換操作的矩陣

在前面代碼段中,如果啓用了unity_MatrixInV等一系列變量,就相當於使用了unity_StereoMatrixInvV[unity_StereoEyeIndex]等變量;如果沒有啓用,那又是什麼呢,代碼如下所示:

從29行開始,40行結束:

#define UNITY_MATRIX_P glstate_matrix_projection
#define UNITY_MATRIX_V unity_MatrixV
#define UNITY_MATRIX_I_V unity_MatrixInvV
#define UNITY_MATRIX_VP unity_MatrixVP
#define UNITY_MATRIX_M unity_ObjectToWorld

#define UNITY_LIGHTMODEL_AMBIENT (glstate_lightmodel_ambient * 2)

1.6 每一幀由客戶端引擎傳遞進來的逐幀數據

如果沒有啓用,在HLSL/Cg語言中,unity_MatrixV等變量就直接定義爲float4X4 類型的變量,如以下代碼所示:

從第214行開始,231行結束:


CBUFFER_START(UnityPerFrame)

    fixed4 glstate_lightmodel_ambient;
    fixed4 unity_AmbientSky;
    fixed4 unity_AmbientEquator;
    fixed4 unity_AmbientGround;
    fixed4 unity_IndirectSpecColor;
	//如果沒有使用立體渲染矩陣,unity_MatrixV等矩陣就是一個float4x4 類型的矩陣
#if !defined(USING_STEREO_MATRICES)
    float4x4 glstate_matrix_projection;
    float4x4 unity_MatrixV;         //當前攝像機所對應的觀察矩陣(view matrix)
    float4x4 unity_MatrixInvV;
    float4x4 unity_MatrixVP;
    int unity_StereoEyeIndex;
#endif

    fixed4 unity_ShadowColor;
CBUFFER_END

1.7 GLSL中各種變換操作用的矩陣

如果使用GLSL,那麼在GLSLsupport.glslinc文件中定義爲mat4類型的uniform變量,如以下代碼所示:

從第15行開始,20行結束:

uniform mat4 unity_ObjectToWorld;
uniform mat4 unity_WorldToObject;
uniform mat4 unity_MatrixVP;
uniform mat4 unity_MatrixV;
uniform mat4 unity_MatrixInvV;
uniform mat4 glstate_matrix_projection;

在編碼實踐中,通常會單獨使用UNITY_MATRIX_V的單獨行來進行操作,如UNITY_MATRIX_V[0]等操作方式。UNITY_MATRIX_V[0]表示當前攝像機在世界座標系下的朝右(right)方向向量,UNITY_MATRIX_V[1]表示在世界座標系下的朝上(up)方向向量,UNITY_MATRIX_V[2]則表示在世界座標系下的朝前方向向量。

二、和攝像機相關的常量緩衝區

2.1 常量緩衝區 UnityPerCamera的定義

從45行開始,第85行結束:

//Unity3D內建的,用來傳遞給每個攝像機的參數組
//這些參數由引擎從C#層代碼傳遞給着色器

CBUFFER_START(UnityPerCamera)
    // Time (t = time since current level load) values from Unity
	//從載入當前的scene開始算起流逝的時間值,單位是s。其x、y、z、w分量分別對應爲1/20流逝時間值、流逝時間值、2倍流逝時間值、三倍流逝時間值
    float4 _Time; // (t/20, t, t*2, t*3)
    //_Time值的正弦值,其x、y、z、w分別對應於1/8的當前流逝時間值的正弦值、1/4的當前流逝時間值的正弦值、1/2的當前流逝時間值的正弦值、當前流逝時間值的正弦值
    float4 _SinTime; // sin(t/8), sin(t/4), sin(t/2), sin(t)
	 //_Time值的餘弦值,其x、y、z、w分別對應於1/8的當前流逝時間值的餘弦值、1/4的當前流逝時間值的餘弦值、1/2的當前流逝時間值的餘弦值、當前流逝時間值的餘弦值
    float4 _CosTime; // cos(t/8), cos(t/4), cos(t/2), cos(t)
	//本幀到上一幀過去的時間間隔
    float4 unity_DeltaTime; // dt, 1/dt, smoothdt, 1/smoothdt
	//如果沒有定義開啓單線程立體渲染,沒有開啓立體多實例化渲染,就由引擎C#層代碼傳遞一個表徵當前攝像機在世界空間中的座標值
#if !defined(USING_STEREO_MATRICES)
    float3 _WorldSpaceCameraPos;
#endif

    // x = 1 or -1 (-1 if projection is flipped)
    // y = near plane
    // z = far plane
    // w = 1/far plane
	//投影矩陣相關的參數,x爲1或者-1,y爲近截平面值,z爲遠截平面值,w爲遠截平面值的倒數
    float4 _ProjectionParams;

    // x = width
    // y = height
    // z = 1 + 1.0/width
    // w = 1 + 1.0/height
	//視口相關的參數,x爲視口寬度,y爲視口高度,z爲1加上視口寬度的倒數,w爲1加上視口高度的倒數
    float4 _ScreenParams;

    // Values used to linearize the Z buffer (http://www.humus.name/temp/Linearize%20depth.txt)
    // x = 1-far/near
    // y = far/near
    // z = x/far
    // w = y/far
    // or in case of a reversed depth buffer (UNITY_REVERSED_Z is 1)
    // x = -1+far/near
    // y = 1
    // z = x/far
    // w = 1/far
	//用來線性化Z buffer
	//x分量爲1減去視截體遠截面值與視椎近截面值的商,y分量爲視截體遠截面值與視椎近截面值的商,z分量爲x分量除以視截體
	//遠截面值,w分量爲y分量除以視截體遠截面值
    float4 _ZBufferParams;

    // x = orthographic camera's width
    // y = orthographic camera's height
    // z = unused
    // w = 1.0 if camera is ortho, 0.0 if perspective

	//x分量爲正交投影攝像機的寬度,y分量爲正交投影攝像機的高度
	//z分量未使用,w分量當攝像機爲正交投影時爲1,透視投影爲0
    float4 unity_OrthoParams;
#if defined(STEREO_CUBEMAP_RENDER_ON)
    //x-component is the half stereo separation value, which a positive for right eye and negative for left eye. The y,z,w components are unused.
    float4 unity_HalfStereoSeparation;
#endif
CBUFFER_END

2.2常量緩衝區UnityPerCameraRare的定義

通過以下代碼定義常量緩衝區UnityPerCameraRare。

從第88行開始,100行結束:

CBUFFER_START(UnityPerCameraRare)
    //當前攝像機視截體(view frustum)的6個截平面的平面表達式。這些平面表達式在世界座標系下描述。
	//每個平面表達式用方程ax+by+cz+d=0表達。float4中的分量x、y、z、w依次存儲了係數a、b、z、d。
	//6個平面依次是左、右、下、上、近、遠裁剪平面
    float4 unity_CameraWorldClipPlanes[6];

    //如果不使用立體渲染,各種矩陣變量就是一個單變量而不是兩個變量的數組
#if !defined(USING_STEREO_MATRICES)
    // Projection matrices of the camera. Note that this might be different from projection matrix
    // that is set right now, e.g. while rendering shadows the matrices below are still the projection
    // of original camera.

    //當前攝像機的投影矩陣
    float4x4 unity_CameraProjection;
	//當前攝像機的投影矩陣的逆矩陣
    float4x4 unity_CameraInvProjection;
	//當前攝像機的觀察矩陣
    float4x4 unity_WorldToCamera;
	//當前攝像機的觀察矩陣的逆矩陣
    float4x4 unity_CameraToWorld;
#endif
CBUFFER_END

三、與光照相關的工具函數和內置光源

3.1 變量_WorldSpaceLightPos0的定義

如下,從第106行開始,112行結束:

CBUFFER_START(UnityLighting)
    //如果定義了有向平行光
    #ifdef USING_DIRECTIONAL_LIGHT
	//分量x、y、z存儲的是有向平行光的方向向量
    half4 _WorldSpaceLightPos0;
    #else   
	//如果不是有向平行光,那麼分量x、y、z存儲的是光源在世界空間中的位置座標
    float4 _WorldSpaceLightPos0;
    #endif

UnityCG.cginc和UnityCG.glslinc文件中的定義UnityWorldSpaceLightDir函數就使用了_WorldSpaceLightPos0變量,計算出某點到光源的連線方向向量。

3.2 4個非重要點光源的位置、衰減值和照射範圍

從第114行開始,123行結束:

  //x、y、z分量爲光源的位置,w分量爲光源照射範圍的倒數   
    float4 _LightPositionRange; // xyz = pos, w = 1/range
    float4 _LightProjectionParams; // for point light projection: x = zfar / (znear - zfar), y = (znear * zfar) / (znear - zfar), z=shadow bias, w=shadow scale bias

	//4個光源的x、y、z座標,注意unity_4LightPosX0中的4個分量分別存儲了4個光源的x座標,unity_4LightPosY0中的4個分量分別存儲
	//了4個光源的y座標,其餘類推
    float4 unity_4LightPosX0;
    float4 unity_4LightPosY0;
    float4 unity_4LightPosZ0;
    half4 unity_4LightAtten0;    //4個光源的衰減值

上面代碼定義的4個光源,是等級爲非重要光源的點光源。這4個光源僅用在前向渲染路徑的base pass中。

3.3 8個光源的顏色、位置、衰減值和照射方向

從124行開始,130行結束:

//8個光源的顏色
    half4 unity_LightColor[8];

	//有向光的視圖空間頂點光源位置(position,1)或者(-direction,0)
	//在光源空間中用來在頂點着色器中執行頂點光照計算的光源位置點。如果光源是有向平行光,那麼變量中的x、y、z分量存儲着光源
	//的光照方向的反方向,w分量爲0;如果光源是非有向平行光源,那麼變量中的x、y、z分量存儲着光源的位置座標,w分量爲1

    float4 unity_LightPosition[8]; // view-space vertex light positions (position,1), or (-direction,0) for directional lights.
    // x = cos(spotAngle/2) or -1 for non-spot
    // y = 1/cos(spotAngle/4) or 1 for non-spot
    // z = quadratic attenuation
    // w = range*range

	//對於非點光源x = cos(spotAngle/2)或1
	//對於非點光源y = 1/cos(spotAngle/4)或1
	//z = quadratic attenuation
	//w = range*range
    half4 unity_LightAtten[8];
	//8個光源的正前照射方向,這些方向向量基於觀察空間,如果這些光源不是聚光燈光源,都爲(0,0,1,0)
    float4 unity_SpotDirection[8]; // view-space spot light directions, or (0,0,1,0) for non-spot

在上述代碼段中,變量unity_LightAtten描述了光源的衰減信息:如果光源是聚光燈光源,每一個數組元素的x分量存儲着聚光燈1/2張角值的餘弦值;如果不是,那麼x分量值爲-1。z分量存儲着衰減值方程式中的二次項係數。w分量存儲着光源照射範圍的距離值的平方。

據unity3D技術支持工程師介紹,因爲一些原因,在unity_LightAtten變量的原有代碼註釋中,對於y分量的描述其實是錯誤的。y分量的正確值應該是:聚光燈1/4張角的餘弦值減去其1/2張角的餘弦值。如果該差值不爲0,則y爲該差值的倒數,否則爲1.

3.4 球諧光照使用到的參數

從第133行開始,139行結束:

 // SH lighting environment
    half4 unity_SHAr;
    half4 unity_SHAg;
    half4 unity_SHAb;
    half4 unity_SHBr;
    half4 unity_SHBg;
    half4 unity_SHBb;
    half4 unity_SHC;

3.5 和光照探針相關的參數

從第142行開始,144行結束:

    // part of Light because it can be used outside of shadow distance
    fixed4 unity_OcclusionMaskSelector;
    fixed4 unity_ProbesOcclusion;
CBUFFER_END

四、與陰影相關的着色器常量緩衝區

UnityShadows着色器常量緩衝區

從第153行開始,162行結束:

CBUFFER_START(UnityShadows)
    //用於構建層疊式陰影貼圖時子視截體用到的包圍球
    float4 unity_ShadowSplitSpheres[4];
    //unity_ShadowSplitSpheres中4個包圍球半徑的平方
    float4 unity_ShadowSplitSqRadii;
    float4 unity_LightShadowBias;
    float4 _LightSplitsNear;
    float4 _LightSplitsFar;
	//把某個座標點從世界空間變換到陰影貼圖空間,如果使用層疊式陰影貼圖
	//把數組各元素就表徵4個陰影貼圖各自所對應的陰影貼圖空間
    float4x4 unity_WorldToShadow[4];
    half4 _LightShadowData;
    float4 unity_ShadowFadeCenterAndType;
CBUFFER_END

unity_ShadowSplitSpheres數組用於構建層疊式陰影貼圖(cascaded shadow map,CSM)。該數組中的4個元素存儲了把當前視截體分割成4個子視截體後,這些子視截體的包圍球(bounding sphere)。每個元素中x、y、z、w分量存儲包圍球的球心座標和半徑。

unity_ShadowSplitSqRadii中的4個分量依次定義unity_ShadowSplitSheres數組對應的4個包圍球半徑的平方。

unity_LightShadowBias的x分量爲產生陰影的光源的光源偏移值乘以一個係數。這個光源偏移值對應於Light面板中的Bias屬性。如果聚光燈光源,所乘的係數爲1;如果是有向平行光源,所乘係數爲投影矩陣的第三行第三列的值的相反數。當光源是聚光燈光源時,y分量是0;當光源是有向平行光源時,爲1。z分量爲解決陰影滲漏問題時,沿着物體表面法線移動的偏移值。w分量爲0。

_LightSplitsNear對應於Shadows面板中的cascade split屬性裏面,當把視截體分割成最多4個視截體時,每個子視截體的近截平面的z值。

unity_WorldToShadow數組中的每一個元素對應於層疊式貼圖中每一個子視截體所對應的陰影貼圖,存儲了從世界座標變換到陰影貼圖空間中的變換座標。

_LightShadowData中x分量表示陰影的強度,即陰影有多黑,1表示全黑,0表示完全透明不黑;y分量目前暫未被使用;當z分量1除以需要渲染的陰影時,表示陰影離當前攝像機的最遠距離值(shadow far distance)。w分量表示陰影攝像機的最近距離值(shadow near distance)。

五、與逐幀繪製調用相關的着色器常量緩衝區

Unity3D引擎預定義了和逐幀繪製調用相關的着色器常量UnityPerDraw。從166行開始,171行結束:

CBUFFER_START(UnityPerDraw)
    //把頂點從局部空間變換到世界空間的變換矩陣
    float4x4 unity_ObjectToWorld;
    //把頂點從世界空間變換到局部空間的變換矩陣
    float4x4 unity_WorldToObject;
    float4 unity_LODFade; // x is the fade value ranging within [0,1]. y is x quantized into 16 levels
	//該變量的w分量通常爲1,當縮放變量值爲負數時,常被引擎賦值爲-1。
    float4 unity_WorldTransformParams; // w is usually 1.0, or -1.0 for odd-negative scale transforms
CBUFFER_END

六、與霧效果相關的常量緩衝區

Unity引擎預定了和霧效果渲染相關的着色器常量UnityFog,從236行開始,243行結束:

CBUFFER_START(UnityFog)
     //霧的顏色
    fixed4 unity_FogColor;
    // x = density / sqrt(ln(2)), useful for Exp2 mode 用於霧化因子指數平方衰減
    // y = density / ln(2), useful for Exp mode 用於霧化因子指數衰減
    // z = -1/(end-start), useful for Linear mode 用於霧化因子線性衰減
    // w = end/(end-start), useful for Linear mode 用於霧化因子線性衰減
    float4 unity_FogParams;
CBUFFER_END

霧化效果是一種可添加到最終渲染圖像的簡單的大氣效果(atmosphere effect)。霧化效果可以提供室外場景的真實度;霧化效果隨着距離觀察者的距離變遠而增加,可以幫助觀察者確定物體的遠近;靠近視截體遠平面的物體就會因爲濃厚的霧效果變得不可見,這樣可以避免原本在視截體之外的不可見物體,因爲進入視截體就突然變得可見的現象;霧化效果一般由硬件實現,所以很高效。

七、與光照貼圖相關的常量緩衝區

7.1 unity_Lightmap變量的聲明

從250行開始,252行結束:

// Lightmaps

// Main lightmap
//聲明瞭主光照貼圖,該貼圖記錄了直接照明下的光照信息
UNITY_DECLARE_TEX2D_HALF(unity_Lightmap);
//聲明瞭間接照明所產生的光照信息,因爲unity_LightmapInd和unity_Lightmap搭配使用所以不用另外專門聲明採樣器
// Directional lightmap (always used with unity_Lightmap, so can share sampler)
UNITY_DECLARE_TEX2D_NOSAMPLER_HALF(unity_LightmapInd);

7.2 UNITY_DECLARE_TEX2D_NOSAMPLER宏的定義

UNITY_DECLARE_TEX2D_NOSAMPLER宏在HLSLSupport.cginc文件中定義,依據不同的目標平臺,它的定義也不同:

 #if defined(SHADER_API_D3D11) || defined(SHADER_API_XBOXONE) || defined(UNITY_COMPILER_HLSLCC) || defined(SHADER_API_PSSL) || (defined(SHADER_TARGET_SURFACE_ANALYSIS) && !defined(SHADER_TARGET_SURFACE_ANALYSIS_MOJOSHADER))

    #define UNITY_DECLARE_TEX2D_NOSAMPLER(tex) Texture2D tex

#else
     #define UNITY_DECLARE_TEX2D_NOSAMPLER(tex) sampler2D tex

7.3 unity_ShadowMask變量的定義

從254行開始,261行結束:

UNITY_DECLARE_TEX2D(unity_ShadowMask);

使用Unity_DECLARE_TEX2D宏直接定義一個名爲unity_ShadowMask的紋理貼圖,定義一個名爲samplerunity_ShadowMask的samplerState。

7.4 和全局照明光照貼圖相關的變量

從264行開始,271行結束:

// Dynamic GI lightmap
UNITY_DECLARE_TEX2D(unity_DynamicLightmap);
UNITY_DECLARE_TEX2D_NOSAMPLER(unity_DynamicDirectionality);
UNITY_DECLARE_TEX2D_NOSAMPLER(unity_DynamicNormal);

CBUFFER_START(UnityLightmaps)
    //對應於靜態光照貼圖變量unity_Lightmap,用於tiling和offset操作。
    float4 unity_LightmapST;
    //對應於動態(實時)光照貼圖變量unity_DynamicLightmap,用於tiling和offset操作
    float4 unity_DynamicLightmapST;
CBUFFER_END

7.5 與反射探針相關的着色器變量

從277行開始,290行結束:

// Reflection Probes

UNITY_DECLARE_TEXCUBE(unity_SpecCube0);
UNITY_DECLARE_TEXCUBE_NOSAMPLER(unity_SpecCube1);

CBUFFER_START(UnityReflectionProbes)
    //反射探針的作用區域立方體是一個和世界座標系座標軸軸對齊的包圍盒
	// unity_SpecCube0_BoxMax的x、y、z分量存儲了該包圍盒在x、y、z軸方向上的最小邊界值
	//它的值由反射探針的Box Size屬性和Box Offset屬性計算而來
    float4 unity_SpecCube0_BoxMax;
    // unity_SpecCube0_BoxMax的x、y、z分量存儲了該包圍盒在x、y、z軸方向上的最小邊界值
    float4 unity_SpecCube0_BoxMin;
	//對應於Reflection組件中的探針位置,它由Transform組件的Position屬性和Box Offset屬性計算而來
    float4 unity_SpecCube0_ProbePosition;
	//反射探針使用的立方體貼圖中包含高動態範圍顏色,它允許它包含大於1的亮度值,在渲染時要將HDR值轉爲RGB值
    half4  unity_SpecCube0_HDR;

    float4 unity_SpecCube1_BoxMax;
    float4 unity_SpecCube1_BoxMin;
    float4 unity_SpecCube1_ProbePosition;
    half4  unity_SpecCube1_HDR;
CBUFFER_END

UNITY_DECLARE_TEXCUBE宏在HLSLSupport.cginc文件中定義,用來聲明一個立方體貼圖變量。並且如果當前是運行在Direct3D 11或者XBoxOne平臺上,此宏還對應立方體貼圖變量聲明一個採樣器變量。而UNITY_DECLARE_TEXCUBE_NOSAMPLER宏則是一個不聲明採樣器變量的版本。

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章