目录
前言:
一、属性
二、SubShader
三、ForwardLitPass
定义Tags
声明变体
声明变量
定义结构体
顶点Shader
片元Shader
四、全代码
四、添加官方的LitShader代码
五、全代码
六、效果图
七、结语
前言:
哈喽啊,我又来啦。这次呢给大家带来了UnityURP渲染管线的优化自定义多光源Shader模板,之前呢我也写过Unity URPShader支持多光源处理_urp 多光源-CSDN博客和多光源的阴影接收Unity URP支持多光源阴影_urp 多光源 阴影-CSDN博客。
前面的文章确实解决了很多,但是呢,其中硬要抠细节,说实话并不好,这次呢,我会给大家带来参考Unity官方的模板,重写URP管线里的Lit光照Shader,这个Shader在主要的光照部分能完美的处理,并且能够自定义我们想要的其它额外效果(主要是跟大家完美解决URP的阴影问题啦。)
其实呢,要改的东西不多,大多数都是Copy官方的Lit代码,其中我们核心修改“ForwardLit”部分。
(支持Sprite精灵图的阴影)
一、属性
Properties{[MainTexture] _BaseMap ("Albedo", 2D) = "white" { }[MainColor] _BaseColor ("Color", Color) = (1, 1, 1, 1)[Toggle] _ReceiveShadows ("Receive Shadows", Float) = 1.0[Enum(UnityEngine.Rendering.CullMode)]_Cull ("CullMode", Float) = 2.0[Toggle] _AlphaTest ("AlphaClip", Float) = 1.0// ObsoleteProperties[HideInInspector] _MainTex ("BaseMap", 2D) = "white" { }[HideInInspector]_Smoothness ("Smoothness", Range(0.0, 1.0)) = 0.5[HideInInspector]_Metallic ("Metallic", Range(0.0, 1.0)) = 0.0[HideInInspector]_Cutoff ("Alpha Cutoff", Range(0.0, 1.0)) = 0.5}
属性呢就可以直接采用我写好的属性,这些都迎合了SRPBactcher,可以保留的最少的属性(奇迹上也不是真的最少啦,我的这种是最有用但最少的哈哈。)
二、SubShader
Tags { "RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline" "UniversalMaterialType" = "Lit" }LOD 300
我们声明好Tags,当然可以根据你的项目需求,自定义这部分。
三、ForwardLitPass
定义Tags
这一块是我们的核心功能,我会给出多光源光照、多光源阴影接收的模板代码并解释,你可以根据需求任意修改它们。
SubShader{Tags { "RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline" "UniversalMaterialType" = "Lit" }LOD 300Pass{Name "ForwardLit"Tags { "LightMode" = "UniversalForward" }Blend One Zero, One ZeroZWrite OnCull[_Cull]AlphaToMask On}}
声明变体
首先呢,Pass里的Name也不是固定的,可以随意修改它,这里我就默认了。
其次,这个Pass采用前向渲染的光照Tag,我们需要定义好。
然后是Blend部分,其实这里呢不加也可以,如果你操作的是透明物体,那么需要加上。
#pragma vertex vert
#pragma fragment frag
#pragma shader_feature_local _RECEIVESHADOWS_ON //是否开启接收阴影的开关
#pragma shader_feature_local _ALPHATEST_ON //其否其余AlphaClip的开关【适合Png图片剔除】
#pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN //主光的阴影变体
#pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS //额外光变体
#pragma multi_compile _ _ADDITIONAL_LIGHT_SHADOWS //额外光的阴影变体
#pragma multi_compile_fragment _ _SHADOWS_SOFT _SHADOWS_SOFT_LOW _SHADOWS_SOFT_MEDIUM _SHADOWS_SOFT_HIGH //阴影的质量变体#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/ShaderGraphFunctions.hlsl" //主要用于后面的函数调用
声明变量
TEXTURE2D(_BaseMap);SAMPLER(sampler_BaseMap);//CBuffer里的变量必须包含以下的变量,不然不会适配SRP,定义这些不会影响性能CBUFFER_START(UnityPerMaterial)float4 _BaseMap_ST;float4 _DetailAlbedoMap_ST;half4 _BaseColor;half4 _SpecColor;half4 _EmissionColor;half _Cutoff;half _Smoothness;half _Metallic;half _BumpScale;half _Parallax;half _OcclusionStrength;half _ClearCoatMask;half _ClearCoatSmoothness;half _DetailAlbedoMapScale;half _DetailNormalMapScale;half _Surface;
CBUFFER_END//实例化参数,看需求定义
#ifdef UNITY_DOTS_INSTANCING_ENABLEDUNITY_DOTS_INSTANCING_START(MaterialPropertyMetadata)UNITY_DOTS_INSTANCED_PROP(float4, _BaseColor)UNITY_DOTS_INSTANCING_END(MaterialPropertyMetadata)
#endif
定义结构体
struct Attributes{float4 positionOS : POSITION;float2 texcoord : TEXCOORD0;float3 normalOS : NORMAL;UNITY_VERTEX_INPUT_INSTANCE_ID};struct Varyings{float4 positionHS : SV_POSITION;float2 uv : TEXCOORD0;float3 positionWS : TEXCOORD1;float3 normalWS : TEXCOORD2;half3 lightColor : COLOR; //额外光照的颜色,需要进行记录顶点光照的#ifdef _RECEIVESHADOWS_ON //开启接收光照开关需要的变量float4 shadowCoord : TEXCOORD3; //主光的阴影#ifdef _ADDITIONAL_LIGHTSfloat4 shadowMask : TEXCOORD4; //如果是逐像素光源,需要一个shadowMask#endif#endifUNITY_VERTEX_INPUT_INSTANCE_ID};
顶点Shader
Varyings vert(Attributes v){Varyings o;UNITY_SETUP_INSTANCE_ID(v);UNITY_TRANSFER_INSTANCE_ID(v, o);o.positionHS = TransformObjectToHClip(v.positionOS.xyz);o.positionWS = TransformObjectToWorld(v.positionOS.xyz);o.normalWS = TransformObjectToWorldNormal(v.normalOS);o.uv = v.texcoord;//光照o.lightColor = 0.0;#ifdef _RECEIVESHADOWS_ON //如果开启接收阴影//主光阴影坐标o.shadowCoord = TransformWorldToShadowCoord(o.positionWS);//多光源的阴影,需要定义shadowMask#if defined(SHADOWS_SHADOWMASK) && defined(LIGHTMAP_ON)half4 shadowMask = inputData.shadowMask;#elif !defined(LIGHTMAP_ON)half4 shadowMask = unity_ProbesOcclusion;#elsehalf4 shadowMask = 1.0;#endif//如果是逐顶点灯光#if _ADDITIONAL_LIGHTS_VERTEXuint pixelLightCount = GetAdditionalLightsCount();for (uint lightIndex = 0u; lightIndex < pixelLightCount; ++lightIndex){Light light = GetAdditionalLight(lightIndex, positionWS, shadowMask);half3 attenuatedLightColor = light.color * light.distanceAttenuation * light.shadowAttenuation;o.lightColor += LightingLambert(attenuatedLightColor, light.direction, o.normalWS);}//如果是逐像素灯光#elif _ADDITIONAL_LIGHTSo.shadowMask = shadowMask;#endif//不开启接收阴影#else#ifdef _ADDITIONAL_LIGHTS_VERTEXfor (uint lightIndex = 0u; lightIndex < pixelLightCount; ++lightIndex){Light light = GetAdditionalLight(lightIndex, positionWS);half3 attenuatedLightColor = light.color * light.distanceAttenuation * light.shadowAttenuation;o.lightColor += LightingLambert(attenuatedLightColor, light.direction, o.normalWS);}#endif#endifreturn o;}
片元Shader
half4 frag(Varyings i) : SV_Target{UNITY_SETUP_INSTANCE_ID(i);//光照half3 lightColor = i.lightColor; //如果是逐顶点光照,lightColor需要保存逐顶点的光照//开启接受阴影#ifdef _RECEIVESHADOWS_ON//主光颜色和阴影Light main_light = GetMainLight(i.shadowCoord);half3 main_attenuatedLightColor = main_light.color * main_light.distanceAttenuation * main_light.shadowAttenuation;lightColor += LightingLambert(main_attenuatedLightColor, main_light.direction, i.normalWS);//如果是逐像素光源#ifdef _ADDITIONAL_LIGHTSuint pixelLightCount = GetAdditionalLightsCount();for (uint lightIndex = 0u; lightIndex < pixelLightCount; ++lightIndex){Light light = GetAdditionalLight(lightIndex, i.positionWS.xyz, i.shadowMask);half3 attenuatedLightColor = light.color * light.distanceAttenuation * light.shadowAttenuation;//继续累加颜色lightColor += LightingLambert(attenuatedLightColor, light.direction, i.normalWS);}#endif//不接受阴影#elseLight main_light = GetMainLight();half3 main_attenuatedLightColor = main_light.color * main_light.distanceAttenuation * main_light.shadowAttenuation;lightColor += LightingLambert(main_attenuatedLightColor, main_light.direction, i.normalWS);#ifdef _ADDITIONAL_LIGHTSuint pixelLightCount = GetAdditionalLightsCount();for (uint lightIndex = 0u; lightIndex < pixelLightCount; ++lightIndex){Light light = GetAdditionalLight(lightIndex, i.positionWS.xyz);half3 attenuatedLightColor = light.color * light.distanceAttenuation * light.shadowAttenuation;lightColor += LightingLambert(attenuatedLightColor, light.direction, i.normalWS);}#endif#endif//环境光half3 ambient = half3(unity_SHAr.w, unity_SHAg.w, unity_SHAb.w);//贴图基础颜色half4 col = SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, i.uv);col.rgb *= _BaseColor.rgb * lightColor + ambient;//alpha剔除,适配png图片#ifdef _ALPHATEST_ONcol.a = AlphaDiscard(col.a, _Cutoff);#elsecol.a = 1.0;#endifreturn col;}
四、全代码
Pass{Name "ForwardLit"Tags { "LightMode" = "UniversalForward" }Blend One Zero, One ZeroZWrite OnCull[_Cull]AlphaToMask OnHLSLPROGRAM#pragma vertex vert#pragma fragment frag#pragma shader_feature_local _RECEIVESHADOWS_ON#pragma shader_feature_local _ALPHATEST_ON#pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN#pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS#pragma multi_compile _ _ADDITIONAL_LIGHT_SHADOWS#pragma multi_compile_fragment _ _SHADOWS_SOFT _SHADOWS_SOFT_LOW _SHADOWS_SOFT_MEDIUM _SHADOWS_SOFT_HIGH#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/ShaderGraphFunctions.hlsl"TEXTURE2D(_BaseMap);SAMPLER(sampler_BaseMap);CBUFFER_START(UnityPerMaterial)float4 _BaseMap_ST;float4 _DetailAlbedoMap_ST;half4 _BaseColor;half4 _SpecColor;half4 _EmissionColor;half _Cutoff;half _Smoothness;half _Metallic;half _BumpScale;half _Parallax;half _OcclusionStrength;half _ClearCoatMask;half _ClearCoatSmoothness;half _DetailAlbedoMapScale;half _DetailNormalMapScale;half _Surface;CBUFFER_END#ifdef UNITY_DOTS_INSTANCING_ENABLEDUNITY_DOTS_INSTANCING_START(MaterialPropertyMetadata)UNITY_DOTS_INSTANCED_PROP(float4, _BaseColor)UNITY_DOTS_INSTANCING_END(MaterialPropertyMetadata)#endifstruct Attributes{float4 positionOS : POSITION;float2 texcoord : TEXCOORD0;float3 normalOS : NORMAL;UNITY_VERTEX_INPUT_INSTANCE_ID};struct Varyings{float4 positionHS : SV_POSITION;float2 uv : TEXCOORD0;float3 positionWS : TEXCOORD1;float3 normalWS : TEXCOORD2;half3 lightColor : COLOR;#ifdef _RECEIVESHADOWS_ONfloat4 shadowCoord : TEXCOORD3;#ifdef _ADDITIONAL_LIGHTSfloat4 shadowMask : TEXCOORD4;#endif#endifUNITY_VERTEX_INPUT_INSTANCE_ID};Varyings vert(Attributes v){Varyings o;UNITY_SETUP_INSTANCE_ID(v);UNITY_TRANSFER_INSTANCE_ID(v, o);o.positionHS = TransformObjectToHClip(v.positionOS.xyz);o.positionWS = TransformObjectToWorld(v.positionOS.xyz);o.normalWS = TransformObjectToWorldNormal(v.normalOS);o.uv = v.texcoord;//光照o.lightColor = 0.0;#ifdef _RECEIVESHADOWS_ONo.shadowCoord = TransformWorldToShadowCoord(o.positionWS);//多光源的阴影#if defined(SHADOWS_SHADOWMASK) && defined(LIGHTMAP_ON)half4 shadowMask = inputData.shadowMask;#elif !defined(LIGHTMAP_ON)half4 shadowMask = unity_ProbesOcclusion;#elsehalf4 shadowMask = 1.0;#endif#if _ADDITIONAL_LIGHTS_VERTEXuint pixelLightCount = GetAdditionalLightsCount();for (uint lightIndex = 0u; lightIndex < pixelLightCount; ++lightIndex){Light light = GetAdditionalLight(lightIndex, positionWS, shadowMask);half3 attenuatedLightColor = light.color * light.distanceAttenuation * light.shadowAttenuation;o.lightColor += LightingLambert(attenuatedLightColor, light.direction, o.normalWS);}#elif _ADDITIONAL_LIGHTSo.shadowMask = shadowMask;#endif#else#ifdef _ADDITIONAL_LIGHTS_VERTEXfor (uint lightIndex = 0u; lightIndex < pixelLightCount; ++lightIndex){Light light = GetAdditionalLight(lightIndex, positionWS);half3 attenuatedLightColor = light.color * light.distanceAttenuation * light.shadowAttenuation;o.lightColor += LightingLambert(attenuatedLightColor, light.direction, o.normalWS);}#endif#endifreturn o;}half4 frag(Varyings i) : SV_Target{UNITY_SETUP_INSTANCE_ID(i);//光照half3 lightColor = i.lightColor;#ifdef _RECEIVESHADOWS_ONLight main_light = GetMainLight(i.shadowCoord);half3 main_attenuatedLightColor = main_light.color * main_light.distanceAttenuation * main_light.shadowAttenuation;lightColor += LightingLambert(main_attenuatedLightColor, main_light.direction, i.normalWS);#ifdef _ADDITIONAL_LIGHTSuint pixelLightCount = GetAdditionalLightsCount();for (uint lightIndex = 0u; lightIndex < pixelLightCount; ++lightIndex){Light light = GetAdditionalLight(lightIndex, i.positionWS.xyz, i.shadowMask);half3 attenuatedLightColor = light.color * light.distanceAttenuation * light.shadowAttenuation;lightColor += LightingLambert(attenuatedLightColor, light.direction, i.normalWS);}#endif#elseLight main_light = GetMainLight();half3 main_attenuatedLightColor = main_light.color * main_light.distanceAttenuation * main_light.shadowAttenuation;lightColor += LightingLambert(main_attenuatedLightColor, main_light.direction, i.normalWS);#ifdef _ADDITIONAL_LIGHTSuint pixelLightCount = GetAdditionalLightsCount();for (uint lightIndex = 0u; lightIndex < pixelLightCount; ++lightIndex){Light light = GetAdditionalLight(lightIndex, i.positionWS.xyz);half3 attenuatedLightColor = light.color * light.distanceAttenuation * light.shadowAttenuation;lightColor += LightingLambert(attenuatedLightColor, light.direction, i.normalWS);}#endif#endif//环境光half3 ambient = half3(unity_SHAr.w, unity_SHAg.w, unity_SHAb.w);half4 col = SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, i.uv);col.rgb *= _BaseColor.rgb * lightColor + ambient;#ifdef _ALPHATEST_ONcol.a = AlphaDiscard(col.a, _Cutoff);#elsecol.a = 1.0;#endifreturn col;}ENDHLSL}
四、添加官方的LitShader代码
如果需要自定义阴影,可以看我之前的阴影部分文章的ShadowCast部分
Unity URP支持多光源阴影_urp 多光源 阴影-CSDN博客
Pass{Name "ShadowCaster"Tags { "LightMode" = "ShadowCaster" }// -------------------------------------// Render State CommandsZWrite OnZTest LEqualColorMask 0Cull[_Cull]HLSLPROGRAM#pragma target 2.0// -------------------------------------// Shader Stages#pragma vertex ShadowPassVertex#pragma fragment ShadowPassFragment// -------------------------------------// Material Keywords#pragma shader_feature_local _ALPHATEST_ON#pragma shader_feature_local_fragment _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A//--------------------------------------// GPU Instancing#pragma multi_compile_instancing#include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DOTS.hlsl"// -------------------------------------// Universal Pipeline keywords// -------------------------------------// Unity defined keywords#pragma multi_compile_fragment _ LOD_FADE_CROSSFADE// This is used during shadow map generation to differentiate between directional and punctual light shadows, as they use different formulas to apply Normal Bias#pragma multi_compile_vertex _ _CASTING_PUNCTUAL_LIGHT_SHADOW// -------------------------------------// Includes#include "Packages/com.unity.render-pipelines.universal/Shaders/LitInput.hlsl"#include "Packages/com.unity.render-pipelines.universal/Shaders/ShadowCasterPass.hlsl"ENDHLSL}Pass{// Lightmode matches the ShaderPassName set in UniversalRenderPipeline.cs. SRPDefaultUnlit and passes with// no LightMode tag are also rendered by Universal Render PipelineName "GBuffer"Tags { "LightMode" = "UniversalGBuffer" }// -------------------------------------// Render State CommandsZWrite[_ZWrite]ZTest LEqualCull[_Cull]HLSLPROGRAM#pragma target 4.5// Deferred Rendering Path does not support the OpenGL-based graphics API:// Desktop OpenGL, OpenGL ES 3.0, WebGL 2.0.#pragma exclude_renderers gles3 glcore// -------------------------------------// Shader Stages#pragma vertex LitGBufferPassVertex#pragma fragment LitGBufferPassFragment// -------------------------------------// Material Keywords#pragma shader_feature_local _NORMALMAP#pragma shader_feature_local_fragment _ALPHATEST_ON//#pragma shader_feature_local_fragment _ALPHAPREMULTIPLY_ON#pragma shader_feature_local_fragment _EMISSION#pragma shader_feature_local_fragment _METALLICSPECGLOSSMAP#pragma shader_feature_local_fragment _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A#pragma shader_feature_local_fragment _OCCLUSIONMAP#pragma shader_feature_local _PARALLAXMAP#pragma shader_feature_local _ _DETAIL_MULX2 _DETAIL_SCALED#pragma shader_feature_local_fragment _SPECULARHIGHLIGHTS_OFF#pragma shader_feature_local_fragment _ENVIRONMENTREFLECTIONS_OFF#pragma shader_feature_local_fragment _SPECULAR_SETUP#pragma shader_feature_local _RECEIVE_SHADOWS_OFF// -------------------------------------// Universal Pipeline keywords#pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN//#pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS//#pragma multi_compile _ _ADDITIONAL_LIGHT_SHADOWS#pragma multi_compile_fragment _ _REFLECTION_PROBE_BLENDING#pragma multi_compile_fragment _ _REFLECTION_PROBE_BOX_PROJECTION#pragma multi_compile_fragment _ _SHADOWS_SOFT _SHADOWS_SOFT_LOW _SHADOWS_SOFT_MEDIUM _SHADOWS_SOFT_HIGH#pragma multi_compile_fragment _ _DBUFFER_MRT1 _DBUFFER_MRT2 _DBUFFER_MRT3#pragma multi_compile_fragment _ _RENDER_PASS_ENABLED#include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/RenderingLayers.hlsl"// -------------------------------------// Unity defined keywords#pragma multi_compile _ LIGHTMAP_SHADOW_MIXING#pragma multi_compile _ SHADOWS_SHADOWMASK#pragma multi_compile _ DIRLIGHTMAP_COMBINED#pragma multi_compile _ LIGHTMAP_ON#pragma multi_compile _ DYNAMICLIGHTMAP_ON#pragma multi_compile_fragment _ LOD_FADE_CROSSFADE#pragma multi_compile_fragment _ _GBUFFER_NORMALS_OCT//--------------------------------------// GPU Instancing#pragma multi_compile_instancing#pragma instancing_options renderinglayer#include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DOTS.hlsl"// -------------------------------------// Includes#include "Packages/com.unity.render-pipelines.universal/Shaders/LitInput.hlsl"#include "Packages/com.unity.render-pipelines.universal/Shaders/LitGBufferPass.hlsl"ENDHLSL}Pass{Name "DepthOnly"Tags { "LightMode" = "DepthOnly" }// -------------------------------------// Render State CommandsZWrite OnColorMask RCull[_Cull]HLSLPROGRAM#pragma target 2.0// -------------------------------------// Shader Stages#pragma vertex DepthOnlyVertex#pragma fragment DepthOnlyFragment// -------------------------------------// Material Keywords#pragma shader_feature_local _ALPHATEST_ON#pragma shader_feature_local_fragment _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A// -------------------------------------// Unity defined keywords#pragma multi_compile_fragment _ LOD_FADE_CROSSFADE//--------------------------------------// GPU Instancing#pragma multi_compile_instancing#include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DOTS.hlsl"// -------------------------------------// Includes#include "Packages/com.unity.render-pipelines.universal/Shaders/LitInput.hlsl"#include "Packages/com.unity.render-pipelines.universal/Shaders/DepthOnlyPass.hlsl"ENDHLSL}// This pass is used when drawing to a _CameraNormalsTexture texturePass{Name "DepthNormals"Tags { "LightMode" = "DepthNormals" }// -------------------------------------// Render State CommandsZWrite OnCull[_Cull]HLSLPROGRAM#pragma target 2.0// -------------------------------------// Shader Stages#pragma vertex DepthNormalsVertex#pragma fragment DepthNormalsFragment// -------------------------------------// Material Keywords#pragma shader_feature_local _NORMALMAP#pragma shader_feature_local _PARALLAXMAP#pragma shader_feature_local _ _DETAIL_MULX2 _DETAIL_SCALED#pragma shader_feature_local_fragment _ALPHATEST_ON#pragma shader_feature_local_fragment _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A// -------------------------------------// Unity defined keywords#pragma multi_compile_fragment _ LOD_FADE_CROSSFADE// -------------------------------------// Universal Pipeline keywords#include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/RenderingLayers.hlsl"//--------------------------------------// GPU Instancing#pragma multi_compile_instancing#include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DOTS.hlsl"// -------------------------------------// Includes#include "Packages/com.unity.render-pipelines.universal/Shaders/LitInput.hlsl"#include "Packages/com.unity.render-pipelines.universal/Shaders/LitDepthNormalsPass.hlsl"ENDHLSL}// This pass it not used during regular rendering, only for lightmap baking.Pass{Name "Meta"Tags { "LightMode" = "Meta" }// -------------------------------------// Render State CommandsCull OffHLSLPROGRAM#pragma target 2.0// -------------------------------------// Shader Stages#pragma vertex UniversalVertexMeta#pragma fragment UniversalFragmentMetaLit// -------------------------------------// Material Keywords#pragma shader_feature_local_fragment _SPECULAR_SETUP#pragma shader_feature_local_fragment _EMISSION#pragma shader_feature_local_fragment _METALLICSPECGLOSSMAP#pragma shader_feature_local_fragment _ALPHATEST_ON#pragma shader_feature_local_fragment _ _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A#pragma shader_feature_local _ _DETAIL_MULX2 _DETAIL_SCALED#pragma shader_feature_local_fragment _SPECGLOSSMAP#pragma shader_feature EDITOR_VISUALIZATION// -------------------------------------// Includes#include "Packages/com.unity.render-pipelines.universal/Shaders/LitInput.hlsl"#include "Packages/com.unity.render-pipelines.universal/Shaders/LitMetaPass.hlsl"ENDHLSL}Pass{Name "Universal2D"Tags { "LightMode" = "Universal2D" }// -------------------------------------// Render State CommandsBlend[_SrcBlend][_DstBlend]ZWrite[_ZWrite]Cull[_Cull]HLSLPROGRAM#pragma target 2.0// -------------------------------------// Shader Stages#pragma vertex vert#pragma fragment frag// -------------------------------------// Material Keywords#pragma shader_feature_local_fragment _ALPHATEST_ON#pragma shader_feature_local_fragment _ALPHAPREMULTIPLY_ON#include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DOTS.hlsl"// -------------------------------------// Includes#include "Packages/com.unity.render-pipelines.universal/Shaders/LitInput.hlsl"#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/Universal2D.hlsl"ENDHLSL}
五、全代码
Shader "Custom_Lit"
{Properties{[MainTexture] _BaseMap ("Albedo", 2D) = "white" { }[MainColor] _BaseColor ("Color", Color) = (1, 1, 1, 1)[Toggle] _ReceiveShadows ("Receive Shadows", Float) = 1.0[Enum(UnityEngine.Rendering.CullMode)]_Cull ("CullMode", Float) = 2.0[Toggle] _AlphaTest ("AlphaClip", Float) = 1.0// ObsoleteProperties[HideInInspector] _MainTex ("BaseMap", 2D) = "white" { }[HideInInspector]_Smoothness ("Smoothness", Range(0.0, 1.0)) = 0.5[HideInInspector]_Metallic ("Metallic", Range(0.0, 1.0)) = 0.0[HideInInspector]_Cutoff ("Alpha Cutoff", Range(0.0, 1.0)) = 0.5}SubShader{Tags { "RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline" "UniversalMaterialType" = "Lit" }LOD 300Pass{Name "ForwardLit"Tags { "LightMode" = "UniversalForward" }Blend One Zero, One ZeroZWrite OnCull[_Cull]AlphaToMask OnHLSLPROGRAM#pragma vertex vert#pragma fragment frag#pragma shader_feature_local _RECEIVESHADOWS_ON#pragma shader_feature_local _ALPHATEST_ON#pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN#pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS#pragma multi_compile _ _ADDITIONAL_LIGHT_SHADOWS#pragma multi_compile_fragment _ _SHADOWS_SOFT _SHADOWS_SOFT_LOW _SHADOWS_SOFT_MEDIUM _SHADOWS_SOFT_HIGH#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/ShaderGraphFunctions.hlsl"TEXTURE2D(_BaseMap);SAMPLER(sampler_BaseMap);CBUFFER_START(UnityPerMaterial)float4 _BaseMap_ST;float4 _DetailAlbedoMap_ST;half4 _BaseColor;half4 _SpecColor;half4 _EmissionColor;half _Cutoff;half _Smoothness;half _Metallic;half _BumpScale;half _Parallax;half _OcclusionStrength;half _ClearCoatMask;half _ClearCoatSmoothness;half _DetailAlbedoMapScale;half _DetailNormalMapScale;half _Surface;CBUFFER_END#ifdef UNITY_DOTS_INSTANCING_ENABLEDUNITY_DOTS_INSTANCING_START(MaterialPropertyMetadata)UNITY_DOTS_INSTANCED_PROP(float4, _BaseColor)UNITY_DOTS_INSTANCING_END(MaterialPropertyMetadata)#endifstruct Attributes{float4 positionOS : POSITION;float2 texcoord : TEXCOORD0;float3 normalOS : NORMAL;UNITY_VERTEX_INPUT_INSTANCE_ID};struct Varyings{float4 positionHS : SV_POSITION;float2 uv : TEXCOORD0;float3 positionWS : TEXCOORD1;float3 normalWS : TEXCOORD2;half3 lightColor : COLOR;#ifdef _RECEIVESHADOWS_ONfloat4 shadowCoord : TEXCOORD3;#ifdef _ADDITIONAL_LIGHTSfloat4 shadowMask : TEXCOORD4;#endif#endifUNITY_VERTEX_INPUT_INSTANCE_ID};Varyings vert(Attributes v){Varyings o;UNITY_SETUP_INSTANCE_ID(v);UNITY_TRANSFER_INSTANCE_ID(v, o);o.positionHS = TransformObjectToHClip(v.positionOS.xyz);o.positionWS = TransformObjectToWorld(v.positionOS.xyz);o.normalWS = TransformObjectToWorldNormal(v.normalOS);o.uv = v.texcoord;//光照o.lightColor = 0.0;#ifdef _RECEIVESHADOWS_ONo.shadowCoord = TransformWorldToShadowCoord(o.positionWS);//多光源的阴影#if defined(SHADOWS_SHADOWMASK) && defined(LIGHTMAP_ON)half4 shadowMask = inputData.shadowMask;#elif !defined(LIGHTMAP_ON)half4 shadowMask = unity_ProbesOcclusion;#elsehalf4 shadowMask = 1.0;#endif#if _ADDITIONAL_LIGHTS_VERTEXuint pixelLightCount = GetAdditionalLightsCount();for (uint lightIndex = 0u; lightIndex < pixelLightCount; ++lightIndex){Light light = GetAdditionalLight(lightIndex, positionWS, shadowMask);half3 attenuatedLightColor = light.color * light.distanceAttenuation * light.shadowAttenuation;o.lightColor += LightingLambert(attenuatedLightColor, light.direction, o.normalWS);}#elif _ADDITIONAL_LIGHTSo.shadowMask = shadowMask;#endif#else#ifdef _ADDITIONAL_LIGHTS_VERTEXfor (uint lightIndex = 0u; lightIndex < pixelLightCount; ++lightIndex){Light light = GetAdditionalLight(lightIndex, positionWS);half3 attenuatedLightColor = light.color * light.distanceAttenuation * light.shadowAttenuation;o.lightColor += LightingLambert(attenuatedLightColor, light.direction, o.normalWS);}#endif#endifreturn o;}half4 frag(Varyings i) : SV_Target{UNITY_SETUP_INSTANCE_ID(i);//光照half3 lightColor = i.lightColor;#ifdef _RECEIVESHADOWS_ONLight main_light = GetMainLight(i.shadowCoord);half3 main_attenuatedLightColor = main_light.color * main_light.distanceAttenuation * main_light.shadowAttenuation;lightColor += LightingLambert(main_attenuatedLightColor, main_light.direction, i.normalWS);#ifdef _ADDITIONAL_LIGHTSuint pixelLightCount = GetAdditionalLightsCount();for (uint lightIndex = 0u; lightIndex < pixelLightCount; ++lightIndex){Light light = GetAdditionalLight(lightIndex, i.positionWS.xyz, i.shadowMask);half3 attenuatedLightColor = light.color * light.distanceAttenuation * light.shadowAttenuation;lightColor += LightingLambert(attenuatedLightColor, light.direction, i.normalWS);}#endif#elseLight main_light = GetMainLight();half3 main_attenuatedLightColor = main_light.color * main_light.distanceAttenuation * main_light.shadowAttenuation;lightColor += LightingLambert(main_attenuatedLightColor, main_light.direction, i.normalWS);#ifdef _ADDITIONAL_LIGHTSuint pixelLightCount = GetAdditionalLightsCount();for (uint lightIndex = 0u; lightIndex < pixelLightCount; ++lightIndex){Light light = GetAdditionalLight(lightIndex, i.positionWS.xyz);half3 attenuatedLightColor = light.color * light.distanceAttenuation * light.shadowAttenuation;lightColor += LightingLambert(attenuatedLightColor, light.direction, i.normalWS);}#endif#endif//环境光half3 ambient = half3(unity_SHAr.w, unity_SHAg.w, unity_SHAb.w);half4 col = SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, i.uv);col.rgb *= _BaseColor.rgb * lightColor + ambient;#ifdef _ALPHATEST_ONcol.a = AlphaDiscard(col.a, _Cutoff);#elsecol.a = 1.0;#endifreturn col;}ENDHLSL}Pass{Name "ShadowCaster"Tags { "LightMode" = "ShadowCaster" }// -------------------------------------// Render State CommandsZWrite OnZTest LEqualColorMask 0Cull[_Cull]HLSLPROGRAM#pragma target 2.0// -------------------------------------// Shader Stages#pragma vertex ShadowPassVertex#pragma fragment ShadowPassFragment// -------------------------------------// Material Keywords#pragma shader_feature_local _ALPHATEST_ON#pragma shader_feature_local_fragment _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A//--------------------------------------// GPU Instancing#pragma multi_compile_instancing#include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DOTS.hlsl"// -------------------------------------// Universal Pipeline keywords// -------------------------------------// Unity defined keywords#pragma multi_compile_fragment _ LOD_FADE_CROSSFADE// This is used during shadow map generation to differentiate between directional and punctual light shadows, as they use different formulas to apply Normal Bias#pragma multi_compile_vertex _ _CASTING_PUNCTUAL_LIGHT_SHADOW// -------------------------------------// Includes#include "Packages/com.unity.render-pipelines.universal/Shaders/LitInput.hlsl"#include "Packages/com.unity.render-pipelines.universal/Shaders/ShadowCasterPass.hlsl"ENDHLSL}Pass{// Lightmode matches the ShaderPassName set in UniversalRenderPipeline.cs. SRPDefaultUnlit and passes with// no LightMode tag are also rendered by Universal Render PipelineName "GBuffer"Tags { "LightMode" = "UniversalGBuffer" }// -------------------------------------// Render State CommandsZWrite[_ZWrite]ZTest LEqualCull[_Cull]HLSLPROGRAM#pragma target 4.5// Deferred Rendering Path does not support the OpenGL-based graphics API:// Desktop OpenGL, OpenGL ES 3.0, WebGL 2.0.#pragma exclude_renderers gles3 glcore// -------------------------------------// Shader Stages#pragma vertex LitGBufferPassVertex#pragma fragment LitGBufferPassFragment// -------------------------------------// Material Keywords#pragma shader_feature_local _NORMALMAP#pragma shader_feature_local_fragment _ALPHATEST_ON//#pragma shader_feature_local_fragment _ALPHAPREMULTIPLY_ON#pragma shader_feature_local_fragment _EMISSION#pragma shader_feature_local_fragment _METALLICSPECGLOSSMAP#pragma shader_feature_local_fragment _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A#pragma shader_feature_local_fragment _OCCLUSIONMAP#pragma shader_feature_local _PARALLAXMAP#pragma shader_feature_local _ _DETAIL_MULX2 _DETAIL_SCALED#pragma shader_feature_local_fragment _SPECULARHIGHLIGHTS_OFF#pragma shader_feature_local_fragment _ENVIRONMENTREFLECTIONS_OFF#pragma shader_feature_local_fragment _SPECULAR_SETUP#pragma shader_feature_local _RECEIVE_SHADOWS_OFF// -------------------------------------// Universal Pipeline keywords#pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN//#pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS//#pragma multi_compile _ _ADDITIONAL_LIGHT_SHADOWS#pragma multi_compile_fragment _ _REFLECTION_PROBE_BLENDING#pragma multi_compile_fragment _ _REFLECTION_PROBE_BOX_PROJECTION#pragma multi_compile_fragment _ _SHADOWS_SOFT _SHADOWS_SOFT_LOW _SHADOWS_SOFT_MEDIUM _SHADOWS_SOFT_HIGH#pragma multi_compile_fragment _ _DBUFFER_MRT1 _DBUFFER_MRT2 _DBUFFER_MRT3#pragma multi_compile_fragment _ _RENDER_PASS_ENABLED#include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/RenderingLayers.hlsl"// -------------------------------------// Unity defined keywords#pragma multi_compile _ LIGHTMAP_SHADOW_MIXING#pragma multi_compile _ SHADOWS_SHADOWMASK#pragma multi_compile _ DIRLIGHTMAP_COMBINED#pragma multi_compile _ LIGHTMAP_ON#pragma multi_compile _ DYNAMICLIGHTMAP_ON#pragma multi_compile_fragment _ LOD_FADE_CROSSFADE#pragma multi_compile_fragment _ _GBUFFER_NORMALS_OCT//--------------------------------------// GPU Instancing#pragma multi_compile_instancing#pragma instancing_options renderinglayer#include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DOTS.hlsl"// -------------------------------------// Includes#include "Packages/com.unity.render-pipelines.universal/Shaders/LitInput.hlsl"#include "Packages/com.unity.render-pipelines.universal/Shaders/LitGBufferPass.hlsl"ENDHLSL}Pass{Name "DepthOnly"Tags { "LightMode" = "DepthOnly" }// -------------------------------------// Render State CommandsZWrite OnColorMask RCull[_Cull]HLSLPROGRAM#pragma target 2.0// -------------------------------------// Shader Stages#pragma vertex DepthOnlyVertex#pragma fragment DepthOnlyFragment// -------------------------------------// Material Keywords#pragma shader_feature_local _ALPHATEST_ON#pragma shader_feature_local_fragment _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A// -------------------------------------// Unity defined keywords#pragma multi_compile_fragment _ LOD_FADE_CROSSFADE//--------------------------------------// GPU Instancing#pragma multi_compile_instancing#include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DOTS.hlsl"// -------------------------------------// Includes#include "Packages/com.unity.render-pipelines.universal/Shaders/LitInput.hlsl"#include "Packages/com.unity.render-pipelines.universal/Shaders/DepthOnlyPass.hlsl"ENDHLSL}// This pass is used when drawing to a _CameraNormalsTexture texturePass{Name "DepthNormals"Tags { "LightMode" = "DepthNormals" }// -------------------------------------// Render State CommandsZWrite OnCull[_Cull]HLSLPROGRAM#pragma target 2.0// -------------------------------------// Shader Stages#pragma vertex DepthNormalsVertex#pragma fragment DepthNormalsFragment// -------------------------------------// Material Keywords#pragma shader_feature_local _NORMALMAP#pragma shader_feature_local _PARALLAXMAP#pragma shader_feature_local _ _DETAIL_MULX2 _DETAIL_SCALED#pragma shader_feature_local_fragment _ALPHATEST_ON#pragma shader_feature_local_fragment _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A// -------------------------------------// Unity defined keywords#pragma multi_compile_fragment _ LOD_FADE_CROSSFADE// -------------------------------------// Universal Pipeline keywords#include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/RenderingLayers.hlsl"//--------------------------------------// GPU Instancing#pragma multi_compile_instancing#include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DOTS.hlsl"// -------------------------------------// Includes#include "Packages/com.unity.render-pipelines.universal/Shaders/LitInput.hlsl"#include "Packages/com.unity.render-pipelines.universal/Shaders/LitDepthNormalsPass.hlsl"ENDHLSL}// This pass it not used during regular rendering, only for lightmap baking.Pass{Name "Meta"Tags { "LightMode" = "Meta" }// -------------------------------------// Render State CommandsCull OffHLSLPROGRAM#pragma target 2.0// -------------------------------------// Shader Stages#pragma vertex UniversalVertexMeta#pragma fragment UniversalFragmentMetaLit// -------------------------------------// Material Keywords#pragma shader_feature_local_fragment _SPECULAR_SETUP#pragma shader_feature_local_fragment _EMISSION#pragma shader_feature_local_fragment _METALLICSPECGLOSSMAP#pragma shader_feature_local_fragment _ALPHATEST_ON#pragma shader_feature_local_fragment _ _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A#pragma shader_feature_local _ _DETAIL_MULX2 _DETAIL_SCALED#pragma shader_feature_local_fragment _SPECGLOSSMAP#pragma shader_feature EDITOR_VISUALIZATION// -------------------------------------// Includes#include "Packages/com.unity.render-pipelines.universal/Shaders/LitInput.hlsl"#include "Packages/com.unity.render-pipelines.universal/Shaders/LitMetaPass.hlsl"ENDHLSL}Pass{Name "Universal2D"Tags { "LightMode" = "Universal2D" }// -------------------------------------// Render State CommandsBlend[_SrcBlend][_DstBlend]ZWrite[_ZWrite]Cull[_Cull]HLSLPROGRAM#pragma target 2.0// -------------------------------------// Shader Stages#pragma vertex vert#pragma fragment frag// -------------------------------------// Material Keywords#pragma shader_feature_local_fragment _ALPHATEST_ON#pragma shader_feature_local_fragment _ALPHAPREMULTIPLY_ON#include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DOTS.hlsl"// -------------------------------------// Includes#include "Packages/com.unity.render-pipelines.universal/Shaders/LitInput.hlsl"#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/Universal2D.hlsl"ENDHLSL}}FallBack "Hidden/Universal Render Pipeline/FallbackError"
}
六、效果图
七、结语
有了以上的模板Shader,这样就可以在第一个Pass里随意自定义自己想要的效果,例如给Shader加一个外描边功能,给Shader加一个溶解功能等等