Created
October 17, 2022 19:57
-
-
Save D4KU/53dcf387a0ddb6a5066eb133ad8cb71f to your computer and use it in GitHub Desktop.
Unity Universal Render Pipeline shadow catcher shader
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Shader "Custom/ShadowCatcher" | |
| { | |
| Properties | |
| { | |
| // Specular vs Metallic workflow | |
| [HideInInspector] _WorkflowMode("WorkflowMode", Float) = 1.0 | |
| [MainColor] _BaseColor("Color", Color) = (0.5,0.5,0.5,1) | |
| [MainTexture] _BaseMap("Albedo", 2D) = "white" {} | |
| _Cutoff("Alpha Cutoff", Range(0.0, 1.0)) = 0.5 | |
| _Smoothness("Smoothness", Range(0.0, 1.0)) = 0.5 | |
| _GlossMapScale("Smoothness Scale", Range(0.0, 1.0)) = 1.0 | |
| _SmoothnessTextureChannel("Smoothness texture channel", Float) = 0 | |
| [Gamma] _Metallic("Metallic", Range(0.0, 1.0)) = 0.0 | |
| _MetallicGlossMap("Metallic", 2D) = "white" {} | |
| _SpecColor("Specular", Color) = (0.2, 0.2, 0.2) | |
| _SpecGlossMap("Specular", 2D) = "white" {} | |
| [ToggleOff] _SpecularHighlights("Specular Highlights", Float) = 1.0 | |
| [ToggleOff] _EnvironmentReflections("Environment Reflections", Float) = 1.0 | |
| _BumpScale("Scale", Float) = 1.0 | |
| _BumpMap("Normal Map", 2D) = "bump" {} | |
| _OcclusionStrength("Strength", Range(0.0, 1.0)) = 1.0 | |
| _OcclusionMap("Occlusion", 2D) = "white" {} | |
| [HDR] _EmissionColor("Color", Color) = (0,0,0) | |
| _EmissionMap("Emission", 2D) = "white" {} | |
| // Blending state | |
| [HideInInspector] _Surface("__surface", Float) = 0.0 | |
| [HideInInspector] _Blend("__blend", Float) = 0.0 | |
| [HideInInspector] _AlphaClip("__clip", Float) = 0.0 | |
| [HideInInspector] _SrcBlend("__src", Float) = 1.0 | |
| [HideInInspector] _DstBlend("__dst", Float) = 0.0 | |
| [HideInInspector] _ZWrite("__zw", Float) = 1.0 | |
| [HideInInspector] _Cull("__cull", Float) = 2.0 | |
| _ReceiveShadows("Receive Shadows", Float) = 1.0 | |
| // Editmode props | |
| [HideInInspector] _QueueOffset("Queue offset", Float) = 0.0 | |
| } | |
| SubShader | |
| { | |
| Tags{ "RenderType" = "TransparentCutout" "Queue"="AlphaTest" "RenderPipeline" = "UniversalRenderPipeline" "IgnoreProjector" = "True"} | |
| LOD 300 | |
| Pass | |
| { | |
| Name "StandardLit" | |
| Tags{"LightMode" = "UniversalForward"} | |
| Blend[_SrcBlend][_DstBlend] | |
| ZWrite[_ZWrite] | |
| Cull[_Cull] | |
| HLSLPROGRAM | |
| #pragma prefer_hlslcc gles | |
| #pragma exclude_renderers d3d11_9x | |
| #pragma target 2.0 | |
| // 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 Render Pipeline keywords | |
| #pragma multi_compile _ _MAIN_LIGHT_SHADOWS | |
| #pragma multi_compile _ _MAIN_LIGHT_SHADOWS_CASCADE | |
| #pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS | |
| #pragma multi_compile_fragment _ _ADDITIONAL_LIGHT_SHADOWS | |
| #pragma multi_compile_fragment _ _SHADOWS_SOFT | |
| #pragma multi_compile_fragment _ _SCREEN_SPACE_OCCLUSION | |
| #pragma multi_compile _ LIGHTMAP_SHADOW_MIXING | |
| #pragma multi_compile _ SHADOWS_SHADOWMASK | |
| // Unity defined keywords | |
| #pragma multi_compile _ DIRLIGHTMAP_COMBINED | |
| #pragma multi_compile _ LIGHTMAP_ON | |
| #pragma multi_compile_fog | |
| // GPU Instancing | |
| #pragma multi_compile_instancing | |
| #pragma vertex LitPassVertex | |
| #pragma fragment LitPassFragment | |
| #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/Shaders/LitInput.hlsl" | |
| struct Attributes | |
| { | |
| float4 positionOS : POSITION; | |
| float3 normalOS : NORMAL; | |
| float4 tangentOS : TANGENT; | |
| float2 uv : TEXCOORD0; | |
| float2 uvLM : TEXCOORD1; | |
| UNITY_VERTEX_INPUT_INSTANCE_ID | |
| }; | |
| struct Varyings | |
| { | |
| float2 uv : TEXCOORD0; | |
| float2 uvLM : TEXCOORD1; | |
| float4 positionWSAndFogFactor : TEXCOORD2; // xyz: positionWS, w: vertex fog factor | |
| half3 normalWS : TEXCOORD3; | |
| #if _NORMALMAP | |
| half3 tangentWS : TEXCOORD4; | |
| half3 bitangentWS : TEXCOORD5; | |
| #endif | |
| #ifdef REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR | |
| float4 shadowCoord : TEXCOORD6; // compute shadow coord per-vertex for the main light | |
| #endif | |
| float4 positionCS : SV_POSITION; | |
| }; | |
| Varyings LitPassVertex(Attributes input) | |
| { | |
| Varyings output; | |
| VertexPositionInputs vertexInput = GetVertexPositionInputs(input.positionOS.xyz); | |
| VertexNormalInputs vertexNormalInput = GetVertexNormalInputs(input.normalOS, input.tangentOS); | |
| float fogFactor = ComputeFogFactor(vertexInput.positionCS.z); | |
| output.uv = TRANSFORM_TEX(input.uv, _BaseMap); | |
| output.uvLM = input.uvLM.xy * unity_LightmapST.xy + unity_LightmapST.zw; | |
| output.positionWSAndFogFactor = float4(vertexInput.positionWS, fogFactor); | |
| output.normalWS = vertexNormalInput.normalWS; | |
| #ifdef _NORMALMAP | |
| output.tangentWS = vertexNormalInput.tangentWS; | |
| output.bitangentWS = vertexNormalInput.bitangentWS; | |
| #endif | |
| #ifdef REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR | |
| output.shadowCoord = GetShadowCoord(vertexInput); | |
| #endif | |
| output.positionCS = vertexInput.positionCS; | |
| return output; | |
| } | |
| half4 LitPassFragment(Varyings input) : SV_Target | |
| { | |
| SurfaceData surfaceData; | |
| InitializeStandardLitSurfaceData(input.uv, surfaceData); | |
| #if _NORMALMAP | |
| half3 normalWS = TransformTangentToWorld(surfaceData.normalTS, | |
| half3x3(input.tangentWS, input.bitangentWS, input.normalWS)); | |
| #else | |
| half3 normalWS = input.normalWS; | |
| #endif | |
| normalWS = normalize(normalWS); | |
| #ifdef LIGHTMAP_ON | |
| half3 bakedGI = SampleLightmap(input.uvLM, normalWS); | |
| #else | |
| half3 bakedGI = SampleSH(normalWS); | |
| #endif | |
| float3 positionWS = input.positionWSAndFogFactor.xyz; | |
| half3 viewDirectionWS = SafeNormalize(GetCameraPositionWS() - positionWS); | |
| BRDFData brdfData; | |
| InitializeBRDFData(surfaceData.albedo, surfaceData.metallic, surfaceData.specular, surfaceData.smoothness, surfaceData.alpha, brdfData); | |
| #ifdef _MAIN_LIGHT_SHADOWS | |
| float4 shadowCoord; | |
| #ifdef REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR | |
| shadowCoord = input.shadowCoord; | |
| #else | |
| #ifdef MAIN_LIGHT_CALCULATE_SHADOWS | |
| shadowCoord = TransformWorldToShadowCoord(positionWS); | |
| #else | |
| shadowCoord = float4(0, 0, 0, 0); | |
| #endif | |
| #endif | |
| Light mainLight = GetMainLight(shadowCoord); | |
| #else | |
| Light mainLight = GetMainLight(); | |
| #endif | |
| half3 color = GlobalIllumination(brdfData, bakedGI, surfaceData.occlusion, normalWS, viewDirectionWS); | |
| color += LightingPhysicallyBased(brdfData, mainLight, normalWS, viewDirectionWS); | |
| half alpha = mainLight.shadowAttenuation; | |
| #ifdef _ADDITIONAL_LIGHTS | |
| int additionalLightsCount = GetAdditionalLightsCount(); | |
| for (int i = 0; i < additionalLightsCount; ++i) | |
| { | |
| Light light = GetAdditionalLight(i, positionWS); | |
| color += LightingPhysicallyBased(brdfData, light, normalWS, viewDirectionWS); | |
| alpha *= light.shadowAttenuation; | |
| } | |
| #endif | |
| color += surfaceData.emission; | |
| float fogFactor = input.positionWSAndFogFactor.w; | |
| color = MixFog(color, fogFactor); | |
| alpha = (1 - alpha) * surfaceData.alpha; | |
| AlphaDiscard(alpha, _Cutoff); | |
| return half4(color, alpha); | |
| } | |
| ENDHLSL | |
| } | |
| // Used for rendering shadowmaps | |
| UsePass "Universal Render Pipeline/Lit/ShadowCaster" | |
| // Used for depth prepass | |
| // If shadows cascade are enabled we need to perform a depth prepass. | |
| // We also need to use a depth prepass in some cases camera require depth texture | |
| // (e.g, MSAA is enabled and we can't resolve with Texture2DMS | |
| UsePass "Universal Render Pipeline/Lit/DepthOnly" | |
| // Used for Baking GI. This pass is stripped from build. | |
| UsePass "Universal Render Pipeline/Lit/Meta" | |
| } | |
| // Uses a custom shader GUI to display settings. Re-use the same from Lit shader as they have the | |
| // same properties. | |
| CustomEditor "UnityEditor.Rendering.Universal.ShaderGUI.LitShader" | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment