Remove unused water quality material creation function

This commit is contained in:
2026-04-06 17:37:04 +02:00
parent 230a45e857
commit 4e455d4076

View File

@@ -668,200 +668,6 @@ export class RuntimeHost {
});
}
// High-quality water shader with normal map animation, refraction, foam, and object interaction.
private createWaterQualityMaterial(
water: { colorHex: string; surfaceOpacity: number; waveStrength: number },
faceId: string
): ShaderMaterial {
const isTopFace = faceId === "posY";
const baseOpacity = Math.max(0.05, Math.min(1, water.surfaceOpacity));
const opacity = isTopFace ? Math.min(1, baseOpacity + 0.2) : baseOpacity * 0.45;
const waveStrength = water.waveStrength;
// Parse hex color into r/g/b floats for GLSL
const hex = water.colorHex.replace("#", "");
const cr = parseInt(hex.substring(0, 2), 16) / 255;
const cg = parseInt(hex.substring(2, 4), 16) / 255;
const cb = parseInt(hex.substring(4, 6), 16) / 255;
const vertexShader = /* glsl */ `
uniform float time;
uniform float waveAmp;
varying vec2 vUv;
varying vec3 vNormal;
varying vec3 vWorldPos;
varying vec3 vViewDir;
varying vec4 vScreenPos;
varying float vDepth;
// Gerstner wave calculation for realistic water motion
vec3 gerstnerWave(vec4 wave, vec3 p) {
float steepness = wave.z;
float wavelength = wave.w;
float k = 2.0 * 3.14159 / wavelength;
float c = sqrt(9.8 / k);
vec2 d = normalize(wave.xy);
float f = k * (dot(d, p.xz) - c * time);
float a = steepness / k;
return vec3(
d.x * a * cos(f),
a * sin(f),
d.y * a * cos(f)
);
}
void main() {
vUv = uv;
vec3 pos = position;
float upFactor = max(0.0, normal.y);
// Composite three Gerstner waves at different frequencies
if (upFactor > 0.9) {
vec3 gridPoint = pos;
vec3 wave1 = gerstnerWave(vec4(1.0, 0.0, 0.25, 60.0), gridPoint);
vec3 wave2 = gerstnerWave(vec4(0.2, 0.86, 0.15, 31.0), gridPoint);
vec3 wave3 = gerstnerWave(vec4(0.2, 0.86, 0.06, 18.0), gridPoint);
pos += (wave1 + wave2 + wave3) * waveAmp * 0.5;
vNormal = normalize(normalMatrix * normalize(normal + vec3(
-(wave1.x + wave2.x + wave3.x) * 2.0,
1.0,
-(wave1.z + wave2.z + wave3.z) * 2.0
)));
} else {
vNormal = normalize(normalMatrix * normal);
}
vec4 worldPos = modelMatrix * vec4(pos, 1.0);
vWorldPos = worldPos.xyz;
vViewDir = normalize(cameraPosition - worldPos.xyz);
vScreenPos = projectionMatrix * viewMatrix * worldPos;
vDepth = -vScreenPos.z; // Store depth for refraction calculations
gl_Position = vScreenPos;
}
`;
const fragmentShader = /* glsl */ `
precision highp float;
uniform vec3 waterColor;
uniform float surfaceOpacity;
uniform float waveStrength;
uniform float time;
varying vec2 vUv;
varying vec3 vNormal;
varying vec3 vWorldPos;
varying vec3 vViewDir;
varying vec4 vScreenPos;
varying float vDepth;
// Simplex-like procedural noise for normal variation and foam
float noise(vec3 p) {
vec3 pi = floor(p);
vec3 pf = p - pi;
pf *= pf * (3.0 - 2.0 * pf);
float n = pi.x + pi.y * 57.0 + pi.z * 113.0;
return mix(
mix(mix(sin(n) * 43758.5453, sin(n + 1.0) * 43758.5453, pf.x),
mix(sin(n + 57.0) * 43758.5453, sin(n + 58.0) * 43758.5453, pf.x), pf.y),
mix(mix(sin(n + 113.0) * 43758.5453, sin(n + 114.0) * 43758.5453, pf.x),
mix(sin(n + 170.0) * 43758.5453, sin(n + 171.0) * 43758.5453, pf.x), pf.y),
pf.z
);
}
void main() {
// Multi-scale normal perturbation — subtle, data-driven
vec3 n1 = normalize(vec3(
noise(vWorldPos + time * 0.3) - 0.5,
0.8,
noise(vWorldPos * 1.5 + time * 0.25) - 0.5
));
vec3 n2 = normalize(vec3(
noise(vWorldPos * 0.7 - time * 0.2) - 0.5,
0.9,
noise(vWorldPos * 2.2 - time * 0.18) - 0.5
));
vec3 surfaceNormal = normalize(mix(vNormal, n1, 0.4) + n2 * 0.3);
vec3 viewDir = normalize(vViewDir);
float vDotN = max(0.0, dot(viewDir, surfaceNormal));
// Fresnel effect (brighter at grazing angles)
float fresnel = pow(1.0 - vDotN, 3.0) * 0.8 + 0.2;
// Specular highlight: sharp, shiny water reflection
vec3 reflection = reflect(-viewDir, surfaceNormal);
float specular = pow(max(0.0, dot(reflection, normalize(vec3(0.3, 0.8, 0.5)))), 16.0) * fresnel * 0.6;
// Depth-based coloring: water darkens with depth
float depthFade = 1.0 / (1.0 + vDepth * 0.008);
// **Color dominance**: user water color is primary, only subtle environment tint
vec3 baseWaterColor = waterColor;
// Slight sky tinting only at grazing angles for realism
vec3 environmentTint = vec3(0.85, 0.9, 1.0);
baseWaterColor = mix(baseWaterColor, environmentTint, fresnel * 0.12);
// Apply depth darkening
vec3 waterWithDepth = baseWaterColor * mix(0.3, 1.0, depthFade);
// **Foam with object interaction**:
// Layer 1: Wave peaks (fresnel-based, high curvature)
float foamPeaks = smoothstep(0.6, 0.85, fresnel) * sin(vWorldPos.x * 2.0 + time) * waveStrength;
foamPeaks = clamp(foamPeaks, 0.0, 0.2);
// Layer 2: Procedural detail (never-repeating, time-varies)
float foamDetail = abs(noise(vWorldPos * 3.0 + time * 0.4)) * 0.15;
// Layer 3: "Object interaction" — use screen-space depth gradient
// Objects touching the water create discontinuities in the depth buffer
vec2 screenUv = vScreenPos.xy / vScreenPos.w * 0.5 + 0.5;
vec2 off1 = screenUv + vec2(0.01, 0.0);
vec2 off2 = screenUv + vec2(-0.01, 0.0);
vec2 off3 = screenUv + vec2(0.0, 0.01);
vec2 off4 = screenUv + vec2(0.0, -0.01);
// Estimate depth gradient using texture coordinate variation
float depthGradient = abs(sin(vWorldPos.x * 0.5) - sin(vWorldPos.x * 0.5 + 0.3)) * waveStrength;
float foamInteraction = smoothstep(0.2, 0.7, depthGradient) * 0.25;
float totalFoam = min(0.4, foamPeaks + foamDetail + foamInteraction);
// Foam appears as bright white, blended with water
vec3 foamColor = vec3(1.0);
vec3 waterWithFoam = mix(waterWithDepth, foamColor, totalFoam);
// Add specular highlight on top
waterWithFoam += specular * vec3(1.0);
// Final alpha combines opacity, fresnel, and foam
float alpha = surfaceOpacity + fresnel * 0.25 + totalFoam * 0.2;
alpha = clamp(alpha, 0.08, 1.0);
gl_FragColor = vec4(waterWithFoam, alpha);
}
`;
const mat = new ShaderMaterial({
vertexShader,
fragmentShader,
uniforms: {
time: { value: this.volumeTime },
waterColor: { value: [cr, cg, cb] },
surfaceOpacity: { value: opacity },
waveStrength: { value: waveStrength },
waveAmp: { value: waveStrength * 0.08 }
},
transparent: true,
depthWrite: false,
side: 2 // DoubleSide for side/bottom faces
});
this.volumeAnimatedMaterials.push(mat);
return mat;
}
// Soft edge-faded fog shader with slow drift animation — quality mode only.
private createFogQualityMaterial(fog: { colorHex: string; density: number }): ShaderMaterial {
const hex = fog.colorHex.replace("#", "");