GroundedSkybox.js 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. import { Mesh, MeshBasicMaterial, SphereGeometry, Vector3 } from 'three';
  2. /**
  3. * A ground-projected skybox.
  4. *
  5. * By default the object is centered at the camera, so it is often helpful to set
  6. * `skybox.position.y = height` to put the ground at the origin.
  7. *
  8. * ```js
  9. * const height = 15, radius = 100;
  10. *
  11. * const skybox = new GroundedSkybox( envMap, height, radius );
  12. * skybox.position.y = height;
  13. * scene.add( skybox );
  14. * ```
  15. *
  16. * @augments Mesh
  17. */
  18. class GroundedSkybox extends Mesh {
  19. /**
  20. * Constructs a new ground-projected skybox.
  21. *
  22. * @param {Texture} map - The environment map to use.
  23. * @param {number} height - The height is how far the camera that took the photo was above the ground.
  24. * A larger value will magnify the downward part of the image.
  25. * @param {number} radius - The radius of the skybox. Must be large enough to ensure the scene's camera stays inside.
  26. * @param {number} [resolution=128] - The geometry resolution of the skybox.
  27. */
  28. constructor( map, height, radius, resolution = 128 ) {
  29. if ( height <= 0 || radius <= 0 || resolution <= 0 ) {
  30. throw new Error( 'GroundedSkybox height, radius, and resolution must be positive.' );
  31. }
  32. const geometry = new SphereGeometry( radius, 2 * resolution, resolution );
  33. geometry.scale( 1, 1, - 1 );
  34. const pos = geometry.getAttribute( 'position' );
  35. const tmp = new Vector3();
  36. for ( let i = 0; i < pos.count; ++ i ) {
  37. tmp.fromBufferAttribute( pos, i );
  38. if ( tmp.y < 0 ) {
  39. // Smooth out the transition from flat floor to sphere:
  40. const y1 = - height * 3 / 2;
  41. const f =
  42. tmp.y < y1 ? - height / tmp.y : ( 1 - tmp.y * tmp.y / ( 3 * y1 * y1 ) );
  43. tmp.multiplyScalar( f );
  44. tmp.toArray( pos.array, 3 * i );
  45. }
  46. }
  47. pos.needsUpdate = true;
  48. super( geometry, new MeshBasicMaterial( { map, depthWrite: false } ) );
  49. }
  50. }
  51. export { GroundedSkybox };
粤ICP备19079148号