NLDClient-yudde/ProjectNLD/Assets/Code/Shaders/Scene/NLD_Scene_FogSheet.shader

173 lines
6.5 KiB
Plaintext

Shader "NLD_URP/NLD_Scene_FogSheet"
{
Properties
{
[Header(Base Settings)]
_MainTex ("Fog Texture", 2D) = "white" {}
_Color("Tint Color", Color) = (0.8, 0.9, 1.0, 0.5)
_AlphaMultiplier("Alpha Multiplier", Range(0, 5)) = 1.0
[Header(Animation)]
_ScrollSpeed("Scroll Speed (XY)", Vector) = (0.1, 0.05, 0, 0)
_NoiseScale("Noise Scale", Float) = 1.0
[Header(Soft Particles)]
[Toggle(_SOFTPARTICLES_ON)] _SoftParticles("Soft Particles Enabled", Float) = 0.0
_SoftParticleFade("Soft Particle Intensity", Range(0.01, 10)) = 1.0
[Header(Vertical Gradient)]
[Toggle(_INVERT_VERTICAL_GRADIENT)] _InvertVerticalGradient("Invert Vertical Gradient", Float) = 0.0
_GradientBottomStart("Gradient Bottom Start (Invisible)", Range(0, 1)) = 0.0
_GradientBottom("Gradient Bottom End (Opaque)", Range(0, 1)) = 0.2
_GradientTop("Gradient Top Start (Opaque)", Range(0, 1)) = 0.8
_GradientTopEnd("Gradient Top End (Invisible)", Range(0, 1)) = 1.0
_GradientPower("Gradient Power", Float) = 1.0
}
SubShader
{
Tags
{
"RenderType" = "Transparent"
"RenderPipeline" = "UniversalPipeline"
"Queue" = "Transparent"
"IgnoreProjector" = "True"
}
Pass
{
Name "ForwardLit"
Tags { "LightMode" = "UniversalForward" }
Blend SrcAlpha OneMinusSrcAlpha
ZWrite Off
Cull Off
HLSLPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma shader_feature_local _INVERT_VERTICAL_GRADIENT
#pragma shader_feature_local _SOFTPARTICLES_ON
#pragma multi_compile_fog
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareDepthTexture.hlsl"
struct Attributes
{
float4 positionOS : POSITION;
float2 uv : TEXCOORD0;
half4 color : COLOR; // Use half for color
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct Varyings
{
float4 positionCS : SV_POSITION;
half4 color : TEXCOORD0; // Color low precision ok
half fogFactor : TEXCOORD1;
// xy: Original UV (for gradient), zw: Scrolled UV (for texture)
float4 uvAndScroll : TEXCOORD2;
#if defined(_SOFTPARTICLES_ON)
float4 screenPos : TEXCOORD3;
#endif
UNITY_VERTEX_OUTPUT_STEREO
};
CBUFFER_START(UnityPerMaterial)
float4 _MainTex_ST;
half4 _Color;
float4 _ScrollSpeed; // Time is high precision
half _SoftParticleFade;
float _NoiseScale;
half _AlphaMultiplier;
half _GradientTop;
half _GradientTopEnd;
half _GradientBottom;
half _GradientBottomStart;
// Power removed for optimization (linear or smoothstep is enough)
CBUFFER_END
TEXTURE2D(_MainTex);
SAMPLER(sampler_MainTex);
Varyings vert(Attributes input)
{
Varyings output = (Varyings)0;
UNITY_SETUP_INSTANCE_ID(input);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
float3 positionWS = TransformObjectToWorld(input.positionOS.xyz);
output.positionCS = TransformWorldToHClip(positionWS);
#if defined(_SOFTPARTICLES_ON)
output.screenPos = ComputeScreenPos(output.positionCS);
#endif
float2 rawUV = TRANSFORM_TEX(input.uv, _MainTex);
output.uvAndScroll.xy = rawUV;
// Calculate Scrolling in Vertex Shader to save ALUs in Pixel Shader
output.uvAndScroll.zw = rawUV * _NoiseScale + _Time.y * _ScrollSpeed.xy;
output.color = input.color;
output.fogFactor = ComputeFogFactor(output.positionCS.z);
return output;
}
half4 frag(Varyings input) : SV_Target
{
half4 texColor = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, input.uvAndScroll.zw);
half v = input.uvAndScroll.y;
#if defined(_INVERT_VERTICAL_GRADIENT)
v = 1.0h - v;
#endif
half bottomDenom = _GradientBottom - _GradientBottomStart;
half topDenom = _GradientTopEnd - _GradientTop;
// Calculate Bottom Fade (0 -> 1)
half fadeBottom = saturate((v - _GradientBottomStart) / (bottomDenom + 0.0001h));
// Calculate Top Fade (1 -> 0)
half fadeTop = saturate((_GradientTopEnd - v) / (topDenom + 0.0001h));
half alphaFactor = fadeBottom * fadeTop * _AlphaMultiplier;
#if defined(_SOFTPARTICLES_ON)
// Soft Particles Logic - Cross Platform Compatible
// Normalize screen position for depth sampling
float2 screenUV = input.screenPos.xy / input.screenPos.w;
// Sample scene depth
float rawDepth = SampleSceneDepth(screenUV);
// Convert to linear eye depth - handles both reversed Z (DX/Vulkan) and standard Z (OpenGL ES)
float sceneDepth = LinearEyeDepth(rawDepth, _ZBufferParams);
// Particle depth is already in linear eye space (clip space w component)
float partDepth = input.screenPos.w;
// Calculate soft fade
half softFade = saturate((sceneDepth - partDepth) * _SoftParticleFade);
alphaFactor *= softFade;
#endif
half4 finalColor = texColor * _Color * input.color;
finalColor.a *= alphaFactor;
// Apply Fog
finalColor.rgb = MixFog(finalColor.rgb, input.fogFactor);
return finalColor;
}
ENDHLSL
}
}
FallBack "Hidden/Universal Render Pipeline/FallbackError"
}