119 lines
5.2 KiB
HLSL
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
|