SoFunction
Updated on 2025-03-08

Unity shader realizes diffuse reflection and shadowing of multiple light sources

This example shares the specific code of shader to realize diffuse reflection and shadows of multiple light sources for your reference. The specific content is as follows

Shader "Unlit/MulLight"
{
 Properties
 {
  _MainTex ("Texture", 2D) = "white" {}
 }
 SubShader
 {
  //A main light  Pass
  {
   //Always: Always rendering; no lighting mode.   //ForwardBase: Suitable for front rendering, environment, main direction light, light/sh light and baking pictures.   //ForwardAdd: Suitable for front rendering, if you superimpose each lamp, each lamp will have an extra pass.   //Deferred: Delay rendering, rendering g buffer.   //ShadowCaster: Render the object depth to a shadow map or depth texture.   //PrepassBase: Used for traditional delay lighting, rendering normals and highlights.   //PrepassFinal: used in traditional delayed lighting, rendering the final result by combining literature, lighting, and normals.   //Vertex: When the object is not a light map, it is used for rendering of legacy vertices, and all vertex lights are used.   //VertexLMRGBM: When an object is lightly mapped, rendering is used on legacy vertices, on platforms where LightMap is RGBM-encoded (pc and console).   //VertexLM: When an object is lightly mapped, rendering is used on legacy vertices, on a platform where LightMap is a dual idr encoding (mobile platform).   Tags { "RenderType"="Opaque" "LightMode" = "ForwardBase"}//////
   CGPROGRAM
   #pragma vertex vert
   #pragma fragment frag
   #include ""
    #pragma target 3.0 
 
   //Implementation of attenuation and shadow   #include ""//////
    //fwdadd: The shadow of ForwardBase is displayed. In the ForwardAdd below, fwdadd must be used; it must be combined with fallback, both are indispensable.   #pragma multi_compile_fwdadd_fullshadows//////
   sampler2D _MainTex;
   float4 _MainTex_ST;
   //Define a light with a fixed format, and will automatically retrieve the light in the scene   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;//////
     //Attenuation required by the point light source    LIGHTING_COORDS(3,4)//////#include ""
   };
   v2f vert (appdata v)
   {
    v2f o;
    //It is usually used here, and sometimes it will cause an error when used.    = UnityObjectToClipPos();
     = TRANSFORM_TEX(, _MainTex);
     = ;//////
    //Attenuation required by the point light source    TRANSFER_VERTEX_TO_FRAGMENT(o)//////#include ""
    return o;
   }
   fixed4 frag (v2f i) : SV_Target
   {
    //The object normal vector is converted into world normal vector    float3 N = normalize(UnityObjectToWorldNormal());//////
    //World light vector: Unit encapsulated light vector will automatically call the existing lights in the scene    float3 L =normalize( _WorldSpaceLightPos0.xyz);//////
             //The attenuation coefficient required by the point light source    float atten = LIGHT_ATTENUATION(i);//////#include ""
 
    fixed4 col = tex2D(_MainTex, );
    // Final color = main color x (light color x diffuse coefficient x attenuation coefficient + ambient light)     =  * (_LightColor0.rgb* saturate(dot(N,L)) *atten + UNITY_LIGHTMODEL_AMBIENT);//////
 
    return col;
   }
   ENDCG
   }
 
   //Add multiple lamps  Pass//////
  {
   Tags { "RenderType"="Opaque" "LightMode" = "ForwardAdd"} //ForwardAdd: Multi-Lamp Mix////////   Blend One One//////
   CGPROGRAM
   #pragma vertex vert
   #pragma fragment frag
   #include ""
   #pragma target 3.0
 
   //Implementation of attenuation and shadow   #include ""//////
    //fwdadd: The shadow of ForwardAdd is displayed. Fwdbase must be used in the ForwardBase above; it must be combined with fallback, both are indispensable.   #pragma multi_compile_fwdadd_fullshadows//////
 
   sampler2D _MainTex;
   float4 _MainTex_ST;
   //Define a light with a fixed format, and will automatically retrieve the light in the scene   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;//////
    //Attenuation required by the point light source    LIGHTING_COORDS(3,4)//////#include ""
   };
   v2f vert (appdata v)
   {
    v2f o;
     //It is usually used here, and sometimes it will cause an error when used.    = UnityObjectToClipPos();
     = TRANSFORM_TEX(, _MainTex);
    = mul(unity_ObjectToWorld, );//////
     = ;//////
    //Attenuation required by the point light source    TRANSFER_VERTEX_TO_FRAGMENT(o)//////#include ""
    return o;
   }
   fixed4 frag (v2f i) : SV_Target
   {
    //The object normal vector is converted into world normal vector    float3 N = normalize(UnityObjectToWorldNormal());//////
 
    //World light vector: Here is the point light source, and the attenuation is calculated according to the distance of the light. The first pass does not need to    float3 L = normalize (lerp(_WorldSpaceLightPos0.xyz , _WorldSpaceLightPos0.xyz -  , _WorldSpaceLightPos0.w));//////
 
    //Attenuation required by the point light source    float atten = LIGHT_ATTENUATION(i);//////#include ""
 
    fixed4 col = tex2D(_MainTex, );
 
    // Final color = main color x light color x diffuse coefficient x attenuation coefficient The first pass already has an environment color. You can't add it here     =  * _LightColor0.rgb * saturate(dot(N,L))*atten;//////
 
    return col;
   }
  ENDCG
  }
 }
   //Shadows need to be generated   FallBack "Diffuse" 
}

The above is all the content of this article. I hope it will be helpful to everyone's study and I hope everyone will support me more.