Skip to content

Commit

Permalink
Grounded Skybox (#27448)
Browse files Browse the repository at this point in the history
* initial change

* mrdoob approves

* updated example

* update screenshot
  • Loading branch information
elalish authored Dec 28, 2023
1 parent dfbee3c commit 36f9019
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 189 deletions.
172 changes: 0 additions & 172 deletions examples/jsm/objects/GroundProjectedSkybox.js

This file was deleted.

49 changes: 49 additions & 0 deletions examples/jsm/objects/GroundedSkybox.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { BackSide, Mesh, MeshBasicMaterial, SphereGeometry, Vector3 } from 'three';

/**
* A ground-projected skybox. 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. By default the object is centered at the camera,
* so it is often helpful to set skybox.position.y = height to put the ground at the origin. Set the radius
* large enough to ensure your user's camera stays inside.
*/

class GroundedSkybox extends Mesh {

constructor( map, height, radius, resolution = 128 ) {

if ( height <= 0 || radius <= 0 || resolution <= 0 ) {

throw new Error( 'GroundedSkybox height, radius, and resolution must be positive.' );

}

const geometry = new SphereGeometry( radius, 2 * resolution, resolution );

const pos = geometry.getAttribute( 'position' );
const tmp = new Vector3();

for ( let i = 0; i < pos.count; ++ i ) {

tmp.fromBufferAttribute( pos, i );
if ( tmp.y < 0 ) {

// Smooth out the transition from flat floor to sphere:
const y1 = - height * 3 / 2;
const f =
tmp.y < y1 ? - height / tmp.y : ( 1 - tmp.y * tmp.y / ( 3 * y1 * y1 ) );
tmp.multiplyScalar( f );
tmp.toArray( pos.array, 3 * i );

}

}

pos.needsUpdate = true;

super( geometry, new MeshBasicMaterial( { map, side: BackSide } ) );

}

}

export { GroundedSkybox };
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
23 changes: 6 additions & 17 deletions examples/webgl_materials_envmaps_groundprojected.html
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
<body>
<div id="container"></div>
<div id="info">
<a href="https://threejs.org" target="_blank" rel="noopener">threejs</a> - Ground projected environment mapping. By <a href="https://twitter.com/CantBeFaraz" target="_blank" rel="noopener">Faraz Shaikh</a>.<br>
<a href="https://threejs.org" target="_blank" rel="noopener">threejs</a> - Ground projected environment mapping.<br>
Ferrari 458 Italia model by <a href="https://sketchfab.com/models/57bf6cc56931426e87494f554df1dab6" target="_blank" rel="noopener">vicent091036</a><br>
<a href="https://polyhaven.com/a/blouberg_sunrise_2" target="_blank" rel="noopener">Blouberg Sunrise 2</a> by <a href="https://gregzaal.com/" target="_blank" rel="noopener">Greg Zaal</a>
</div>
Expand All @@ -31,16 +31,15 @@
<script type="module">
import * as THREE from 'three';

import { GUI } from 'three/addons/libs/lil-gui.module.min.js';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
import { GroundProjectedSkybox } from 'three/addons/objects/GroundProjectedSkybox.js';
import { GroundedSkybox } from 'three/addons/objects/GroundedSkybox.js';
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
import { DRACOLoader } from 'three/addons/loaders/DRACOLoader.js';
import { RGBELoader } from 'three/addons/loaders/RGBELoader.js';

const params = {
height: 20,
radius: 440
height: 15,
radius: 100
};

let camera, scene, renderer, skybox;
Expand All @@ -64,8 +63,8 @@
const envMap = await hdrLoader.loadAsync( 'textures/equirectangular/blouberg_sunrise_2_1k.hdr' );
envMap.mapping = THREE.EquirectangularReflectionMapping;

skybox = new GroundProjectedSkybox( envMap );
skybox.scale.setScalar( 100 );
skybox = new GroundedSkybox( envMap, params.height, params.radius );
skybox.position.y = params.height - 0.01;
scene.add( skybox );

scene.environment = envMap;
Expand Down Expand Up @@ -115,7 +114,6 @@
} )
);
mesh.rotation.x = - Math.PI / 2;
mesh.renderOrder = 2;
carModel.add( mesh );

scene.add( carModel );
Expand All @@ -142,12 +140,6 @@
controls.enablePan = false;
controls.update();

const gui = new GUI();
gui.add( params, 'height', 20, 50, 0.1 ).name( 'Skybox height' ).onChange( render );
gui.add( params, 'radius', 200, 600, 0.1 ).name( 'Skybox radius' ).onChange( render );

//

document.body.appendChild( renderer.domElement );
window.addEventListener( 'resize', onWindowResize );

Expand All @@ -168,9 +160,6 @@

renderer.render( scene, camera );

skybox.radius = params.radius;
skybox.height = params.height;

}
</script>
</body>
Expand Down

0 comments on commit 36f9019

Please sign in to comment.