// Example Shader for Universal RP // Written by @Cyanilux // https://www.cyanilux.com/tutorials/urp-shader-code Shader "Cyanilux/URPTemplates/Unlit+ShaderExample" { Properties { _BaseMap ("Example Texture", 2D) = "white" {} _BaseColor ("Example Colour", Color) = (0, 0.66, 0.73, 1) [Toggle(_ALPHATEST_ON)] _AlphaTestToggle ("Alpha Clipping", Float) = 0 _Cutoff ("Alpha Cutoff", Float) = 0.5 [HideInInspector] _Cull("__cull", Float) = 2.0 } SubShader { Tags { "RenderPipeline"="UniversalPipeline" "RenderType"="Opaque" "Queue"="Geometry" "UniversalMaterialType" = "Lit" "IgnoreProjector" = "True" } HLSLINCLUDE #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" CBUFFER_START(UnityPerMaterial) float4 _BaseMap_ST; float4 _BaseColor; float _Cutoff; CBUFFER_END ENDHLSL Pass { Name "Unlit" //Tags { "LightMode"="SRPDefaultUnlit" } // (is default anyway) HLSLPROGRAM #pragma vertex UnlitPassVertex #pragma fragment UnlitPassFragment // Material Keywords #pragma shader_feature _ALPHATEST_ON // Structs struct Attributes { float4 positionOS : POSITION; float2 uv : TEXCOORD0; float4 color : COLOR; }; struct Varyings { float4 positionCS : SV_POSITION; float2 uv : TEXCOORD0; float4 color : COLOR; }; // Textures, Samplers & Global Properties TEXTURE2D(_BaseMap); SAMPLER(sampler_BaseMap); // Vertex Shader Varyings UnlitPassVertex(Attributes IN) { Varyings OUT; VertexPositionInputs positionInputs = GetVertexPositionInputs(IN.positionOS.xyz); OUT.positionCS = positionInputs.positionCS; // Or : //OUT.positionCS = TransformObjectToHClip(IN.positionOS.xyz); OUT.uv = TRANSFORM_TEX(IN.uv, _BaseMap); OUT.color = IN.color; return OUT; } // Fragment Shader half4 UnlitPassFragment(Varyings IN) : SV_Target { half4 baseMap = SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, IN.uv); #ifdef _ALPHATEST_ON // Alpha Clipping clip(baseMap.a - _Cutoff); #endif return baseMap * _BaseColor * IN.color; } ENDHLSL } // UsePass "Universal Render Pipeline/Lit/ShadowCaster" // UsePass "Universal Render Pipeline/Lit/DepthOnly" // Would be nice if we could just use the passes from existing shaders, // However this breaks SRP Batcher compatibility. Instead, we should define them : // ShadowCaster, for casting shadows Pass { Name "ShadowCaster" Tags { "LightMode"="ShadowCaster" } ZWrite On ZTest LEqual ColorMask 0 Cull[_Cull] HLSLPROGRAM #pragma vertex ShadowPassVertex #pragma fragment ShadowPassFragment // Material Keywords #pragma shader_feature _ALPHATEST_ON #pragma shader_feature _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A // GPU Instancing #pragma multi_compile_instancing //#pragma multi_compile _ DOTS_INSTANCING_ON // Universal Pipeline Keywords // (v11+) This is used during shadow map generation to differentiate between directional and punctual (point/spot) light shadows, as they use different formulas to apply Normal Bias #pragma multi_compile_vertex _ _CASTING_PUNCTUAL_LIGHT_SHADOW #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/CommonMaterial.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceInput.hlsl" #include "Packages/com.unity.render-pipelines.universal/Shaders/ShadowCasterPass.hlsl" // Note if we do any vertex displacement, we'll need to change the vertex function. e.g. : /* #pragma vertex DisplacedShadowPassVertex (instead of ShadowPassVertex above) Varyings DisplacedShadowPassVertex(Attributes input) { Varyings output = (Varyings)0; UNITY_SETUP_INSTANCE_ID(input); // Example Displacement input.positionOS += float4(0, _SinTime.y, 0, 0); output.uv = TRANSFORM_TEX(input.texcoord, _BaseMap); output.positionCS = GetShadowPositionHClip(input); return output; } */ ENDHLSL } // DepthOnly, used for Camera Depth Texture (if cannot copy depth buffer instead, and the DepthNormals below isn't used) Pass { Name "DepthOnly" Tags { "LightMode"="DepthOnly" } ColorMask 0 ZWrite On ZTest LEqual HLSLPROGRAM #pragma vertex DepthOnlyVertex #pragma fragment DepthOnlyFragment // Material Keywords #pragma shader_feature _ALPHATEST_ON #pragma shader_feature _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A // GPU Instancing #pragma multi_compile_instancing //#pragma multi_compile _ DOTS_INSTANCING_ON #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/CommonMaterial.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceInput.hlsl" #include "Packages/com.unity.render-pipelines.universal/Shaders/DepthOnlyPass.hlsl" // Note if we do any vertex displacement, we'll need to change the vertex function. e.g. : /* #pragma vertex DisplacedDepthOnlyVertex (instead of DepthOnlyVertex above) Varyings DisplacedDepthOnlyVertex(Attributes input) { Varyings output = (Varyings)0; UNITY_SETUP_INSTANCE_ID(input); UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output); // Example Displacement input.positionOS += float4(0, _SinTime.y, 0, 0); output.uv = TRANSFORM_TEX(input.texcoord, _BaseMap); output.positionCS = TransformObjectToHClip(input.position.xyz); return output; } */ ENDHLSL } // DepthNormals, used for SSAO & other custom renderer features that request it Pass { Name "DepthNormals" Tags { "LightMode"="DepthNormals" } ZWrite On ZTest LEqual HLSLPROGRAM #pragma vertex DepthNormalsVertex #pragma fragment DepthNormalsFragment // Material Keywords #pragma shader_feature_local _NORMALMAP #pragma shader_feature _ALPHATEST_ON #pragma shader_feature _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A // GPU Instancing #pragma multi_compile_instancing //#pragma multi_compile _ DOTS_INSTANCING_ON #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/CommonMaterial.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceInput.hlsl" #include "Packages/com.unity.render-pipelines.universal/Shaders/DepthNormalsPass.hlsl" // Note if we do any vertex displacement, we'll need to change the vertex function. e.g. : /* #pragma vertex DisplacedDepthNormalsVertex (instead of DepthNormalsVertex above) Varyings DisplacedDepthNormalsVertex(Attributes input) { Varyings output = (Varyings)0; UNITY_SETUP_INSTANCE_ID(input); UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output); // Example Displacement input.positionOS += float4(0, _SinTime.y, 0, 0); output.uv = TRANSFORM_TEX(input.texcoord, _BaseMap); output.positionCS = TransformObjectToHClip(input.position.xyz); VertexNormalInputs normalInput = GetVertexNormalInputs(input.normal, input.tangentOS); output.normalWS = NormalizeNormalPerVertex(normalInput.normalWS); return output; } */ ENDHLSL } } }