Files
Emberwild/Assets/GAME/Shaders/StylizedLeavesCommon.hlsl
2026-06-22 16:18:34 +02:00

119 lines
5.2 KiB
HLSL

#ifndef STYLIZED_LEAVES_COMMON_INCLUDED
#define STYLIZED_LEAVES_COMMON_INCLUDED
// =====================================================================================
// Stylized Leaves - logique partagée (feuilles d'arbre).
// Inclus par TOUTES les passes pour un vent identique partout (ombres/depth cohérents).
// Réutilise SeasonCore.hlsl pour la saison globale (_Season) -> synchro avec l'herbe.
// =====================================================================================
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
TEXTURE2D(_MainTex); SAMPLER(sampler_MainTex);
TEXTURE2D(_NormalMap); SAMPLER(sampler_NormalMap);
TEXTURE2D(_MaskMap); SAMPLER(sampler_MaskMap); // R: Metallic, G: Occlusion, A: Smoothness
CBUFFER_START(UnityPerMaterial)
float4 _MainTex_ST;
float4 _NormalMap_ST;
// Couleurs PAR SAISON (1 couleur + variation A/B par feuille).
half4 _SummerColorA; half4 _SummerColorB;
half4 _AutumnColorA; half4 _AutumnColorB;
half4 _WinterColorA; half4 _WinterColorB;
float _LeafVariation; // échelle du bruit de variation par feuille
float _TextureColorInfluence; // 0 = texture en détail N&B (saison pilote), 1 = couleur texture
float _WinterThinning; // 0..1 : amincissement du feuillage en hiver (alpha cutoff monte)
// Surface PBR
float _Smoothness;
float _Metallic;
float _Occlusion;
float _NormalStrength;
float _NormalSphereBlend; // 0 = normale du mesh, 1 = normale sphérique (canopée puffy)
float _Cutoff;
// Éclairage stylisé
float _ShadowLift;
half4 _TranslucencyColor;
float _TranslucencyStrength;
float _TranslucencyPower;
// Vent
float4 _WindDirection; // .xy = direction du vent en monde (XZ)
float _WindStrength; // amplitude du balancement du canopée
float _WindSpeed; // vitesse du balancement
float _WindFrequency; // densité spatiale des vagues
float _WindHeight; // hauteur objet à laquelle le balancement est à 100%
float _FlutterStrength; // amplitude du frémissement des feuilles
float _FlutterSpeed; // vitesse du frémissement
float _FlutterFreq; // fréquence spatiale du frémissement
float _WindWinterStiffness; // multiplie le vent en hiver (branches plus raides)
CBUFFER_END
#include "SeasonCore.hlsl"
// -------------------------------------------------------------------------------------
// Vent : balancement du canopée (plus fort en haut) + frémissement des feuilles.
// -------------------------------------------------------------------------------------
float3 LeafApplyWind(float3 positionWS, float3 positionOS)
{
float t = _Time.y;
float2 windDir = _WindDirection.xy;
windDir = (dot(windDir, windDir) > 1e-5) ? normalize(windDir) : float2(1.0, 0.0);
float heightMask = saturate(positionOS.y / max(_WindHeight, 1e-4));
// Balancement global du canopée.
float phase = dot(positionWS.xz, windDir) * _WindFrequency + t * _WindSpeed;
float3 sway = float3(windDir.x, 0.0, windDir.y) * (sin(phase) * _WindStrength * heightMask);
// Frémissement haute fréquence, propre à chaque sommet.
float fp = t * _FlutterSpeed + dot(positionOS, float3(12.9, 7.3, 5.1)) * _FlutterFreq;
float3 flutter = float3(sin(fp), sin(fp * 1.7 + 1.0), cos(fp)) * (_FlutterStrength * heightMask);
float3 offset = (sway + flutter) * lerp(1.0, _WindWinterStiffness, SeasonWinterWeight());
return positionWS + offset;
}
// Test alpha + chute ÉPARSE et progressive des feuilles en hiver.
// Renvoie une valeur < 0 quand le fragment doit être clippé.
// En hiver, les feuilles dont le bruit < seuil "tombent" par paquets (pas un pop uniforme).
float LeafAlphaTest(half alpha, float3 positionWS)
{
float a = alpha - _Cutoff;
float drop = saturate(SeasonWinterWeight() * _WinterThinning); // proportion de feuilles tombées
float leafRand = SeasonGradientNoise(positionWS.xz * 1.7 + positionWS.y * 0.9);
return min(a, leafRand - drop);
}
// -------------------------------------------------------------------------------------
// Couleur de feuille pilotée par la saison (1 couleur + variation A/B par feuille).
// -------------------------------------------------------------------------------------
half3 LeafColor(float2 uv, float3 positionWS)
{
half3 tex = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, uv).rgb;
int i0, i1; float f;
SeasonBlend(i0, i1, f);
half3 colA[3] = { _SummerColorA.rgb, _AutumnColorA.rgb, _WinterColorA.rgb };
half3 colB[3] = { _SummerColorB.rgb, _AutumnColorB.rgb, _WinterColorB.rgb };
half3 cA = lerp(colA[i0], colA[i1], f);
half3 cB = lerp(colB[i0], colB[i1], f);
// Variation par feuille / amas (bruit world-space, un peu de Y pour casser la régularité).
float v = SeasonGradientNoise(positionWS.xz * _LeafVariation + positionWS.y * 0.5);
half3 seasonCol = lerp(cA, cB, v);
// Texture : détail N&B par défaut (la saison pilote la couleur).
float texLum = dot(tex, half3(0.299, 0.587, 0.114));
half3 texMod = lerp(saturate(texLum * 2.0).xxx, tex, _TextureColorInfluence);
return seasonCol * texMod;
}
#endif // STYLIZED_LEAVES_COMMON_INCLUDED