Spaces:
Running
Running
import { Matrix3, NodeMaterial } from 'three/webgpu'; | |
import { clamp, nodeObject, Fn, vec4, uv, uniform, max } from 'three/tsl'; | |
import StereoCompositePassNode from './StereoCompositePassNode.js'; | |
/** @module AnaglyphPassNode **/ | |
/** | |
* A render pass node that creates an anaglyph effect. | |
* | |
* @augments StereoCompositePassNode | |
*/ | |
class AnaglyphPassNode extends StereoCompositePassNode { | |
static get type() { | |
return 'AnaglyphPassNode'; | |
} | |
/** | |
* Constructs a new anaglyph pass node. | |
* | |
* @param {Scene} scene - The scene to render. | |
* @param {Camera} camera - The camera to render the scene with. | |
*/ | |
constructor( scene, camera ) { | |
super( scene, camera ); | |
/** | |
* This flag can be used for type testing. | |
* | |
* @type {Boolean} | |
* @readonly | |
* @default true | |
*/ | |
this.isAnaglyphPassNode = true; | |
// Dubois matrices from https://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.7.6968&rep=rep1&type=pdf#page=4 | |
/** | |
* Color matrix node for the left eye. | |
* | |
* @type {UniformNode<mat3>} | |
*/ | |
this._colorMatrixLeft = uniform( new Matrix3().fromArray( [ | |
0.456100, - 0.0400822, - 0.0152161, | |
0.500484, - 0.0378246, - 0.0205971, | |
0.176381, - 0.0157589, - 0.00546856 | |
] ) ); | |
/** | |
* Color matrix node for the right eye. | |
* | |
* @type {UniformNode<mat3>} | |
*/ | |
this._colorMatrixRight = uniform( new Matrix3().fromArray( [ | |
- 0.0434706, 0.378476, - 0.0721527, | |
- 0.0879388, 0.73364, - 0.112961, | |
- 0.00155529, - 0.0184503, 1.2264 | |
] ) ); | |
} | |
/** | |
* This method is used to setup the effect's TSL code. | |
* | |
* @param {NodeBuilder} builder - The current node builder. | |
* @return {PassTextureNode} | |
*/ | |
setup( builder ) { | |
const uvNode = uv(); | |
const anaglyph = Fn( () => { | |
const colorL = this._mapLeft.sample( uvNode ); | |
const colorR = this._mapRight.sample( uvNode ); | |
const color = clamp( this._colorMatrixLeft.mul( colorL.rgb ).add( this._colorMatrixRight.mul( colorR.rgb ) ) ); | |
return vec4( color.rgb, max( colorL.a, colorR.a ) ); | |
} ); | |
const material = this._material || ( this._material = new NodeMaterial() ); | |
material.fragmentNode = anaglyph().context( builder.getSharedContext() ); | |
material.name = 'Anaglyph'; | |
material.needsUpdate = true; | |
return super.setup( builder ); | |
} | |
} | |
export default AnaglyphPassNode; | |
/** | |
* TSL function for creating an anaglyph pass node. | |
* | |
* @function | |
* @param {Scene} scene - The scene to render. | |
* @param {Camera} camera - The camera to render the scene with. | |
* @returns {AnaglyphPassNode} | |
*/ | |
export const anaglyphPass = ( scene, camera ) => nodeObject( new AnaglyphPassNode( scene, camera ) ); | |