63 lines
2.6 KiB
GLSL
63 lines
2.6 KiB
GLSL
#ifdef HAS_NORMALMAP
|
||
uniform sampler2D m_NormalMap;
|
||
#endif
|
||
#ifdef HAS_FOAMMAP
|
||
uniform sampler2D m_FoamMap;
|
||
#endif
|
||
|
||
uniform vec4 m_Tint;
|
||
uniform float m_FoamAmount;
|
||
|
||
in vec2 vUV;
|
||
in vec2 vTex1;
|
||
in vec2 vTex2;
|
||
|
||
out vec4 outFragColor;
|
||
|
||
void main() {
|
||
// ── Randabstand: 0 = Mitte, 1 = Rand ─────────────────────────────────────
|
||
float edgeDist = abs(vUV.x * 2.0 - 1.0);
|
||
|
||
// ── Tiefengradient ────────────────────────────────────────────────────────
|
||
// Ränder heller/transparenter (flaches Ufer), Mitte dunkler (tief)
|
||
vec3 baseColor = m_Tint.rgb * (1.0 - edgeDist * 0.45);
|
||
float baseAlpha = m_Tint.a * smoothstep(0.0, 0.18, 1.0 - edgeDist);
|
||
|
||
// ── Dual-Layer Normal-Map: Specular + Wellenhelligkeit ────────────────────
|
||
float specular = 0.0;
|
||
float ripple = 0.0;
|
||
#ifdef HAS_NORMALMAP
|
||
vec3 n1 = texture(m_NormalMap, vTex1).rgb * 2.0 - 1.0;
|
||
vec3 n2 = texture(m_NormalMap, vTex2).rgb * 2.0 - 1.0;
|
||
vec3 n = normalize(n1 + n2);
|
||
|
||
// Feste Sonnenrichtung – gut für Bachlauf-Optik
|
||
vec3 sunDir = normalize(vec3(0.5, 1.0, 0.3));
|
||
specular = pow(max(0.0, dot(n, sunDir)), 22.0);
|
||
// Wellenhelligkeit variiert den Basiston leicht
|
||
ripple = dot(n, vec3(0.0, 1.0, 0.0)) * 0.10;
|
||
#endif
|
||
|
||
// ── Schaum ────────────────────────────────────────────────────────────────
|
||
// Uferschaum wird stärker je näher am Rand; Wasserfälle extra
|
||
float foamEdge = smoothstep(0.55, 1.0, edgeDist);
|
||
float foamMask = clamp(foamEdge + m_FoamAmount * 0.75, 0.0, 1.0);
|
||
|
||
#ifdef HAS_FOAMMAP
|
||
float foamSample = texture(m_FoamMap, vTex1 * 0.4).r;
|
||
foamMask *= foamSample;
|
||
#else
|
||
// Prozeduraler Fallback wenn keine Schaumtextur geladen
|
||
float procFoam = (sin(vTex1.x * 6.283) * 0.5 + 0.5)
|
||
* (sin(vTex1.y * 3.141) * 0.5 + 0.5);
|
||
foamMask *= procFoam;
|
||
#endif
|
||
|
||
// ── Zusammenführen ────────────────────────────────────────────────────────
|
||
vec3 waterColor = baseColor + ripple + vec3(0.35, 0.45, 0.55) * specular;
|
||
vec3 finalColor = mix(waterColor, vec3(1.0), foamMask);
|
||
float finalAlpha = max(baseAlpha, foamMask * 0.9);
|
||
|
||
outFragColor = vec4(clamp(finalColor, 0.0, 1.0), finalAlpha);
|
||
}
|