LightNode.js 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. import Node from '../core/Node.js';
  2. import Object3DNode from '../accessors/Object3DNode.js';
  3. import PositionNode from '../accessors/PositionNode.js';
  4. import UniformNode from '../core/UniformNode.js';
  5. import OperatorNode from '../math/OperatorNode.js';
  6. import MathNode from '../math/MathNode.js';
  7. import { NodeUpdateType } from '../core/constants.js';
  8. import { getDistanceAttenuation } from '../functions/BSDFs.js';
  9. import { Color } from 'three';
  10. class LightNode extends Node {
  11. constructor( light = null ) {
  12. super( 'vec3' );
  13. this.updateType = NodeUpdateType.Object;
  14. this.light = light;
  15. this._colorNode = new UniformNode( new Color() );
  16. this._lightCutoffDistanceNode = new UniformNode( 0 );
  17. this._lightDecayExponentNode = new UniformNode( 0 );
  18. }
  19. getHash( /*builder*/ ) {
  20. return this.light.uuid;
  21. }
  22. update( /* frame */ ) {
  23. this._colorNode.value.copy( this.light.color ).multiplyScalar( this.light.intensity );
  24. this._lightCutoffDistanceNode.value = this.light.distance;
  25. this._lightDecayExponentNode.value = this.light.decay;
  26. }
  27. generate( builder ) {
  28. const lightPositionView = new Object3DNode( Object3DNode.VIEW_POSITION );
  29. const positionView = new PositionNode( PositionNode.VIEW );
  30. const lVector = new OperatorNode( '-', lightPositionView, positionView );
  31. const lightDirection = new MathNode( MathNode.NORMALIZE, lVector );
  32. const lightDistance = new MathNode( MathNode.LENGTH, lVector );
  33. const lightAttenuation = getDistanceAttenuation( {
  34. lightDistance,
  35. cutoffDistance: this._lightCutoffDistanceNode,
  36. decayExponent: this._lightDecayExponentNode
  37. } );
  38. const lightColor = new OperatorNode( '*', this._colorNode, lightAttenuation );
  39. lightPositionView.object3d = this.light;
  40. const lightingModelFunction = builder.context.lightingModel;
  41. if ( lightingModelFunction !== undefined ) {
  42. const directDiffuse = builder.context.directDiffuse;
  43. const directSpecular = builder.context.directSpecular;
  44. lightingModelFunction( {
  45. lightDirection,
  46. lightColor,
  47. directDiffuse,
  48. directSpecular
  49. }, builder );
  50. }
  51. }
  52. }
  53. export default LightNode;