Files
test/Assets/ModelRenderer/Art/Shaders/CustomUnlitShader.shader
T
2025-10-25 12:27:22 +07:00

290 lines
9.1 KiB
Plaintext

Shader "BrewMonster/UnlitWithShadows"
{
Properties
{
_BaseMap ("Texture", 2D) = "white" {}
_Color ("Color", Color) = (1,1,1,1)
_ShadowStrength ("Shadow Strength", Range(0, 1)) = 0.5
[Toggle(_ALPHATEST_ON)] _AlphaClip("Alpha Clip", Float) = 0
_Cutoff("Alpha Cutoff", Range(0.0, 1.0)) = 0.5
// BlendMode options
[Enum(UnityEngine.Rendering.BlendMode)] _SrcBlend("Src Blend Mode", Float) = 1
[Enum(UnityEngine.Rendering.BlendMode)] _DstBlend("Dst Blend Mode", Float) = 0
[Enum(Off, 0, On, 1)] _ZWrite("Z Write", Float) = 1
// Surface options
[Enum(UnityEngine.Rendering.CullMode)] _Cull("Cull Mode", Float) = 2
[Toggle(_ALPHAMODULATE_ON)] _AlphaModulate("Alpha Modulate", Float) = 0
// Material type
[HideInInspector] _Surface("__surface", Float) = 0.0
}
// Helper to set render queue and render type based on alpha mode
CustomEditor "BrewMonsterUnlitShaderGUI"
SubShader
{
Tags
{
"RenderPipeline" = "UniversalPipeline"
"RenderType" = "Opaque"
"Queue" = "Geometry"
}
LOD 100
// Main pass
Pass
{
Name "ForwardLit"
Tags { "LightMode"="UniversalForward" }
Blend [_SrcBlend] [_DstBlend]
ZWrite [_ZWrite]
Cull [_Cull]
HLSLPROGRAM
#pragma vertex vert
#pragma fragment frag
// Shadows
#pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE
#pragma multi_compile _ _SHADOWS_SOFT
#pragma multi_compile _ _ADDITIONAL_LIGHT_SHADOWS
// Fog
#pragma multi_compile_fog
// Alpha features
#pragma shader_feature_local_fragment _ALPHATEST_ON
#pragma shader_feature_local_fragment _ALPHAMODULATE_ON
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
TEXTURE2D(_BaseMap);
SAMPLER(sampler_BaseMap);
CBUFFER_START(UnityPerMaterial)
float4 _BaseMap_ST;
half4 _Color;
half _ShadowStrength;
half _Cutoff;
CBUFFER_END
struct Attributes
{
float4 positionOS : POSITION;
float2 uv : TEXCOORD0;
float3 normalOS : NORMAL;
};
struct Varyings
{
float4 positionCS : SV_POSITION;
float2 uv : TEXCOORD0;
float3 positionWS : TEXCOORD1;
float3 normalWS : TEXCOORD2;
float fogCoord : TEXCOORD3;
};
Varyings vert(Attributes input)
{
Varyings output;
// Transform position
VertexPositionInputs vertexInput = GetVertexPositionInputs(input.positionOS.xyz);
output.positionCS = vertexInput.positionCS;
output.positionWS = vertexInput.positionWS;
// Transform normal
VertexNormalInputs normalInput = GetVertexNormalInputs(input.normalOS);
output.normalWS = normalInput.normalWS;
// UV
output.uv = TRANSFORM_TEX(input.uv, _BaseMap);
// Fog
output.fogCoord = ComputeFogFactor(vertexInput.positionCS.z);
return output;
}
half4 frag(Varyings input) : SV_Target
{
// Sample the texture
half4 mainTex = SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, input.uv);
half4 color = mainTex * _Color;
// Alpha test
#ifdef _ALPHATEST_ON
clip(color.a - _Cutoff);
#endif
// Alpha modulate mode (for special effects)
#ifdef _ALPHAMODULATE_ON
color.rgb *= color.a;
#endif
// Shadow calculation
float4 shadowCoord = TransformWorldToShadowCoord(input.positionWS);
Light mainLight = GetMainLight(shadowCoord);
half shadowAttenuation = mainLight.shadowAttenuation;
// Apply shadow
half shadow = lerp(1.0, shadowAttenuation, _ShadowStrength);
color.rgb *= shadow;
// Apply fog
color.rgb = MixFog(color.rgb, input.fogCoord);
return color;
}
ENDHLSL
}
// Shadow caster pass
Pass
{
Name "ShadowCaster"
Tags { "LightMode"="ShadowCaster" }
ZWrite On
ZTest LEqual
ColorMask 0
Cull [_Cull]
HLSLPROGRAM
#pragma vertex ShadowPassVertex
#pragma fragment ShadowPassFragment
// Alpha clipping for shadows
#pragma shader_feature_local_fragment _ALPHATEST_ON
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Shadows.hlsl"
TEXTURE2D(_BaseMap);
SAMPLER(sampler_BaseMap);
CBUFFER_START(UnityPerMaterial)
float4 _BaseMap_ST;
half4 _Color;
half _ShadowStrength;
half _Cutoff;
CBUFFER_END
struct Attributes
{
float4 positionOS : POSITION;
float3 normalOS : NORMAL;
float2 texcoord : TEXCOORD0;
};
struct Varyings
{
float4 positionCS : SV_POSITION;
float2 uv : TEXCOORD0;
};
float3 _LightDirection;
float4 GetShadowPositionHClip(Attributes input)
{
float3 positionWS = TransformObjectToWorld(input.positionOS.xyz);
float3 normalWS = TransformObjectToWorldNormal(input.normalOS);
float4 positionCS = TransformWorldToHClip(ApplyShadowBias(positionWS, normalWS, _LightDirection));
#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 input)
{
Varyings output;
output.positionCS = GetShadowPositionHClip(input);
output.uv = TRANSFORM_TEX(input.texcoord, _BaseMap);
return output;
}
half4 ShadowPassFragment(Varyings input) : SV_TARGET
{
#ifdef _ALPHATEST_ON
half4 mainTex = SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, input.uv);
half alpha = mainTex.a * _Color.a;
clip(alpha - _Cutoff);
#endif
return 0;
}
ENDHLSL
}
// Depth pass for receiving shadows
Pass
{
Name "DepthOnly"
Tags { "LightMode"="DepthOnly" }
ZWrite On
ColorMask 0
Cull [_Cull]
HLSLPROGRAM
#pragma vertex DepthOnlyVertex
#pragma fragment DepthOnlyFragment
// Alpha clipping for depth
#pragma shader_feature_local_fragment _ALPHATEST_ON
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
TEXTURE2D(_BaseMap);
SAMPLER(sampler_BaseMap);
CBUFFER_START(UnityPerMaterial)
float4 _BaseMap_ST;
half4 _Color;
half _Cutoff;
CBUFFER_END
struct Attributes
{
float4 position : POSITION;
float2 texcoord : TEXCOORD0;
};
struct Varyings
{
float4 positionCS : SV_POSITION;
float2 uv : TEXCOORD0;
};
Varyings DepthOnlyVertex(Attributes input)
{
Varyings output;
output.positionCS = TransformObjectToHClip(input.position.xyz);
output.uv = TRANSFORM_TEX(input.texcoord, _BaseMap);
return output;
}
half4 DepthOnlyFragment(Varyings input) : SV_TARGET
{
#ifdef _ALPHATEST_ON
half4 mainTex = SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, input.uv);
half alpha = mainTex.a * _Color.a;
clip(alpha - _Cutoff);
#endif
return 0;
}
ENDHLSL
}
}
FallBack "Universal Render Pipeline/Lit"
}