TransitionNode.js 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. import { TempNode } from 'three/webgpu';
  2. import { nodeObject, Fn, float, uv, convertToTexture, vec4, If, int, clamp, sub, mix } from 'three/tsl';
  3. /**
  4. * Post processing node for creating a transition effect between scenes.
  5. *
  6. * @augments TempNode
  7. */
  8. class TransitionNode extends TempNode {
  9. static get type() {
  10. return 'TransitionNode';
  11. }
  12. /**
  13. * Constructs a new transition node.
  14. *
  15. * @param {TextureNode} textureNodeA - A texture node that represents the beauty pass of the first scene.
  16. * @param {TextureNode} textureNodeB - A texture node that represents the beauty pass of the second scene.
  17. * @param {TextureNode} mixTextureNode - A texture node that defines how the transition effect should look like.
  18. * @param {Node<float>} mixRatioNode - The interpolation factor that controls the mix.
  19. * @param {Node<float>} thresholdNode - Can be used to tweak the linear interpolation.
  20. * @param {Node<float>} useTextureNode - Whether `mixTextureNode` should influence the transition or not.
  21. */
  22. constructor( textureNodeA, textureNodeB, mixTextureNode, mixRatioNode, thresholdNode, useTextureNode ) {
  23. super( 'vec4' );
  24. /**
  25. * A texture node that represents the beauty pass of the first scene.
  26. *
  27. * @type {TextureNode}
  28. */
  29. this.textureNodeA = textureNodeA;
  30. /**
  31. * A texture node that represents the beauty pass of the second scene.
  32. *
  33. * @type {TextureNode}
  34. */
  35. this.textureNodeB = textureNodeB;
  36. /**
  37. * A texture that defines how the transition effect should look like.
  38. *
  39. * @type {TextureNode}
  40. */
  41. this.mixTextureNode = mixTextureNode;
  42. /**
  43. * The interpolation factor that controls the mix.
  44. *
  45. * @type {Node<float>}
  46. */
  47. this.mixRatioNode = mixRatioNode;
  48. /**
  49. * Can be used to tweak the linear interpolation.
  50. *
  51. * @type {Node<float>}
  52. */
  53. this.thresholdNode = thresholdNode;
  54. /**
  55. * Whether `mixTextureNode` should influence the transition or not.
  56. *
  57. * @type {Node<float>}
  58. */
  59. this.useTextureNode = useTextureNode;
  60. }
  61. /**
  62. * This method is used to setup the effect's TSL code.
  63. *
  64. * @param {NodeBuilder} builder - The current node builder.
  65. * @return {ShaderCallNodeInternal}
  66. */
  67. setup() {
  68. const { textureNodeA, textureNodeB, mixTextureNode, mixRatioNode, thresholdNode, useTextureNode } = this;
  69. const sampleTexture = ( textureNode ) => {
  70. const uvNodeTexture = textureNode.uvNode || uv();
  71. return textureNode.sample( uvNodeTexture );
  72. };
  73. const transition = Fn( () => {
  74. const texelOne = sampleTexture( textureNodeA );
  75. const texelTwo = sampleTexture( textureNodeB );
  76. const color = vec4().toVar();
  77. If( useTextureNode.equal( int( 1 ) ), () => {
  78. const transitionTexel = sampleTexture( mixTextureNode );
  79. const r = mixRatioNode.mul( thresholdNode.mul( 2.0 ).add( 1.0 ) ).sub( thresholdNode );
  80. const mixf = clamp( sub( transitionTexel.r, r ).mul( float( 1.0 ).div( thresholdNode ) ), 0.0, 1.0 );
  81. color.assign( mix( texelOne, texelTwo, mixf ) );
  82. } ).Else( () => {
  83. color.assign( mix( texelTwo, texelOne, mixRatioNode ) );
  84. } );
  85. return color;
  86. } );
  87. const outputNode = transition();
  88. return outputNode;
  89. }
  90. }
  91. export default TransitionNode;
  92. /**
  93. * TSL function for creating a transition node for post processing.
  94. *
  95. * @tsl
  96. * @function
  97. * @param {Node<vec4>} nodeA - A texture node that represents the beauty pass of the first scene.
  98. * @param {Node<vec4>} nodeB - A texture node that represents the beauty pass of the second scene.
  99. * @param {Node<vec4>} mixTextureNode - A texture that defines how the transition effect should look like.
  100. * @param {Node<float> | number} mixRatio - The interpolation factor that controls the mix.
  101. * @param {Node<float> | number} threshold - Can be used to tweak the linear interpolation.
  102. * @param {Node<float> | number} useTexture - Whether `mixTextureNode` should influence the transition or not.
  103. * @returns {TransitionNode}
  104. */
  105. export const transition = ( nodeA, nodeB, mixTextureNode, mixRatio, threshold, useTexture ) => nodeObject( new TransitionNode( convertToTexture( nodeA ), convertToTexture( nodeB ), convertToTexture( mixTextureNode ), nodeObject( mixRatio ), nodeObject( threshold ), nodeObject( useTexture ) ) );
粤ICP备19079148号