AnaglyphPassNode.js 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. import { Matrix3, NodeMaterial } from 'three/webgpu';
  2. import { clamp, nodeObject, Fn, vec4, uv, uniform, max } from 'three/tsl';
  3. import StereoCompositePassNode from './StereoCompositePassNode.js';
  4. /**
  5. * A render pass node that creates an anaglyph effect.
  6. *
  7. * @augments StereoCompositePassNode
  8. * @three_import import { anaglyphPass } from 'three/addons/tsl/display/AnaglyphPassNode.js';
  9. */
  10. class AnaglyphPassNode extends StereoCompositePassNode {
  11. static get type() {
  12. return 'AnaglyphPassNode';
  13. }
  14. /**
  15. * Constructs a new anaglyph pass node.
  16. *
  17. * @param {Scene} scene - The scene to render.
  18. * @param {Camera} camera - The camera to render the scene with.
  19. */
  20. constructor( scene, camera ) {
  21. super( scene, camera );
  22. /**
  23. * This flag can be used for type testing.
  24. *
  25. * @type {boolean}
  26. * @readonly
  27. * @default true
  28. */
  29. this.isAnaglyphPassNode = true;
  30. // Dubois matrices from https://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.7.6968&rep=rep1&type=pdf#page=4
  31. /**
  32. * Color matrix node for the left eye.
  33. *
  34. * @private
  35. * @type {UniformNode<mat3>}
  36. */
  37. this._colorMatrixLeft = uniform( new Matrix3().fromArray( [
  38. 0.456100, - 0.0400822, - 0.0152161,
  39. 0.500484, - 0.0378246, - 0.0205971,
  40. 0.176381, - 0.0157589, - 0.00546856
  41. ] ) );
  42. /**
  43. * Color matrix node for the right eye.
  44. *
  45. * @private
  46. * @type {UniformNode<mat3>}
  47. */
  48. this._colorMatrixRight = uniform( new Matrix3().fromArray( [
  49. - 0.0434706, 0.378476, - 0.0721527,
  50. - 0.0879388, 0.73364, - 0.112961,
  51. - 0.00155529, - 0.0184503, 1.2264
  52. ] ) );
  53. }
  54. /**
  55. * This method is used to setup the effect's TSL code.
  56. *
  57. * @param {NodeBuilder} builder - The current node builder.
  58. * @return {PassTextureNode}
  59. */
  60. setup( builder ) {
  61. const uvNode = uv();
  62. const anaglyph = Fn( () => {
  63. const colorL = this._mapLeft.sample( uvNode );
  64. const colorR = this._mapRight.sample( uvNode );
  65. const color = clamp( this._colorMatrixLeft.mul( colorL.rgb ).add( this._colorMatrixRight.mul( colorR.rgb ) ) );
  66. return vec4( color.rgb, max( colorL.a, colorR.a ) );
  67. } );
  68. const material = this._material || ( this._material = new NodeMaterial() );
  69. material.fragmentNode = anaglyph().context( builder.getSharedContext() );
  70. material.name = 'Anaglyph';
  71. material.needsUpdate = true;
  72. return super.setup( builder );
  73. }
  74. }
  75. export default AnaglyphPassNode;
  76. /**
  77. * TSL function for creating an anaglyph pass node.
  78. *
  79. * @tsl
  80. * @function
  81. * @param {Scene} scene - The scene to render.
  82. * @param {Camera} camera - The camera to render the scene with.
  83. * @returns {AnaglyphPassNode}
  84. */
  85. export const anaglyphPass = ( scene, camera ) => nodeObject( new AnaglyphPassNode( scene, camera ) );
粤ICP备19079148号