173 lines
6.5 KiB
Plaintext
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"
|
|
}
|