From cd8eb0c8a7e98cbdf3ddec46500b87e48a7d7b32 Mon Sep 17 00:00:00 2001 From: Michael Herzog Date: Wed, 20 May 2026 14:39:30 +0200 Subject: [PATCH] Examples: Add TSL function for grounded skyboxes. (#33611) --- examples/files.json | 1 + examples/jsm/tsl/utils/GroundedSkybox.js | 62 ++++++ ...bgpu_materials_envmaps_groundprojected.jpg | Bin 0 -> 26009 bytes ...gpu_materials_envmaps_groundprojected.html | 208 ++++++++++++++++++ 4 files changed, 271 insertions(+) create mode 100644 examples/jsm/tsl/utils/GroundedSkybox.js create mode 100644 examples/screenshots/webgpu_materials_envmaps_groundprojected.jpg create mode 100644 examples/webgpu_materials_envmaps_groundprojected.html diff --git a/examples/files.json b/examples/files.json index 87c447172f0279..510dd4925dcd92 100644 --- a/examples/files.json +++ b/examples/files.json @@ -386,6 +386,7 @@ "webgpu_materials_cubemap_mipmaps", "webgpu_materials_displacementmap", "webgpu_materials_envmaps_bpcem", + "webgpu_materials_envmaps_groundprojected", "webgpu_materials_envmaps", "webgpu_materials_lightmap", "webgpu_materials_matcap", diff --git a/examples/jsm/tsl/utils/GroundedSkybox.js b/examples/jsm/tsl/utils/GroundedSkybox.js new file mode 100644 index 00000000000000..7769aae8fcdc0f --- /dev/null +++ b/examples/jsm/tsl/utils/GroundedSkybox.js @@ -0,0 +1,62 @@ +import { Fn, If, vec3, float, min, cameraPosition, positionWorld } from 'three/tsl'; + +/** + * @module GroundedSkybox + * @three_import import { getGroundProjectedNormal } from 'three/addons/tsl/utils/GroundedSkybox.js'; + */ + +/** + * Projects the world position onto a sphere whose bottom is clipped by a ground disk, + * then returns a vector usable for sampling an environment cube map. + * + * @tsl + * @function + * @param {Node} radiusNode - The radius of the projection sphere. Must be large enough to ensure the scene's camera stays inside. + * @param {Node} heightNode - The height is how far the camera that took the photo was above the ground. A larger value will magnify the downward part of the image. + * @return {Node} A direction vector for sampling the environment cube map. + */ +export const getGroundProjectedNormal = Fn( ( [ radiusNode, heightNode ] ) => { + + const p = positionWorld.sub( cameraPosition ).normalize().toConst(); + const camPos = cameraPosition.toVar(); + camPos.y.subAssign( heightNode ); + + // sphereIntersect( camPos, p, vec3( 0 ), radius ) + const b = camPos.dot( p ).toConst(); + const c = camPos.dot( camPos ).sub( radiusNode.mul( radiusNode ) ).toConst(); + const h = b.mul( b ).sub( c ).toConst(); + + const intersection = h.greaterThanEqual( 0 ).select( h.sqrt().sub( b ), - 1 ); + + const projected = vec3( 0, 1, 0 ).toVar(); + + If( intersection.greaterThan( 0 ), () => { + + // diskIntersectWithBackFaceCulling( camPos, p, diskCenter, n, radius ) + const diskCenter = vec3( 0, heightNode.negate(), 0 ).toConst(); + const n = vec3( 0, 1, 0 ).toConst(); + const d = p.dot( n ).toConst(); + + const intersection2 = float( 1e6 ).toVar(); + + If( d.lessThanEqual( 0 ), () => { + + const o = camPos.sub( diskCenter ).toConst(); + const t = n.dot( o ).negate().div( d ).toConst(); + const q = o.add( p.mul( t ) ).toConst(); + + If( q.dot( q ).lessThan( radiusNode.mul( radiusNode ) ), () => { + + intersection2.assign( t ); + + } ); + + } ); + + projected.assign( camPos.add( p.mul( min( intersection, intersection2 ) ) ).div( radiusNode ) ); + + } ); + + return projected; + +} ); diff --git a/examples/screenshots/webgpu_materials_envmaps_groundprojected.jpg b/examples/screenshots/webgpu_materials_envmaps_groundprojected.jpg new file mode 100644 index 0000000000000000000000000000000000000000..595a76707c906cbe5881acbeca3fde4514ded62b GIT binary patch literal 26009 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 literal 0 HcmV?d00001 diff --git a/examples/webgpu_materials_envmaps_groundprojected.html b/examples/webgpu_materials_envmaps_groundprojected.html new file mode 100644 index 00000000000000..7680cf65a2bb71 --- /dev/null +++ b/examples/webgpu_materials_envmaps_groundprojected.html @@ -0,0 +1,208 @@ + + + + threejs webgpu - materials - ground projected environment mapping + + + + + + + + + +
+ + +
+ three.jsGround Projected Env Maps +
+ + + Ferrari 458 Italia model by vicent091036
+ Blouberg Sunrise 2 by Greg Zaal +
+
+ + + + + +