LightProbeHelperGPU.js 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. import {
  2. Mesh,
  3. NodeMaterial,
  4. SphereGeometry
  5. } from 'three';
  6. import { float, Fn, getShIrradianceAt, normalWorld, uniformArray, uniform, vec4 } from 'three/tsl';
  7. /**
  8. * Renders a sphere to visualize a light probe in the scene.
  9. *
  10. * This helper can only be used with {@link WebGPURenderer}.
  11. * When using {@link WebGLRenderer}, import from `LightProbeHelper.js`.
  12. *
  13. * ```js
  14. * const helper = new LightProbeHelper( lightProbe );
  15. * scene.add( helper );
  16. * ```
  17. *
  18. * @private
  19. * @augments Mesh
  20. * @three_import import { LightProbeHelper } from 'three/addons/helpers/LightProbeHelperGPU.js';
  21. */
  22. class LightProbeHelper extends Mesh {
  23. /**
  24. * Constructs a new light probe helper.
  25. *
  26. * @param {LightProbe} lightProbe - The light probe to visualize.
  27. * @param {number} [size=1] - The size of the helper.
  28. */
  29. constructor( lightProbe, size = 1 ) {
  30. const sh = uniformArray( lightProbe.sh.coefficients );
  31. const intensity = uniform( lightProbe.intensity );
  32. const RECIPROCAL_PI = float( 1 / Math.PI );
  33. const fragmentNode = Fn( () => {
  34. const irradiance = getShIrradianceAt( normalWorld, sh );
  35. const outgoingLight = RECIPROCAL_PI.mul( irradiance ).mul( intensity );
  36. return vec4( outgoingLight, 1.0 );
  37. } )();
  38. const material = new NodeMaterial();
  39. material.fragmentNode = fragmentNode;
  40. const geometry = new SphereGeometry( 1, 32, 16 );
  41. super( geometry, material );
  42. /**
  43. * The light probe to visualize.
  44. *
  45. * @type {LightProbe}
  46. */
  47. this.lightProbe = lightProbe;
  48. /**
  49. * The size of the helper.
  50. *
  51. * @type {number}
  52. * @default 1
  53. */
  54. this.size = size;
  55. this.type = 'LightProbeHelper';
  56. this._intensity = intensity;
  57. this._sh = sh;
  58. this.onBeforeRender();
  59. }
  60. /**
  61. * Frees the GPU-related resources allocated by this instance. Call this
  62. * method whenever this instance is no longer used in your app.
  63. */
  64. dispose() {
  65. this.geometry.dispose();
  66. this.material.dispose();
  67. }
  68. onBeforeRender() {
  69. this.position.copy( this.lightProbe.position );
  70. this.scale.set( 1, 1, 1 ).multiplyScalar( this.size );
  71. this._intensity.value = this.lightProbe.intensity;
  72. this._sh.array = this.lightProbe.sh.coefficients;
  73. }
  74. }
  75. export { LightProbeHelper };