Lut3DNode.js 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. import { TempNode } from 'three/webgpu';
  2. import { nodeObject, Fn, float, uniform, vec3, vec4, mix } from 'three/tsl';
  3. /**
  4. * A post processing node for color grading via lookup tables.
  5. *
  6. * @augments TempNode
  7. */
  8. class Lut3DNode extends TempNode {
  9. static get type() {
  10. return 'Lut3DNode';
  11. }
  12. /**
  13. * Constructs a new LUT node.
  14. *
  15. * @param {Node} inputNode - The node that represents the input of the effect.
  16. * @param {TextureNode} lutNode - A texture node that represents the lookup table.
  17. * @param {number} size - The size of the lookup table.
  18. * @param {Node<float>} intensityNode - Controls the intensity of the effect.
  19. */
  20. constructor( inputNode, lutNode, size, intensityNode ) {
  21. super( 'vec4' );
  22. /**
  23. * The node that represents the input of the effect.
  24. *
  25. * @type {Node}
  26. */
  27. this.inputNode = inputNode;
  28. /**
  29. * A texture node that represents the lookup table.
  30. *
  31. * @type {TextureNode}
  32. */
  33. this.lutNode = lutNode;
  34. /**
  35. * The size of the lookup table.
  36. *
  37. * @type {UniformNode<float>}
  38. */
  39. this.size = uniform( size );
  40. /**
  41. * Controls the intensity of the effect.
  42. *
  43. * @type {Node<float>}
  44. */
  45. this.intensityNode = intensityNode;
  46. }
  47. /**
  48. * This method is used to setup the effect's TSL code.
  49. *
  50. * @param {NodeBuilder} builder - The current node builder.
  51. * @return {ShaderCallNodeInternal}
  52. */
  53. setup() {
  54. const { inputNode, lutNode } = this;
  55. const sampleLut = ( uv ) => lutNode.sample( uv );
  56. const lut3D = Fn( () => {
  57. const base = inputNode;
  58. // pull the sample in by half a pixel so the sample begins at the center of the edge pixels.
  59. const pixelWidth = float( 1.0 ).div( this.size );
  60. const halfPixelWidth = float( 0.5 ).div( this.size );
  61. const uvw = vec3( halfPixelWidth ).add( base.rgb.mul( float( 1.0 ).sub( pixelWidth ) ) );
  62. const lutValue = vec4( sampleLut( uvw ).rgb, base.a );
  63. return vec4( mix( base, lutValue, this.intensityNode ) );
  64. } );
  65. const outputNode = lut3D();
  66. return outputNode;
  67. }
  68. }
  69. export default Lut3DNode;
  70. /**
  71. * TSL function for creating a LUT node for color grading via post processing.
  72. *
  73. * @tsl
  74. * @function
  75. * @param {Node} node - The node that represents the input of the effect.
  76. * @param {TextureNode} lut - A texture node that represents the lookup table.
  77. * @param {number} size - The size of the lookup table.
  78. * @param {Node<float> | number} intensity - Controls the intensity of the effect.
  79. * @returns {Lut3DNode}
  80. */
  81. export const lut3D = ( node, lut, size, intensity ) => nodeObject( new Lut3DNode( nodeObject( node ), nodeObject( lut ), size, nodeObject( intensity ) ) );
粤ICP备19079148号