Skip to content

Instantly share code, notes, and snippets.

@gameshalico
Created January 2, 2024 12:11
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gameshalico/27b09a2476a72737e6a8a1b090259f9c to your computer and use it in GitHub Desktop.
Save gameshalico/27b09a2476a72737e6a8a1b090259f9c to your computer and use it in GitHub Desktop.
Shader "Universal Render Pipeline/2D/Sprite-Lit-3D-Shadow-Cutoff"
{
Properties
{
_MainTex ("Sprite Texture", 2D) = "white" {}
_Cutoff ("Shadow Cutoff", Range(0,1)) = 0.5
// Legacy properties. They're here so that materials using this shader can gracefully fallback to the legacy sprite shader.
[HideInInspector] _Color ("Tint", Color) = (1,1,1,1)
[HideInInspector] PixelSnap ("Pixel snap", Float) = 0
[HideInInspector] _RendererColor ("RendererColor", Color) = (1,1,1,1)
[HideInInspector] _AlphaTex ("External Alpha", 2D) = "white" {}
[HideInInspector] _EnableExternalAlpha ("Enable External Alpha", Float) = 0
}
SubShader
{
Tags {"Queue" = "Transparent" "RenderType" = "Transparent" "RenderPipeline" = "UniversalPipeline" }
Blend SrcAlpha OneMinusSrcAlpha
Cull Off
ZWrite Off
Pass
{
Tags { "LightMode" = "Universal2D" }
HLSLPROGRAM
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/2D/Include/Core2D.hlsl"
#if defined(DEBUG_DISPLAY)
#include "Packages/com.unity.render-pipelines.universal/Shaders/2D/Include/InputData2D.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/2D/Include/SurfaceData2D.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Debug/Debugging2D.hlsl"
#endif
#pragma vertex UnlitVertex
#pragma fragment UnlitFragment
#pragma multi_compile _ DEBUG_DISPLAY SKINNED_SPRITE
struct Attributes
{
float3 positionOS : POSITION;
float4 color : COLOR;
float2 uv : TEXCOORD0;
UNITY_SKINNED_VERTEX_INPUTS
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct Varyings
{
float4 positionCS : SV_POSITION;
half4 color : COLOR;
float2 uv : TEXCOORD0;
#if defined(DEBUG_DISPLAY)
float3 positionWS : TEXCOORD2;
#endif
UNITY_VERTEX_OUTPUT_STEREO
};
TEXTURE2D(_MainTex);
SAMPLER(sampler_MainTex);
// NOTE: Do not ifdef the properties here as SRP batcher can not handle different layouts.
CBUFFER_START(UnityPerMaterial)
half4 _MainTex_ST;
half4 _Color;
CBUFFER_END
Varyings UnlitVertex(Attributes v)
{
Varyings o = (Varyings)0;
UNITY_SETUP_INSTANCE_ID(v);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
UNITY_SKINNED_VERTEX_COMPUTE(v);
v.positionOS = UnityFlipSprite(v.positionOS, unity_SpriteProps.xy);
o.positionCS = TransformObjectToHClip(v.positionOS);
#if defined(DEBUG_DISPLAY)
o.positionWS = TransformObjectToWorld(v.positionOS);
#endif
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
o.color = v.color * _Color * unity_SpriteColor;
return o;
}
half4 UnlitFragment(Varyings i) : SV_Target
{
float4 mainTex = i.color * SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.uv);
#if defined(DEBUG_DISPLAY)
SurfaceData2D surfaceData;
InputData2D inputData;
half4 debugColor = 0;
InitializeSurfaceData(mainTex.rgb, mainTex.a, surfaceData);
InitializeInputData(i.uv, inputData);
SETUP_DEBUG_DATA_2D(inputData, i.positionWS);
if(CanDebugOverrideOutputColor(surfaceData, inputData, debugColor))
{
return debugColor;
}
#endif
return mainTex;
}
ENDHLSL
}
Pass
{
Tags { "LightMode" = "UniversalForward" "Queue"="Transparent" "RenderType"="Transparent"}
HLSLPROGRAM
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/2D/Include/Core2D.hlsl"
#if defined(DEBUG_DISPLAY)
#include "Packages/com.unity.render-pipelines.universal/Shaders/2D/Include/InputData2D.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/2D/Include/SurfaceData2D.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Debug/Debugging2D.hlsl"
#endif
#pragma vertex UnlitVertex
#pragma fragment UnlitFragment
#pragma multi_compile_fragment _ DEBUG_DISPLAY
struct Attributes
{
float3 positionOS : POSITION;
float4 color : COLOR;
float2 uv : TEXCOORD0;
UNITY_SKINNED_VERTEX_INPUTS
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct Varyings
{
float4 positionCS : SV_POSITION;
float4 color : COLOR;
float2 uv : TEXCOORD0;
#if defined(DEBUG_DISPLAY)
float3 positionWS : TEXCOORD2;
#endif
UNITY_VERTEX_OUTPUT_STEREO
};
TEXTURE2D(_MainTex);
SAMPLER(sampler_MainTex);
// NOTE: Do not ifdef the properties here as SRP batcher can not handle different layouts.
CBUFFER_START( UnityPerMaterial )
half4 _MainTex_ST;
half4 _Color;
CBUFFER_END
Varyings UnlitVertex(Attributes attributes)
{
Varyings o = (Varyings)0;
UNITY_SETUP_INSTANCE_ID(attributes);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
UNITY_SKINNED_VERTEX_COMPUTE(v);
attributes.positionOS = UnityFlipSprite(attributes.positionOS, unity_SpriteProps.xy);
o.positionCS = TransformObjectToHClip(attributes.positionOS);
#if defined(DEBUG_DISPLAY)
o.positionWS = TransformObjectToWorld(attributes.positionOS);
#endif
o.uv = TRANSFORM_TEX(attributes.uv, _MainTex);
o.color = attributes.color * _Color * unity_SpriteColor;
return o;
}
float4 UnlitFragment(Varyings i) : SV_Target
{
float4 mainTex = i.color * SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.uv);
#if defined(DEBUG_DISPLAY)
SurfaceData2D surfaceData;
InputData2D inputData;
half4 debugColor = 0;
InitializeSurfaceData(mainTex.rgb, mainTex.a, surfaceData);
InitializeInputData(i.uv, inputData);
SETUP_DEBUG_DATA_2D(inputData, i.positionWS);
if(CanDebugOverrideOutputColor(surfaceData, inputData, debugColor))
{
return debugColor;
}
#endif
return mainTex;
}
ENDHLSL
}
Pass
{
Tags { "LightMode" = "ShadowCaster" }
ZWrite On
ZTest LEqual
ColorMask 0
HLSLPROGRAM
#pragma target 2.0
// -------------------------------------
// Shader Stages
#pragma vertex ShadowPassVertex
#pragma fragment ShadowPassFragment
// -------------------------------------
// Material Keywords
#pragma shader_feature_local_fragment _ALPHATEST_ON
//--------------------------------------
// GPU Instancing
#pragma multi_compile_instancing
#include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DOTS.hlsl"
// -------------------------------------
// Universal Pipeline keywords
// -------------------------------------
// 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/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/CommonMaterial.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Shadows.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/2D/Include/Core2D.hlsl"
// Shadow Casting Light geometric parameters. These variables are used when applying the shadow Normal Bias and are set by UnityEngine.Rendering.Universal.ShadowUtils.SetupShadowCasterConstantBuffer in com.unity.render-pipelines.universal/Runtime/ShadowUtils.cs
// For Directional lights, _LightDirection is used when applying shadow Normal Bias.
// For Spot lights and Point lights, _LightPosition is used to compute the actual light direction because it is different at each shadow caster geometry vertex.
float3 _LightDirection;
float3 _LightPosition;
struct Attributes
{
float3 positionOS : POSITION;
float3 normalOS : NORMAL;
float4 color : COLOR;
float2 uv : TEXCOORD0;
UNITY_SKINNED_VERTEX_INPUTS
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct Varyings
{
float4 positionCS : SV_POSITION;
half4 color : COLOR;
float2 uv : TEXCOORD0;
UNITY_VERTEX_OUTPUT_STEREO
};
TEXTURE2D(_MainTex);
SAMPLER(sampler_MainTex);
// NOTE: Do not ifdef the properties here as SRP batcher can not handle different layouts.
CBUFFER_START( UnityPerMaterial )
half4 _MainTex_ST;
half4 _Color;
half _Cutoff;
CBUFFER_END
float4 GetShadowPositionHClip(Attributes input)
{
float3 positionWS = TransformObjectToWorld(input.positionOS.xyz);
float3 normalWS = TransformObjectToWorldNormal(input.normalOS);
#if _CASTING_PUNCTUAL_LIGHT_SHADOW
float3 lightDirectionWS = normalize(_LightPosition - positionWS);
#else
float3 lightDirectionWS = _LightDirection;
#endif
float4 positionCS = TransformWorldToHClip(ApplyShadowBias(positionWS, normalWS, lightDirectionWS));
#if UNITY_REVERSED_Z
positionCS.z = min(positionCS.z, UNITY_NEAR_CLIP_VALUE);
#else
positionCS.z = max(positionCS.z, UNITY_NEAR_CLIP_VALUE);
#endif
return positionCS;
}
Varyings ShadowPassVertex(Attributes attributes)
{
Varyings o = (Varyings)0;
UNITY_SETUP_INSTANCE_ID(attributes);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
UNITY_SKINNED_VERTEX_COMPUTE(v);
attributes.positionOS = UnityFlipSprite(attributes.positionOS, unity_SpriteProps.xy);
o.positionCS = GetShadowPositionHClip(attributes);
o.uv = TRANSFORM_TEX(attributes.uv, _MainTex);
o.color = attributes.color * _Color * unity_SpriteColor;
return o;
}
half4 ShadowPassFragment(Varyings i) : SV_TARGET
{
half alpha = (i.color * SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.uv)).a;
half clippedAlpha = (alpha >= _Cutoff) ? float(alpha) : 0.0;
#ifdef _ALPHATEST_ON
half alphaToCoverageAlpha = SharpenAlpha(alpha, _Cutoff);
alpha = IsAlphaToMaskAvailable() ? alphaToCoverageAlpha : clippedAlpha;
#else
alpha = clippedAlpha;
#endif
clip(alpha - 0.0001);
return 0;
}
ENDHLSL
}
}
Fallback "Sprites/Default"
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment