AnaglyphPassNode.js 2.6 KB

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