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.