LightingContextNode.js 2.1 KB

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