短視訊系統,實現介面陰影效果

zhibo系統開發發表於2021-12-06

短視訊系統,實現介面陰影效果

為了便於實現,方便理解實現邏輯,本案例在Lambert光照模型(逐畫素光照渲染)基礎上進行改進。

原始碼

Shader "Chapter6/LambertFrag"
{
    Properties
    {
        _MainCol ("Main Color", Color) = (1,1,1,1)
    }
    SubShader
    {
        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"
            #include "UnityLightingCommon.cginc"
            struct v2f
            {
                float4 pos : SV_POSITION;
                float3 normal : TEXCOORD0;//這裡不能是NORMAL,會跟appdata_base衝突
                float4 vertex : TEXCOORD1;
            };
            fixed4 _MainCol;
            v2f vert (appdata_base v)
            {
                v2f o;
                o.pos = UnityObjectToClipPos(v.vertex);
                o.normal = v.normal;
                o.vertex = v.vertex;
                return o;
            }
            fixed4 frag (v2f i) : SV_Target
            {
                //法線向量
                float3 n = UnityObjectToWorldNormal(i.normal);
                //n = normalize(n);
                //燈光方向向量
                fixed3 l = normalize(_WorldSpaceLightPos0.xyz);
                //計算漫反射
                fixed ndotl = dot(n,l);
                fixed4 color = _LightColor0 * _MainCol *saturate(ndotl);
                return color;
            }
            ENDCG
        }
    }
}


附上程式碼:

Shader "Chapter6/LambertFrag"
{
    Properties
    {
        _MainColor ("Main Color", Color) = (1,1,1,1)
    }
    SubShader
    {
        Pass
        {
            Tags { "LightMode"="ForwardBase" }//第一步:新增標籤,計算主要燈光模式
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            //第二步:呼叫多重編譯指令,為當前pass中渲染的每個燈光編譯出不同變體
            #pragma multi_compile_fwdbase
            #include "UnityCG.cginc"
            //第三步:引入相關檔案,便於使用內建變數和預定義函式
            #include "Lighting.cginc"
            #include "AutoLight.cginc"
            struct v2f
            {
                float4 pos : SV_POSITION;
                float3 normal : TEXCOORD0;//這裡不能是NORMAL,會跟appdata_base衝突
                float4 vertex: TEXCOORD1;
                SHADOW_COORDS(2)//第四步:使用預定義巨集儲存陰影貼圖座標,2表示texcoord後的序號,前面兩套已經被使用了
            };
            fixed4 _MainColor;
            v2f vert (appdata_base v)
            {
                v2f o;
                o.pos = UnityObjectToClipPos(v.vertex);
                o.normal = v.normal;
                o.vertex = v.vertex;
                //第五步:TRANSFER_SHADOW
                //1:如果當前平臺可以使用螢幕空間的陰影對映技術(SCREENSPACE_SHADOWS),則會呼叫內建的ComputeScreenPos函式計算螢幕空間的uv座標,儲存在_ShadowCoord,後續直接用螢幕uv座標取樣螢幕陰影貼圖;
                //2:如果不支援則會使用傳統的陰影對映技術,TRANSFER_SHADOW會把頂點座標從模型空間轉換到光源空間後儲存到_ShadowCoord中,後續根據座標資訊對ShadowMap取樣。
                TRANSFER_SHADOW(o)
                //我的理解是,如果使用螢幕空間的陰影對映技術,會計算物體在光照下陰影對應的螢幕空間的uv座標
                return o;
            }
            fixed4 frag (v2f i) : SV_Target
            {
                //法線向量
                float3 n = UnityObjectToWorldNormal(i.normal);
                //n = normalize(n);
                //燈光方向向量
                //fixed3 l = normalize(_WorldSpaceLightPos0.xyz);//意思是第一個平行光的方向
                float3 l = WorldSpaceLightDir(i.vertex);//第六步:會根據不同型別的燈光計算燈光方向,沒有歸一化
                l = normalize(l);
                float4 worldPos = mul(unity_ObjectToWorld,i.vertex);//第七步:獲取世界空間頂點座標
                //計算漫反射Lambert光照
                fixed ndotl = dot(n,l);
                fixed4 color = _LightColor0 * _MainColor *saturate(ndotl);
                //第八步:加上4個點光源的光照
                //Shade4PointLights: 從4個點光源計算漫反射照明,並以特殊方式打包資料。
                //unity_4LightPosX0,unity_4LightPosY0,unity_4LightPosZ0,4個座標的向量資料
                color.rgb += Shade4PointLights(
                unity_4LightPosX0,unity_4LightPosY0,unity_4LightPosZ0,
                unity_LightColor[0].rgb,unity_LightColor[1].rgb,
                unity_LightColor[2].rgb,unity_LightColor[3].rgb,
                unity_4LightAtten0,worldPos.rgb,n) * _MainColor;
                //第九步:加上環境光照
                color += unity_AmbientSky;
                //第十步:使用巨集定義計算陰影係數
                //用於計算光照衰減係數。引數一為返回值(光照衰減係數),引數二用於陰影計算,引數三是世界座標
                UNITY_LIGHT_ATTENUATION(shadowmask,i,worldPos.rgb)
                //第十一步:陰影合成
                color.rgb *= shadowmask;
                return color;
            }
            ENDCG
        }
    }
    FallBack "Diffuse"//第十二步:這裡的Fallback並不是備胎,而是必要的儲存投影的方式 https://blog.csdn.net/shenmifangke/article/details/50466798
}


以上就是短視訊系統,實現介面陰影效果, 更多內容歡迎關注之後的文章

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69978258/viewspace-2845968/,如需轉載,請註明出處,否則將追究法律責任。

相關文章