LightNode.js 2.3 KB

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