Pārlūkot izejas kodu

Remove DualKawaseBloomNode. (#33979)

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
mrdoob 2 nedēļas atpakaļ
vecāks
revīzija
fe787b29ec

+ 0 - 596
examples/jsm/tsl/display/DualKawaseBloomNode.js

@@ -1,596 +0,0 @@
-import { HalfFloatType, RenderTarget, Vector2, TempNode, QuadMesh, NodeMaterial, RendererUtils, NodeUpdateType } from 'three/webgpu';
-import { nodeObject, Fn, float, vec2, uv, passTexture, uniform, texture, luminance, smoothstep, mix, vec4 } from 'three/tsl';
-
-const _quadMesh = /*@__PURE__*/ new QuadMesh();
-const _size = /*@__PURE__*/ new Vector2();
-
-let _rendererState;
-
-const luminosityHighPass = Fn( ( { input, threshold, smoothWidth } ) => {
-
-	const v = luminance( input.rgb );
-	const alpha = smoothstep( threshold, threshold.add( smoothWidth ), v );
-
-	return mix( vec4( 0 ), input, alpha );
-
-} );
-
-/**
- * Post processing node for creating a bloom effect.
- *
- * The bloom is produced with a Dual Kawase blur: the bright areas are
- * progressively downsampled with a 5-tap filter and then upsampled with an
- * 8-tap filter, accumulating the levels back together.
- * ```js
- * const renderPipeline = new THREE.RenderPipeline( renderer );
- *
- * const scenePass = pass( scene, camera );
- * const scenePassColor = scenePass.getTextureNode( 'output' );
- *
- * const bloomPass = dualKawaseBloom( scenePassColor );
- *
- * renderPipeline.outputNode = scenePassColor.add( bloomPass );
- * ```
- * By default, the node affects the entire image. For a selective bloom,
- * use the `emissive` material property to control which objects should
- * contribute to bloom or not. This can be achieved via MRT.
- * ```js
- * const renderPipeline = new THREE.RenderPipeline( renderer );
- *
- * const scenePass = pass( scene, camera );
- * scenePass.setMRT( mrt( {
- * 	output,
- * 	emissive
- * } ) );
- *
- * const scenePassColor = scenePass.getTextureNode( 'output' );
- * const emissivePass = scenePass.getTextureNode( 'emissive' );
- *
- * const bloomPass = dualKawaseBloom( emissivePass );
- * renderPipeline.outputNode = scenePassColor.add( bloomPass );
- * ```
- * @augments TempNode
- * @three_import import { dualKawaseBloom } from 'three/addons/tsl/display/DualKawaseBloomNode.js';
- */
-class DualKawaseBloomNode extends TempNode {
-
-	static get type() {
-
-		return 'DualKawaseBloomNode';
-
-	}
-
-	/**
-	 * Constructs a new bloom node.
-	 *
-	 * @param {Node<vec4>} inputNode - The node that represents the input of the effect.
-	 * @param {number} [strength=1] - The strength of the bloom.
-	 * @param {number} [radius=0] - The radius of the bloom.
-	 * @param {number} [threshold=0] - The luminance threshold limits which bright areas contribute to the bloom effect.
-	 */
-	constructor( inputNode, strength = 1, radius = 0, threshold = 0 ) {
-
-		super( 'vec4' );
-
-		/**
-		 * The node that represents the input of the effect.
-		 *
-		 * @type {Node<vec4>}
-		 */
-		this.inputNode = inputNode;
-
-		/**
-		 * The strength of the bloom.
-		 *
-		 * @type {UniformNode<float>}
-		 */
-		this.strength = strength.isNode ? strength : uniform( strength );
-
-		/**
-		 * The radius of the bloom. Must be in the range `[0,1]`.
-		 *
-		 * @type {UniformNode<float>}
-		 */
-		this.radius = radius.isNode ? radius : uniform( radius );
-
-		/**
-		 * The luminance threshold limits which bright areas contribute to the bloom effect.
-		 *
-		 * @type {UniformNode<float>}
-		 */
-		this.threshold = threshold.isNode ? threshold : uniform( threshold );
-
-		/**
-		 * Can be used to tweak the extracted luminance from the scene.
-		 *
-		 * @type {UniformNode<float>}
-		 */
-		this.smoothWidth = uniform( 0.01 );
-
-		/**
-		 * Scale factor for the internal render targets.
-		 *
-		 * @private
-		 * @type {number}
-		 * @default 0.5
-		 */
-		this._resolutionScale = 0.5;
-
-		/**
-		 * Can be used to inject a custom high pass filter (e.g., for anamorphic effects).
-		 *
-		 * @type {Function}
-		 */
-		this.highPassFn = luminosityHighPass;
-
-		/**
-		 * The number of downsample / upsample levels in the Dual Kawase pyramid.
-		 *
-		 * @private
-		 * @type {number}
-		 */
-		this._nMips = 6;
-
-		/**
-		 * Sample spread of the Dual Kawase filters. Kept small so each level's kernel
-		 * stays round (a wide offset makes the diamond sampling pattern visible as a
-		 * square halo); the bloom width comes from the depth of the pyramid instead.
-		 *
-		 * @private
-		 * @type {UniformNode<float>}
-		 */
-		this._offset = uniform( 3 );
-
-		/**
-		 * Per-level mixing factors, redistributed by `radius` between a tight and a wide bloom.
-		 * A linear ramp from `1.0` to `0.2` (mean `0.6`) keeps the total bloom energy constant
-		 * as `radius` shifts weight between the fine and coarse levels.
-		 *
-		 * @private
-		 * @type {Array<number>}
-		 */
-		this._bloomFactors = [];
-
-		for ( let i = 0; i < this._nMips; i ++ ) {
-
-			this._bloomFactors.push( this._nMips === 1 ? 0.6 : 1.0 - 0.8 * i / ( this._nMips - 1 ) );
-
-		}
-
-		/**
-		 * The render target for the luminance pass.
-		 *
-		 * @private
-		 * @type {RenderTarget}
-		 */
-		this._renderTargetBright = new RenderTarget( 1, 1, { depthBuffer: false, type: HalfFloatType } );
-		this._renderTargetBright.texture.name = 'DualKawaseBloom.bright';
-		this._renderTargetBright.texture.generateMipmaps = false;
-
-		/**
-		 * The render targets for the downsample chain.
-		 *
-		 * @private
-		 * @type {Array<RenderTarget>}
-		 */
-		this._downsampleRTs = [];
-
-		/**
-		 * The render targets for the upsample / accumulation chain.
-		 *
-		 * @private
-		 * @type {Array<RenderTarget>}
-		 */
-		this._accumRTs = [];
-
-		/**
-		 * The resolution of each pyramid level.
-		 *
-		 * @private
-		 * @type {Array<Vector2>}
-		 */
-		this._levelSizes = [];
-
-		/**
-		 * The resolution of the bright pass.
-		 *
-		 * @private
-		 * @type {Vector2}
-		 */
-		this._brightSize = new Vector2();
-
-		for ( let i = 0; i < this._nMips; i ++ ) {
-
-			const downsampleRT = new RenderTarget( 1, 1, { depthBuffer: false, type: HalfFloatType } );
-			downsampleRT.texture.name = 'DualKawaseBloom.down' + i;
-			downsampleRT.texture.generateMipmaps = false;
-			this._downsampleRTs.push( downsampleRT );
-
-			const accumRT = new RenderTarget( 1, 1, { depthBuffer: false, type: HalfFloatType } );
-			accumRT.texture.name = 'DualKawaseBloom.up' + i;
-			accumRT.texture.generateMipmaps = false;
-			this._accumRTs.push( accumRT );
-
-			this._levelSizes.push( new Vector2() );
-
-		}
-
-		/**
-		 * The material for the luminance pass.
-		 *
-		 * @private
-		 * @type {?NodeMaterial}
-		 */
-		this._highPassFilterMaterial = null;
-
-		/**
-		 * The material for the downsample pass.
-		 *
-		 * @private
-		 * @type {?NodeMaterial}
-		 */
-		this._downsampleMaterial = null;
-
-		/**
-		 * The material for the upsample / accumulation pass.
-		 *
-		 * @private
-		 * @type {?NodeMaterial}
-		 */
-		this._upsampleMaterial = null;
-
-		/**
-		 * The result of the effect is represented as a separate texture node.
-		 * The finest accumulation target holds the composited bloom.
-		 *
-		 * @private
-		 * @type {PassTextureNode}
-		 */
-		this._textureOutput = passTexture( this, this._accumRTs[ 0 ].texture );
-
-		/**
-		 * The `updateBeforeType` is set to `NodeUpdateType.FRAME` since the node renders
-		 * its effect once per frame in `updateBefore()`.
-		 *
-		 * @type {string}
-		 * @default 'frame'
-		 */
-		this.updateBeforeType = NodeUpdateType.FRAME;
-
-	}
-
-	/**
-	 * Returns the result of the effect as a texture node.
-	 *
-	 * @return {PassTextureNode} A texture node that represents the result of the effect.
-	 */
-	getTextureNode() {
-
-		return this._textureOutput;
-
-	}
-
-	/**
-	 * Sets the resolution scale for the pass.
-	 * The resolution scale is a factor that is multiplied with the renderer's width and height.
-	 *
-	 * @param {number} resolutionScale - The resolution scale to set. A value of `1` means full resolution.
-	 * @return {DualKawaseBloomNode} A reference to this node.
-	 */
-	setResolutionScale( resolutionScale ) {
-
-		this._resolutionScale = resolutionScale;
-
-		return this;
-
-	}
-
-	/**
-	 * Gets the current resolution scale of the pass.
-	 *
-	 * @return {number} The current resolution scale. A value of `1` means full resolution.
-	 */
-	getResolutionScale() {
-
-		return this._resolutionScale;
-
-	}
-
-	/**
-	 * Sets the size of the effect.
-	 *
-	 * @param {number} width - The width of the effect.
-	 * @param {number} height - The height of the effect.
-	 */
-	setSize( width, height ) {
-
-		const resx = Math.max( 1, Math.floor( width * this._resolutionScale ) );
-		const resy = Math.max( 1, Math.floor( height * this._resolutionScale ) );
-
-		this._renderTargetBright.setSize( resx, resy );
-		this._brightSize.set( resx, resy );
-
-		let rx = resx;
-		let ry = resy;
-
-		for ( let i = 0; i < this._nMips; i ++ ) {
-
-			// Level 0 blurs in place at bright resolution; the rest halve.
-
-			if ( i > 0 ) {
-
-				rx = Math.max( 1, Math.floor( rx / 2 ) );
-				ry = Math.max( 1, Math.floor( ry / 2 ) );
-
-			}
-
-			this._downsampleRTs[ i ].setSize( rx, ry );
-			this._accumRTs[ i ].setSize( rx, ry );
-			this._levelSizes[ i ].set( rx, ry );
-
-		}
-
-	}
-
-	/**
-	 * This method is used to render the effect once per frame.
-	 *
-	 * @param {NodeFrame} frame - The current node frame.
-	 */
-	updateBefore( frame ) {
-
-		const { renderer } = frame;
-
-		_rendererState = RendererUtils.resetRendererState( renderer, _rendererState );
-
-		//
-
-		const size = renderer.getDrawingBufferSize( _size );
-		this.setSize( size.width, size.height );
-
-		const nMips = this._nMips;
-		const downMaterial = this._downsampleMaterial;
-		const upMaterial = this._upsampleMaterial;
-
-		// 1. Extract bright areas
-
-		renderer.setRenderTarget( this._renderTargetBright );
-		_quadMesh.material = this._highPassFilterMaterial;
-		_quadMesh.name = 'Dual Kawase Bloom [ High Pass ]';
-		_quadMesh.render( renderer );
-
-		// 2. Downsample chain ( bright -> down0 -> down1 -> ... ). The coarsest level
-		// pre-multiplies its `radius` weight so the upsample chain can seed from it.
-
-		_quadMesh.material = downMaterial;
-
-		let sourceTexture = this._renderTargetBright.texture;
-		let sourceSize = this._brightSize;
-
-		for ( let i = 0; i < nMips; i ++ ) {
-
-			const isCoarsest = ( i === nMips - 1 );
-
-			downMaterial.colorTexture.value = sourceTexture;
-			downMaterial.texelSize.value.set( 1 / sourceSize.x, 1 / sourceSize.y );
-			downMaterial.applyWeight.value = isCoarsest ? 1 : 0;
-			downMaterial.bloomFactor.value = this._bloomFactors[ i ];
-			renderer.setRenderTarget( this._downsampleRTs[ i ] );
-			_quadMesh.name = `Dual Kawase Bloom [ Downsample - ${ i } ]`;
-			_quadMesh.render( renderer );
-
-			sourceTexture = this._downsampleRTs[ i ].texture;
-			sourceSize = this._levelSizes[ i ];
-
-		}
-
-		// 3. Upsample chain with weighted accumulation ( ... -> up1 -> up0 ).
-		// Each level adds its matching downsample weighted by `radius`; the
-		// coarsest downsample seeds the chain. The finest step ( i = 0 ) lands at
-		// bright resolution and applies `strength`, so it doubles as the composite.
-
-		_quadMesh.material = upMaterial;
-
-		for ( let i = nMips - 2; i >= 0; i -- ) {
-
-			const isSeed = ( i === nMips - 2 );
-
-			upMaterial.finalFlag.value = ( i === 0 ) ? 1 : 0;
-			upMaterial.bloomFactor.value = this._bloomFactors[ i ];
-			upMaterial.prevTexture.value = isSeed ? this._downsampleRTs[ i + 1 ].texture : this._accumRTs[ i + 1 ].texture;
-			upMaterial.addTexture.value = this._downsampleRTs[ i ].texture;
-			upMaterial.texelSize.value.set( 1 / this._levelSizes[ i + 1 ].x, 1 / this._levelSizes[ i + 1 ].y );
-
-			renderer.setRenderTarget( this._accumRTs[ i ] );
-			_quadMesh.name = ( i === 0 ) ? 'Dual Kawase Bloom [ Composite ]' : `Dual Kawase Bloom [ Upsample - ${ i } ]`;
-			_quadMesh.render( renderer );
-
-		}
-
-		// restore
-
-		RendererUtils.restoreRendererState( renderer, _rendererState );
-
-	}
-
-	/**
-	 * This method is used to setup the effect's TSL code.
-	 *
-	 * @param {NodeBuilder} builder - The current node builder.
-	 * @return {PassTextureNode}
-	 */
-	setup( builder ) {
-
-		// luminosity high pass material
-
-		this._highPassFilterMaterial = this._highPassFilterMaterial || new NodeMaterial();
-		this._highPassFilterMaterial.fragmentNode = this.highPassFn( { input: this.inputNode, threshold: this.threshold, smoothWidth: this.smoothWidth } ).context( builder.getSharedContext() );
-		this._highPassFilterMaterial.name = 'DualKawaseBloom_highPass';
-		this._highPassFilterMaterial.needsUpdate = true;
-
-		// downsample material ( Dual Kawase, 5 taps )
-
-		this._downsampleMaterial = this._downsampleMaterial || this._getDownsampleMaterial( builder );
-
-		// upsample material ( Dual Kawase, 8 taps, weighted accumulation )
-
-		this._upsampleMaterial = this._upsampleMaterial || this._getUpsampleMaterial( builder );
-
-		//
-
-		return this._textureOutput;
-
-	}
-
-	/**
-	 * Frees internal resources. This method should be called
-	 * when the effect is no longer required.
-	 */
-	dispose() {
-
-		this._renderTargetBright.dispose();
-
-		for ( let i = 0; i < this._nMips; i ++ ) {
-
-			this._downsampleRTs[ i ].dispose();
-			this._accumRTs[ i ].dispose();
-
-		}
-
-		if ( this._highPassFilterMaterial !== null ) this._highPassFilterMaterial.dispose();
-		if ( this._downsampleMaterial !== null ) this._downsampleMaterial.dispose();
-		if ( this._upsampleMaterial !== null ) this._upsampleMaterial.dispose();
-
-	}
-
-	/**
-	 * Creates the Dual Kawase downsample material. Each output texel reads the
-	 * center plus four diagonal corners of the source.
-	 *
-	 * @private
-	 * @param {NodeBuilder} builder - The current node builder.
-	 * @return {NodeMaterial}
-	 */
-	_getDownsampleMaterial( builder ) {
-
-		const colorTexture = texture( null );
-		const texelSize = uniform( new Vector2() );
-		const offset = this._offset;
-
-		const applyWeight = uniform( 0 );
-		const bloomFactor = uniform( 1 );
-
-		const uvNode = uv();
-
-		const downsamplePass = Fn( () => {
-
-			const o = texelSize.mul( 0.5 ).mul( offset );
-
-			const color = colorTexture.sample( uvNode ).mul( 4.0 ).toVar();
-
-			color.addAssign( colorTexture.sample( uvNode.add( vec2( o.x.negate(), o.y.negate() ) ) ) );
-			color.addAssign( colorTexture.sample( uvNode.add( vec2( o.x, o.y.negate() ) ) ) );
-			color.addAssign( colorTexture.sample( uvNode.add( vec2( o.x.negate(), o.y ) ) ) );
-			color.addAssign( colorTexture.sample( uvNode.add( vec2( o.x, o.y ) ) ) );
-
-			// The coarsest level pre-applies its `radius` weight so it can seed the upsample chain.
-			const weight = mix( bloomFactor, float( 1.2 ).sub( bloomFactor ), this.radius );
-
-			return vec4( color.rgb.div( 8.0 ).mul( mix( float( 1.0 ), weight, applyWeight ) ), 1.0 );
-
-		} );
-
-		const material = new NodeMaterial();
-		material.fragmentNode = downsamplePass().context( builder.getSharedContext() );
-		material.name = 'DualKawaseBloom_down';
-		material.needsUpdate = true;
-
-		material.colorTexture = colorTexture;
-		material.texelSize = texelSize;
-		material.applyWeight = applyWeight;
-		material.bloomFactor = bloomFactor;
-
-		return material;
-
-	}
-
-	/**
-	 * Creates the Dual Kawase upsample material. Each output texel reads four
-	 * edge centers and four diagonal corners of the source, then accumulates the
-	 * matching downsample level weighted by `radius`.
-	 *
-	 * @private
-	 * @param {NodeBuilder} builder - The current node builder.
-	 * @return {NodeMaterial}
-	 */
-	_getUpsampleMaterial( builder ) {
-
-		const prevTexture = texture( null );
-		const addTexture = texture( null );
-		const texelSize = uniform( new Vector2() );
-		const offset = this._offset;
-
-		const finalFlag = uniform( 0 );
-		const bloomFactor = uniform( 1 );
-
-		const uvNode = uv();
-
-		const upsamplePass = Fn( () => {
-
-			const o = texelSize.mul( 0.5 ).mul( offset );
-
-			const sum = prevTexture.sample( uvNode.add( vec2( o.x.mul( - 2.0 ), 0.0 ) ) ).rgb.toVar();
-			sum.addAssign( prevTexture.sample( uvNode.add( vec2( o.x.mul( 2.0 ), 0.0 ) ) ).rgb );
-			sum.addAssign( prevTexture.sample( uvNode.add( vec2( 0.0, o.y.mul( - 2.0 ) ) ) ).rgb );
-			sum.addAssign( prevTexture.sample( uvNode.add( vec2( 0.0, o.y.mul( 2.0 ) ) ) ).rgb );
-
-			sum.addAssign( prevTexture.sample( uvNode.add( vec2( o.x.negate(), o.y ) ) ).rgb.mul( 2.0 ) );
-			sum.addAssign( prevTexture.sample( uvNode.add( vec2( o.x, o.y ) ) ).rgb.mul( 2.0 ) );
-			sum.addAssign( prevTexture.sample( uvNode.add( vec2( o.x.negate(), o.y.negate() ) ) ).rgb.mul( 2.0 ) );
-			sum.addAssign( prevTexture.sample( uvNode.add( vec2( o.x, o.y.negate() ) ) ).rgb.mul( 2.0 ) );
-
-			const blurred = sum.div( 12.0 );
-
-			// redistribute the level's contribution between a tight and a wide bloom
-			const weight = mix( bloomFactor, float( 1.2 ).sub( bloomFactor ), this.radius );
-			const added = addTexture.sample( uvNode ).rgb.mul( weight );
-
-			// keep the total intensity independent of the level count ( the factors sum to `_nMips * 0.6` )
-			const norm = 3 / ( this._nMips * 0.6 );
-			const result = blurred.add( added ).mul( mix( float( 1.0 ), this.strength.mul( norm ), finalFlag ) );
-
-			return vec4( result, 1.0 );
-
-		} );
-
-		const material = new NodeMaterial();
-		material.fragmentNode = upsamplePass().context( builder.getSharedContext() );
-		material.name = 'DualKawaseBloom_up';
-		material.needsUpdate = true;
-
-		material.prevTexture = prevTexture;
-		material.addTexture = addTexture;
-		material.texelSize = texelSize;
-		material.finalFlag = finalFlag;
-		material.bloomFactor = bloomFactor;
-
-		return material;
-
-	}
-
-}
-
-/**
- * TSL function for creating a bloom effect.
- *
- * @tsl
- * @function
- * @param {Node<vec4>} node - The node that represents the input of the effect.
- * @param {number} [strength=1] - The strength of the bloom.
- * @param {number} [radius=0] - The radius of the bloom.
- * @param {number} [threshold=0] - The luminance threshold limits which bright areas contribute to the bloom effect.
- * @returns {DualKawaseBloomNode}
- */
-export const dualKawaseBloom = ( node, strength, radius, threshold ) => new DualKawaseBloomNode( nodeObject( node ), strength, radius, threshold );
-
-export default DualKawaseBloomNode;

+ 21 - 24
examples/webgpu_postprocessing_bloom.html

@@ -20,7 +20,7 @@
 			</div>
 
 			<small>
-				Gaussian bloom by <a href="http://eduperiment.com" target="_blank" rel="noopener">Prashant Sharma</a> and <a href="https://clara.io" target="_blank" rel="noopener">Ben Houston</a>.<br/>
+				Bloom pass by <a href="http://eduperiment.com" target="_blank" rel="noopener">Prashant Sharma</a> and <a href="https://clara.io" target="_blank" rel="noopener">Ben Houston</a>.<br/>
 				<a href="https://blog.sketchfab.com/art-spotlight-primary-ion-drive/" target="_blank" rel="noopener">Primary Ion Drive</a>
 				by <a href="http://mjmurdock.com/" target="_blank" rel="noopener">Mike Murdock</a> is licensed under <a href="https://creativecommons.org/licenses/by/4.0/" target="_blank" rel="noopener">Creative Commons Attribution</a>.<br />
 			</small>
@@ -40,9 +40,8 @@
 		<script type="module">
 
 			import * as THREE from 'three/webgpu';
-			import { pass, uniform } from 'three/tsl';
+			import { pass } from 'three/tsl';
 			import { bloom } from 'three/addons/tsl/display/BloomNode.js';
-			import { dualKawaseBloom } from 'three/addons/tsl/display/DualKawaseBloomNode.js';
 
 			import { Inspector } from 'three/addons/inspector/Inspector.js';
 
@@ -54,7 +53,9 @@
 			let renderPipeline, renderer, mixer, timer;
 
 			const params = {
-				type: 'Gaussian',
+				threshold: 0,
+				strength: 1,
+				radius: 0,
 				exposure: 1
 			};
 
@@ -115,23 +116,9 @@
 				const scenePass = pass( scene, camera, config );
 				const scenePassColor = scenePass.getTextureNode( 'output' ).toInspector( 'Color' );
 
-				const strength = uniform( 1 );
-				const radius = uniform( 0 );
-				const threshold = uniform( 0 );
+				const bloomPass = bloom( scenePassColor ).toInspector( 'Bloom' );
 
-				const bloomPasses = {
-					'Gaussian': bloom( scenePassColor, strength, radius, threshold ),
-					'Dual Kawase': dualKawaseBloom( scenePassColor, strength, radius, threshold )
-				};
-
-				function updateBloom() {
-
-					renderPipeline.outputNode = scenePassColor.add( bloomPasses[ params.type ] );
-					renderPipeline.needsUpdate = true;
-
-				}
-
-				updateBloom();
+				renderPipeline.outputNode = scenePassColor.add( bloomPass );
 
 				//
 
@@ -146,13 +133,23 @@
 
 				const bloomFolder = gui.addFolder( 'bloom' );
 
-				bloomFolder.add( params, 'type', [ 'Gaussian', 'Dual Kawase' ] ).onChange( updateBloom );
+				bloomFolder.add( params, 'threshold', 0.0, 1.0 ).onChange( function ( value ) {
+
+					bloomPass.threshold.value = value;
 
-				bloomFolder.add( threshold, 'value', 0.0, 1.0 ).name( 'threshold' );
+				} );
+
+				bloomFolder.add( params, 'strength', 0.0, 3.0 ).onChange( function ( value ) {
 
-				bloomFolder.add( strength, 'value', 0.0, 3.0 ).name( 'strength' );
+					bloomPass.strength.value = value;
+
+				} );
 
-				bloomFolder.add( radius, 'value', 0.0, 1.0, 0.01 ).name( 'radius' );
+				bloomFolder.add( params, 'radius', 0.0, 1.0, 0.01 ).onChange( function ( value ) {
+
+					bloomPass.radius.value = value;
+
+				} );
 
 				const toneMappingFolder = gui.addFolder( 'tone mapping' );
 

+ 5 - 23
examples/webgpu_postprocessing_bloom_emissive.html

@@ -36,9 +36,8 @@
 		<script type="module">
 
 			import * as THREE from 'three/webgpu';
-			import { pass, mrt, output, emissive, vec4, uniform } from 'three/tsl';
+			import { pass, mrt, output, emissive, vec4 } from 'three/tsl';
 			import { bloom } from 'three/addons/tsl/display/BloomNode.js';
-			import { dualKawaseBloom } from 'three/addons/tsl/display/DualKawaseBloomNode.js';
 
 			import { HDRLoader } from 'three/addons/loaders/HDRLoader.js';
 
@@ -119,26 +118,10 @@
 				const outputPass = scenePass.getTextureNode().toInspector( 'Color' );
 				const emissivePass = scenePass.getTextureNode( 'emissive' ).toInspector( 'Emissive' );
 
-				const params = { type: 'Gaussian' };
-
-				const strength = uniform( 2.5 );
-				const radius = uniform( 0.5 );
-
-				const bloomPasses = {
-					'Gaussian': bloom( emissivePass, strength, radius ),
-					'Dual Kawase': dualKawaseBloom( emissivePass, strength, radius )
-				};
+				const bloomPass = bloom( emissivePass, 2.5, .5 );
 
 				renderPipeline = new THREE.RenderPipeline( renderer );
-
-				function updateBloom() {
-
-					renderPipeline.outputNode = outputPass.add( bloomPasses[ params.type ] );
-					renderPipeline.needsUpdate = true;
-
-				}
-
-				updateBloom();
+				renderPipeline.outputNode = outputPass.add( bloomPass );
 
 				//
 
@@ -155,9 +138,8 @@
 				const gui = renderer.inspector.createParameters( 'Settings' );
 
 				const bloomFolder = gui.addFolder( 'Bloom' );
-				bloomFolder.add( params, 'type', [ 'Gaussian', 'Dual Kawase' ] ).onChange( updateBloom );
-				bloomFolder.add( strength, 'value', 0.0, 5.0 ).name( 'strength' );
-				bloomFolder.add( radius, 'value', 0.0, 1.0 ).name( 'radius' );
+				bloomFolder.add( bloomPass.strength, 'value', 0.0, 5.0 ).name( 'strength' );
+				bloomFolder.add( bloomPass.radius, 'value', 0.0, 1.0 ).name( 'radius' );
 
 				const toneMappingFolder = gui.addFolder( 'Tone Mapping' );
 				toneMappingFolder.add( renderer, 'toneMappingExposure', 0.1, 2 ).name( 'exposure' );

+ 5 - 25
examples/webgpu_postprocessing_bloom_selective.html

@@ -38,7 +38,6 @@
 			import * as THREE from 'three/webgpu';
 			import { pass, mrt, output, float, uniform } from 'three/tsl';
 			import { bloom } from 'three/addons/tsl/display/BloomNode.js';
-			import { dualKawaseBloom } from 'three/addons/tsl/display/DualKawaseBloomNode.js';
 
 			import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
 
@@ -97,29 +96,11 @@
 			const outputPass = scenePass.getTextureNode().toInspector( 'Color' );
 			const bloomIntensityPass = scenePass.getTextureNode( 'bloomIntensity' ).toInspector( 'Bloom Intensity' );
 
-			const params = { type: 'Gaussian' };
-			const bloomInput = outputPass.mul( bloomIntensityPass );
-
-			const strength = uniform( 1 );
-			const radius = uniform( 0 );
-			const threshold = uniform( 0 );
-
-			const bloomPasses = {
-				'Gaussian': bloom( bloomInput, strength, radius, threshold ),
-				'Dual Kawase': dualKawaseBloom( bloomInput, strength, radius, threshold )
-			};
+			const bloomPass = bloom( outputPass.mul( bloomIntensityPass ) );
 
 			const renderPipeline = new THREE.RenderPipeline( renderer );
 			renderPipeline.outputColorTransform = false;
-
-			function updateBloom() {
-
-				renderPipeline.outputNode = outputPass.add( bloomPasses[ params.type ] ).renderOutput();
-				renderPipeline.needsUpdate = true;
-
-			}
-
-			updateBloom();
+			renderPipeline.outputNode = outputPass.add( bloomPass ).renderOutput();
 
 			// controls
 
@@ -158,10 +139,9 @@
 			const gui = renderer.inspector.createParameters( 'Settings' );
 
 			const bloomFolder = gui.addFolder( 'Bloom' );
-			bloomFolder.add( params, 'type', [ 'Gaussian', 'Dual Kawase' ] ).onChange( updateBloom );
-			bloomFolder.add( threshold, 'value', 0.0, 1.0 ).name( 'threshold' );
-			bloomFolder.add( strength, 'value', 0.0, 3 ).name( 'strength' );
-			bloomFolder.add( radius, 'value', 0.0, 1.0 ).name( 'radius' );
+			bloomFolder.add( bloomPass.threshold, 'value', 0.0, 1.0 ).name( 'threshold' );
+			bloomFolder.add( bloomPass.strength, 'value', 0.0, 3 ).name( 'strength' );
+			bloomFolder.add( bloomPass.radius, 'value', 0.0, 1.0 ).name( 'radius' );
 
 			const toneMappingFolder = gui.addFolder( 'Tone Mapping' );
 			toneMappingFolder.add( renderer, 'toneMappingExposure', 0.1, 3 ).name( 'exposure' );

粤ICP备19079148号