164 lines
5.0 KiB
HLSL

//--------------------------------------------------------------------------------------------------------------------------------
// Cartoon FX
// (c) 2012-2020 Jean Moreno
//--------------------------------------------------------------------------------------------------------------------------------
// Change this value if you want to globally scale the HDR effects
#define GLOBAL_HDR_MULTIPLIER 1
#if defined(CFXR_URP)
float LinearEyeDepthURP(float depth, float4 zBufferParam)
{
return 1.0 / (zBufferParam.z * depth + zBufferParam.w);
}
float SoftParticles(float near, float far, float4 projection)
{
float fade = 1;
if (near > 0.0 || far > 0.0)
{
float sceneZ = LinearEyeDepthURP(SAMPLE_DEPTH_TEXTURE_PROJ(_CameraDepthTexture, UNITY_PROJ_COORD(projection)).r, _ZBufferParams);
float thisZ = LinearEyeDepthURP(projection.z / projection.w, _ZBufferParams);
fade = saturate (far * ((sceneZ - near) - thisZ));
}
return 1.0;
}
#else
float SoftParticles(float near, float far, float4 projection)
{
float sceneZ = LinearEyeDepth (SAMPLE_DEPTH_TEXTURE_PROJ(_CameraDepthTexture, UNITY_PROJ_COORD(projection))); \
float fade = saturate (far * ((sceneZ - near) - projection.z)); \
return fade;
}
#endif
float LinearToGammaSpaceApprox(float value)
{
return max(1.055h * pow(value, 0.416666667h) - 0.055h, 0.h);
}
//Macros
// Project Position
#if (defined(SOFTPARTICLES_ON) && defined(_FADING_ON))
#define vertProjPos(o, clipPos) \
o.projPos = ComputeScreenPos(clipPos); \
COMPUTE_EYEDEPTH(o.projPos.z);
#else
#define vertProjPos(o, clipPos)
#endif
// Soft Particles
#if defined(SOFTPARTICLES_ON) && defined(_FADING_ON)
#define fragSoftParticlesFade(i, color) \
color *= SoftParticles(_SoftParticlesFadeDistanceNear, _SoftParticlesFadeDistanceFar, i.projPos);
#else
#define fragSoftParticlesFade(i, color)
#endif
// Edge fade (note: particle meshes are already in world space)
#if defined(_CFXR_EDGE_FADING)
#define vertEdgeFade(v, color) \
float3 viewDir = UnityWorldSpaceViewDir(v.vertex); \
float ndv = abs(dot(normalize(viewDir), v.normal.xyz)); \
color *= saturate(pow(ndv, _EdgeFadePow));
#else
#define vertEdgeFade(v, color)
#endif
// Fog
#if _ALPHABLEND_ON
#define applyFog(i, color, alpha) UNITY_APPLY_FOG_COLOR(i.fogCoord, color, unity_FogColor);
#elif _ALPHAPREMULTIPLY_ON
#define applyFog(i, color, alpha) UNITY_APPLY_FOG_COLOR(i.fogCoord, color, alpha * unity_FogColor);
#elif _CFXR_ADDITIVE
#define applyFog(i, color, alpha) UNITY_APPLY_FOG_COLOR(i.fogCoord, color, half4(0, 0, 0, 0));
#elif _ALPHAMODULATE_ON
#define applyFog(i, color, alpha) UNITY_APPLY_FOG_COLOR(i.fogCoord, color, half4(1, 1, 1, 1));
#else
#define applyFog(i, color, alpha) UNITY_APPLY_FOG_COLOR(i.fogCoord, color, unity_FogColor);
#endif
// Vertex program
#if PASS_SHADOW_CASTER
void vert(appdata v, v2f_shadowCaster o, out float4 opos)
#else
v2f vert(appdata v, v2f o)
#endif
{
UNITY_TRANSFER_FOG(o, o.pos);
vertProjPos(o, o.pos);
vertEdgeFade(v, o.color.a);
#if PASS_SHADOW_CASTER
TRANSFER_SHADOW_CASTER_NOPOS(o, opos);
#else
return o;
#endif
}
// Fragment program
#if PASS_SHADOW_CASTER
float4 frag(v2f_shadowCaster i, UNITY_VPOS_TYPE vpos, half3 particleColor, half particleAlpha, half dissolve, half dissolveTime) : SV_Target
#else
half4 frag(v2f i, half3 particleColor, half particleAlpha, half dissolve, half dissolveTime) : SV_Target
#endif
{
//Blending
#if _ALPHAPREMULTIPLY_ON
particleColor *= particleAlpha;
#endif
#if _ALPHAMODULATE_ON
particleColor.rgb = lerp(float3(1,1,1), particleColor.rgb, particleAlpha);
#endif
#if _CFXR_DISSOLVE
// Dissolve
half time = lerp(-_DissolveSmooth, 1+_DissolveSmooth, dissolveTime);
particleAlpha *= smoothstep(dissolve - _DissolveSmooth, dissolve + _DissolveSmooth, time);
#endif
#if _ALPHATEST_ON
clip(particleAlpha - _Cutoff);
#endif
// Fog & Soft Particles
applyFog(i, particleColor, particleAlpha);
fragSoftParticlesFade(i, particleAlpha);
// Prevent alpha from exceeding 1
particleAlpha = min(particleAlpha, 1.0);
#if !PASS_SHADOW_CASTER
return float4(particleColor, particleAlpha);
#else
//--------------------------------------------------------------------------------------------------------------------------------
// Shadow Caster Pass
#if _CFXR_ADDITIVE
half alpha = max(particleColor.r, max(particleColor.g, particleColor.b));
#else
half alpha = particleAlpha;
#endif
#if _CFXR_DITHERED_SHADOWS_ON || _CFXR_DITHERED_SHADOWS_CUSTOMTEXTURE
alpha = min(alpha, _ShadowStrength);
// Use dither mask for alpha blended shadows, based on pixel position xy
// and alpha level. Our dither texture is 4x4x16.
#if _CFXR_DITHERED_SHADOWS_CUSTOMTEXTURE
half texSize = _DitherCustom_TexelSize.z;
alpha = tex3D(_DitherCustom, float3(vpos.xy*(1 / texSize), alpha*(1 - (1 / (texSize*texSize))))).a;
#else
alpha = tex3D(_DitherMaskLOD, float3(vpos.xy*0.25, alpha*0.9375)).a;
#endif
#endif
clip(alpha - 0.01);
SHADOW_CASTER_FRAGMENT(i)
#endif
}