LightingContextNode.js 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. import ContextNode from '../core/ContextNode.js';
  2. import { temp } from '../core/VarNode.js';
  3. import { add } from '../math/OperatorNode.js';
  4. import { mix } from '../math/MathNode.js';
  5. import { addNodeClass } from '../core/Node.js';
  6. import { addNodeElement, nodeProxy, float, vec3 } from '../shadernode/ShaderNode.js';
  7. class LightingContextNode extends ContextNode {
  8. constructor( node, lightingModelNode = null, backdropNode = null, backdropAlphaNode = null ) {
  9. super( node );
  10. this.lightingModelNode = lightingModelNode;
  11. this.backdropNode = backdropNode;
  12. this.backdropAlphaNode = backdropAlphaNode;
  13. }
  14. getNodeType( /*builder*/ ) {
  15. return 'vec3';
  16. }
  17. construct( builder ) {
  18. const { lightingModelNode, backdropNode, backdropAlphaNode } = this;
  19. const context = this.context = {}; // reset context
  20. const properties = builder.getNodeProperties( this );
  21. const directDiffuse = temp( vec3() ),
  22. directSpecular = temp( vec3() ),
  23. indirectDiffuse = temp( vec3() ),
  24. indirectSpecular = temp( vec3() );
  25. let totalDiffuse = add( directDiffuse, indirectDiffuse );
  26. if ( backdropNode !== null ) {
  27. totalDiffuse = vec3( backdropAlphaNode !== null ? mix( totalDiffuse, backdropNode, backdropAlphaNode ) : backdropNode );
  28. }
  29. const totalSpecular = add( directSpecular, indirectSpecular );
  30. const total = add( totalDiffuse, totalSpecular );
  31. const reflectedLight = {
  32. directDiffuse,
  33. directSpecular,
  34. indirectDiffuse,
  35. indirectSpecular,
  36. total
  37. };
  38. const lighting = {
  39. radiance: temp( vec3() ),
  40. irradiance: temp( vec3() ),
  41. iblIrradiance: temp( vec3() ),
  42. ambientOcclusion: temp( float( 1 ) )
  43. };
  44. Object.assign( properties, reflectedLight, lighting );
  45. Object.assign( context, lighting );
  46. context.reflectedLight = reflectedLight;
  47. context.lightingModelNode = lightingModelNode || context.lightingModelNode;
  48. if ( lightingModelNode && lightingModelNode.indirectDiffuse ) lightingModelNode.indirectDiffuse.call( context );
  49. if ( lightingModelNode && lightingModelNode.indirectSpecular ) lightingModelNode.indirectSpecular.call( context );
  50. if ( lightingModelNode && lightingModelNode.ambientOcclusion ) lightingModelNode.ambientOcclusion.call( context );
  51. return super.construct( builder );
  52. }
  53. generate( builder ) {
  54. const { context } = this;
  55. const type = this.getNodeType( builder );
  56. super.generate( builder, type );
  57. return context.reflectedLight.total.build( builder, type );
  58. }
  59. }
  60. export default LightingContextNode;
  61. export const lightingContext = nodeProxy( LightingContextNode );
  62. addNodeElement( 'lightingContext', lightingContext );
  63. addNodeClass( LightingContextNode );