From 965be72ea477ccbe391c53d4b8a348e4bc22cb55 Mon Sep 17 00:00:00 2001 From: Georg Tomitsch Date: Sat, 6 Jun 2026 10:41:00 +0200 Subject: [PATCH] Tune WebGL book bounce lighting --- public/js/webgl-book-lab.js | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/public/js/webgl-book-lab.js b/public/js/webgl-book-lab.js index bc29491..ad15bf6 100644 --- a/public/js/webgl-book-lab.js +++ b/public/js/webgl-book-lab.js @@ -547,17 +547,20 @@ function configureBookShadowReceiver(material, strength) { return clamp(max(max(shadow0, shadow1), shadow2), 0.0, 1.0); } - vec3 bookLocalBounce(vec3 worldPosition, vec3 worldNormal, float shadow) { + vec3 bookLocalBounce(vec3 worldPosition, vec3 worldNormal, float shadow, vec3 albedo) { float tableDistance = max(0.0, worldPosition.y - bookTableTopY); - float tableReach = 1.0 - smoothstep(0.02, 0.24, tableDistance); + float tableReach = 1.0 - smoothstep(0.0, 0.34, tableDistance); + float sideReach = 1.0 - smoothstep(0.02, 0.62, tableDistance); float grazingSide = 1.0 - pow(abs(worldNormal.y), 0.65); - float underside = smoothstep(0.12, 0.82, -worldNormal.y); - float pageGlow = smoothstep(0.02, 0.18, worldPosition.y - bookTableTopY) * - (1.0 - smoothstep(0.18, 0.34, worldPosition.y - bookTableTopY)); - float bounce = tableReach * (0.42 + grazingSide * 0.34 + underside * 0.32) + pageGlow * 0.16; - vec3 tableWarmth = vec3(0.055, 0.029, 0.014); - vec3 pageWarmth = vec3(0.03, 0.021, 0.012); - return (tableWarmth * bounce + pageWarmth * pageGlow) * mix(1.0, 0.62, shadow); + float underside = smoothstep(0.16, 0.88, -worldNormal.y); + float sideFill = grazingSide * sideReach; + float tableFill = tableReach * (0.22 + underside * 0.24); + float pageFill = smoothstep(0.02, 0.2, tableDistance) * (1.0 - smoothstep(0.24, 0.72, tableDistance)); + vec3 tableWarmth = vec3(0.08, 0.045, 0.024) * tableFill; + vec3 roomWarmth = vec3(0.045, 0.033, 0.024) * sideFill; + vec3 pageWarmth = vec3(0.05, 0.041, 0.029) * pageFill * grazingSide; + vec3 indirect = tableWarmth + roomWarmth + pageWarmth; + return albedo * indirect * mix(1.0, 0.72, shadow); } float spineClothThread(float coordinate, float frequency, float sharpness) { @@ -606,7 +609,7 @@ function configureBookShadowReceiver(material, strength) { ${isHeadband ? 'outgoingLight = headbandCreviceLight(vBookSurfaceUv, outgoingLight);' : ''} float bookReceiverShadow = bookReceiverShadowField(vBookReceiverWorldPosition) * bookShadowReceiverStrength; outgoingLight *= mix(vec3(1.0), ${isHeadband ? 'vec3(0.16, 0.095, 0.055)' : 'vec3(0.38, 0.29, 0.2)'}, bookReceiverShadow); - outgoingLight += bookLocalBounce(vBookReceiverWorldPosition, normalize(vBookReceiverWorldNormal), bookReceiverShadow); + outgoingLight += bookLocalBounce(vBookReceiverWorldPosition, normalize(vBookReceiverWorldNormal), bookReceiverShadow, diffuseColor.rgb); #include ` ); };