UNPKG

three

Version:

JavaScript 3D library

135 lines (99 loc) 3.14 kB
import { ShaderMaterial, UniformsUtils } from 'three'; import { Pass, FullScreenQuad } from './Pass.js'; /** * This pass can be used to create a post processing effect * with a raw GLSL shader object. Useful for implementing custom * effects. * * ```js * const fxaaPass = new ShaderPass( FXAAShader ); * composer.addPass( fxaaPass ); * ``` * * @augments Pass */ class ShaderPass extends Pass { /** * Constructs a new shader pass. * * @param {Object|ShaderMaterial} [shader] - A shader object holding vertex and fragment shader as well as * defines and uniforms. It's also valid to pass a custom shader material. * @param {string} [textureID='tDiffuse'] - The name of the texture uniform that should sample * the read buffer. */ constructor( shader, textureID = 'tDiffuse' ) { super(); /** * The name of the texture uniform that should sample the read buffer. * * @type {string} * @default 'tDiffuse' */ this.textureID = textureID; /** * The pass uniforms. * * @type {?Object} */ this.uniforms = null; /** * The pass material. * * @type {?ShaderMaterial} */ this.material = null; if ( shader instanceof ShaderMaterial ) { this.uniforms = shader.uniforms; this.material = shader; } else if ( shader ) { this.uniforms = UniformsUtils.clone( shader.uniforms ); this.material = new ShaderMaterial( { name: ( shader.name !== undefined ) ? shader.name : 'unspecified', defines: Object.assign( {}, shader.defines ), uniforms: this.uniforms, vertexShader: shader.vertexShader, fragmentShader: shader.fragmentShader } ); } // internals this._fsQuad = new FullScreenQuad( this.material ); } /** * Performs the shader pass. * * @param {WebGLRenderer} renderer - The renderer. * @param {WebGLRenderTarget} writeBuffer - The write buffer. This buffer is intended as the rendering * destination for the pass. * @param {WebGLRenderTarget} readBuffer - The read buffer. The pass can access the result from the * previous pass from this buffer. * @param {number} deltaTime - The delta time in seconds. * @param {boolean} maskActive - Whether masking is active or not. */ render( renderer, writeBuffer, readBuffer /*, deltaTime, maskActive */ ) { if ( this.uniforms[ this.textureID ] ) { this.uniforms[ this.textureID ].value = readBuffer.texture; } this._fsQuad.material = this.material; if ( this.renderToScreen ) { renderer.setRenderTarget( null ); this._fsQuad.render( renderer ); } else { renderer.setRenderTarget( writeBuffer ); // TODO: Avoid using autoClear properties, see https://github.com/mrdoob/three.js/pull/15571#issuecomment-465669600 if ( this.clear ) renderer.clear( renderer.autoClearColor, renderer.autoClearDepth, renderer.autoClearStencil ); this._fsQuad.render( renderer ); } } /** * Frees the GPU-related resources allocated by this instance. Call this * method whenever the pass is no longer used in your app. */ dispose() { this.material.dispose(); this._fsQuad.dispose(); } } export { ShaderPass };