unity shader 處理陰影

陰影處理
1、物體能投射陰影以及物體能接受陰影為兩個(gè)方面。
a.物體投射陰影在unity中應(yīng)該打開CastShadow選項(xiàng)。這樣物體深度就可以加入到深度紋理的計(jì)算中,從而影響深度紋理中的depth值。這個(gè)深度紋理生成unity3D中采用的方法與OpenGL大同小異,即:以光源位置,光源方向?yàn)橄鄼C(jī)參數(shù),得到相應(yīng)的深度紋理。
b.物體接受陰影,這個(gè)過程是判斷正常相機(jī)下看到的片段是否在陰影中,采用的方法是傳遞光源下相機(jī)的MVP,然后做position變換到clip空間,然后對(x,y)做[0,1]處理,根據(jù)這個(gè)處理后的值對上一步中的深度紋理進(jìn)行采樣得到相應(yīng)的深度d0,如果d0<postion.z([0,1]變換后的depth值),說明這個(gè)片段在陰影中,應(yīng)該對顏色進(jìn)行乘以shadow值。

2、Unity3D shader中寫法。
unity3d中讓物體參與到陰影紋理的生成中,除了castShadow打開外,要在pass中執(zhí)行上述說的深度紋理生成,此過程一般不放到basePass與addtionPass中,因?yàn)檫@兩個(gè)pass一般進(jìn)行光照計(jì)算,而深度紋理計(jì)算只是得到深度紋理,因此可以使用一個(gè)單獨(dú)的pass,即“LightMode” = “ShadowCaster”的pass來得到。而這個(gè)pass一般在FallBack “Diffuse”等FallBack中得到。
接受紋理可以用下面步驟:
a.單獨(dú)處理shadow可以在v2f中添加SHADOW_COORD(x) ,x為下一個(gè)可以使用的寄存器編號。注意使用這個(gè)宏最后不加“;”,因?yàn)檫@個(gè)定義是在struct中,且在“autolight.cginc”的定義中已經(jīng)添加了最后的分號。
b.在vert中使用TRANSFER_SHADOW(o);這個(gè)宏可以將v2f變量o中的紋理采樣坐標(biāo)變換得到相應(yīng)的屏幕空間紋理,為采樣深度紋理使用。
c.在frg中使用SHADOW_ATTENUTION(i),計(jì)算對應(yīng)的fragment是否在shadow中,這個(gè)宏返回一個(gè)fixed值,然后將此值與frag中得到的col值相乘,即可得到相應(yīng)的陰影效果。
3、實(shí)例代碼

Shader "FFD/shadow1"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" "LightMode"="ForwardBase"}
        LOD 100
        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            //要想有正確的衰減內(nèi)置變量等,必須要有這句
            #pragma multi_compile_fwdbase

            
            #include "UnityCG.cginc"
            #include "autolight.cginc"
            #include "lighting.cginc"

            struct v2f
            {
                float2 uv : TEXCOORD0;
                float4 pos : SV_POSITION;
                SHADOW_COORDS(1)    //宏表示為定義一個(gè)float4的采樣坐標(biāo),放到編號為1的寄存器中
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;
            
            v2f vert (appdata_base v)
            {
                v2f o;
                o.pos = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
                TRANSFER_SHADOW(o)  //根據(jù)變換求解上面結(jié)構(gòu)體中的float4坐標(biāo),unity5中采用的是屏幕空間陰影貼圖
                return o;
            }
            fixed4 frag (v2f i) : SV_Target
            {
                // sample the texture
                fixed4 col = tex2D(_MainTex, i.uv);
                fixed shadow = SHADOW_ATTENUATION(i); //根據(jù)貼圖與紋理坐標(biāo)對紋理采樣得到shadow值。
                col = col*shadow; //最終影響光照
                return col;
            }
            ENDCG
        }
    }
    FallBack "Specular"
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 一.標(biāo)準(zhǔn)光照模型OpenGL與Direct3D提供了幾乎相同的固定功能光照模型。什么是固定功能光照模型?在過去只有...
    karma085閱讀 3,856評論 0 2
  • 很久之前.我養(yǎng)過一只貓.那是我在路邊撿到的一只黑貓.恬靜的黑,一點(diǎn)一點(diǎn)的將我吸引而去.猶如掉入無盡黑暗中.對上眼眸...
    1988情人閱讀 616評論 0 1
  • 文/向光的小蟲 1、 透過卷簾的百葉窗,看到秋葉蕭瑟地從窗前緩緩滑落,突然感覺秋意濃烈的像桌上的那杯熱咖,苦澀中嘗...
    向光的小蟲閱讀 357評論 0 1
  • 明天開學(xué),欣翼就要成為三年級的小學(xué)生了,看得出一個(gè)暑假沒見老師跟同學(xué)了,談起上學(xué)她還是有點(diǎn)小緊張的,晚飯后,...
    欣翼媽媽閱讀 315評論 0 0

友情鏈接更多精彩內(nèi)容