1. 程式人生 > 程式設計 >Unity shader實現多光源漫反射以及陰影

Unity shader實現多光源漫反射以及陰影

本文例項為大家分享了shader實現多光源漫反射以及陰影的具體程式碼,供大家參考,具體內容如下

Shader "Unlit/MulLight"
{
 Properties
 {
  _MainTex ("Texture",2D) = "white" {}
 }
 SubShader
 {
  //一盞主燈
  Pass
  {
   //Always: 總是渲染;沒有光照模式。
   //ForwardBase: 適用於前渲染、環境、主要方向燈、光/sh光和烘焙圖。
   //ForwardAdd: 適用於前渲染, 疊加每一盞燈,每一盞燈就多一個pass。
   //Deferred: 延遲渲染,渲染g緩衝區 。
   //ShadowCaster:將物體深度渲染到陰影貼圖或者深度紋理上 。
   //PrepassBase: 用於傳統的延遲光照,渲染法線和高光效果。
   //PrepassFinal:用於傳統的延遲光照,通過結合文理、燈光、和法線來渲染最終的結果。
   //Vertex:當物件不是光對映時,用於遺留頂點的渲染,所有頂點燈都被利用。 
   //VertexLMRGBM: 當物件被光對映時,在遺留的頂點上使用渲染,在LightMap是RGBM編碼的平臺上(pc和控制檯)。
   //VertexLM: 當物件被光對映時,在遺留的頂點上使用渲染,在LightMap是雙idr編碼的(移動平臺)平臺上。
   Tags { "RenderType"="Opaque" "LightMode" = "ForwardBase"}//////
   CGPROGRAM
   #pragma vertex vert
   #pragma fragment frag
   #include "UnityCG.cginc"
    #pragma target 3.0 
 
   //衰減與陰影的實現
   #include "AutoLight.cginc"//////
    //fwdadd:ForwardBase的陰影顯示,在下面的ForwardAdd裡得用fwdadd; 必須結合fallback,兩者缺一不可 
   #pragma multi_compile_fwdadd_fullshadows//////
   sampler2D _MainTex;
   float4 _MainTex_ST;
   //定義一個燈光,名字為固定格式,會自動取場景中燈光
   float4 _LightColor0;//////
 
   struct appdata
   {
    float4 vertex : POSITION;
    float2 uv : TEXCOORD0;
    float4 normal:NORMAL;//////
   };
 
   struct v2f
   {
    float2 uv : TEXCOORD0;
    float4 pos: SV_POSITION;
    float3 normal :TEXCOORD1;//////
     //點光源需要的衰減 
    LIGHTING_COORDS(3,4)//////#include "AutoLight.cginc"
   };
   v2f vert (appdata v)
   {
    v2f o;
    //這裡一般用 o.pos,用o.vertex有時候會報錯 
    o.pos= UnityObjectToClipPos(v.vertex);
    o.uv = TRANSFORM_TEX(v.uv,_MainTex);
    o.normal = v.normal;//////
    //點光源需要的衰減 
    TRANSFER_VERTEX_TO_FRAGMENT(o)//////#include "AutoLight.cginc"
    return o;
   }
   fixed4 frag (v2f i) : SV_Target
   {
    //物體法向量轉化為世界法向量
    float3 N = normalize(UnityObjectToWorldNormal(i.normal));//////
    //世界光向量:unity封裝好的光向量,會自動呼叫場景裡面的存在的燈光
    float3 L =normalize( _WorldSpaceLightPos0.xyz);//////
             //點光源需要的衰減係數
    float atten = LIGHT_ATTENUATION(i);//////#include "AutoLight.cginc"
 
    fixed4 col = tex2D(_MainTex,i.uv);
    //最終顏色 = 主顏色 x( 燈光顏色 x 漫反射係數 x衰減係數 + 環境光)
    col.rgb = col.rgb * (_LightColor0.rgb* saturate(dot(N,L)) *atten + UNITY_LIGHTMODEL_AMBIENT);//////
 
    return col;
   }
   ENDCG
   }
 
   //多盞燈疊加
  Pass//////
  {
   Tags { "RenderType"="Opaque" "LightMode" = "ForwardAdd"} //ForwardAdd :多燈混合//////
   Blend One One//////
   CGPROGRAM
   #pragma vertex vert
   #pragma fragment frag
   #include "UnityCG.cginc"
   #pragma target 3.0
 
   //衰減與陰影的實現
   #include "AutoLight.cginc"//////
    //fwdadd:ForwardAdd的陰影顯示,在上面的ForwardBase裡得用fwdbase; 必須結合fallback,兩者缺一不可 
   #pragma multi_compile_fwdadd_fullshadows//////
 
   sampler2D _MainTex;
   float4 _MainTex_ST;
   //定義一個燈光,名字為固定格式,會自動取場景中燈光
   float4 _LightColor0;//////
 
   struct appdata
   {
    float4 vertex : POSITION;
    float2 uv : TEXCOORD0;
    float4 normal:NORMAL;//////
   };
 
   struct v2f
   {
    float2 uv : TEXCOORD0;
    float4 pos: SV_POSITION;
    float3 normal :TEXCOORD1;//////
    float4 wPos :TEXCOORD2;//////
    //點光源需要的衰減 
    LIGHTING_COORDS(3,4)//////#include "AutoLight.cginc"
   };
   v2f vert (appdata v)
   {
    v2f o;
     //這裡一般用 o.pos,用o.vertex有時候會報錯
    o.pos= UnityObjectToClipPos(v.vertex);
    o.uv = TRANSFORM_TEX(v.uv,_MainTex);
    o.wPos= mul(unity_ObjectToWorld,v.vertex);//////
    o.normal = v.normal;//////
    //點光源需要的衰減
    TRANSFER_VERTEX_TO_FRAGMENT(o)//////#include "AutoLight.cginc"
    return o;
   }
   fixed4 frag (v2f i) : SV_Target
   {
    //物體法向量轉化為世界法向量
    float3 N = normalize(UnityObjectToWorldNormal(i.normal));//////
 
    //世界光向量:這裡計算的是點光源,按照燈光的距離來算衰減,第一個pass不需要
    float3 L = normalize (lerp(_WorldSpaceLightPos0.xyz,_WorldSpaceLightPos0.xyz - i.wPos.xyz,_WorldSpaceLightPos0.w));//////
 
    //點光源需要的衰減
    float atten = LIGHT_ATTENUATION(i);//////#include "AutoLight.cginc"
 
    fixed4 col = tex2D(_MainTex,i.uv);
 
    //最終顏色 = 主顏色 x 燈光顏色 x 漫反射係數 x 衰減係數 第一個pass已經有了環境色 這裡就不能加了
    col.rgb = col.rgb * _LightColor0.rgb * saturate(dot(N,L))*atten;//////
 
    return col;
   }
  ENDCG
  }
 }
   //需要產生陰影 
   FallBack "Diffuse" 
}

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。