ViewportNode.js 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. import Node from '../core/Node.js';
  2. import { uniform, div, vec2, invert } from '../shadernode/ShaderNodeBaseElements.js';
  3. import { Vector2 } from 'three';
  4. import { NodeUpdateType } from '../core/constants.js';
  5. let resolution;
  6. class ViewportNode extends Node {
  7. static COORDINATE = 'coordinate';
  8. static RESOLUTION = 'resolution';
  9. static TOP_LEFT = 'topLeft';
  10. static BOTTOM_LEFT = 'bottomLeft';
  11. static TOP_RIGHT = 'topRight';
  12. static BOTTOM_RIGHT = 'bottomRight';
  13. constructor( scope ) {
  14. super();
  15. this.scope = scope;
  16. this.isViewportNode = true;
  17. }
  18. getNodeType() {
  19. return this.scope === ViewportNode.COORDINATE ? 'vec4' : 'vec2';
  20. }
  21. getUpdateType() {
  22. let updateType = NodeUpdateType.NONE;
  23. if ( this.scope === ViewportNode.RESOLUTION ) {
  24. updateType = NodeUpdateType.FRAME;
  25. }
  26. this.updateType = updateType;
  27. return updateType;
  28. }
  29. update( { renderer } ) {
  30. renderer.getSize( resolution );
  31. }
  32. construct( builder ) {
  33. const scope = this.scope;
  34. if ( scope === ViewportNode.COORDINATE ) return;
  35. let output = null;
  36. if ( scope === ViewportNode.RESOLUTION ) {
  37. resolution ||= new Vector2();
  38. output = uniform( resolution );
  39. } else {
  40. const coordinateNode = vec2( new ViewportNode( ViewportNode.COORDINATE ) );
  41. const resolutionNode = new ViewportNode( ViewportNode.RESOLUTION );
  42. output = div( coordinateNode, resolutionNode );
  43. let outX = output.x;
  44. let outY = output.y;
  45. if ( /top/i.test( scope ) && builder.isFlipY() ) outY = invert( outY );
  46. else if ( /bottom/i.test( scope ) && builder.isFlipY() === false ) outY = invert( outY );
  47. if ( /right/i.test( scope ) ) outX = invert( outX );
  48. output = vec2( outX, outY );
  49. }
  50. return output;
  51. }
  52. generate( builder ) {
  53. if ( this.scope === ViewportNode.COORDINATE ) {
  54. return builder.getFragCoord();
  55. }
  56. return super.generate( builder );
  57. }
  58. }
  59. export default ViewportNode;