diff --git a/examples/files.json b/examples/files.json index 39389c773481a0..abbc2ef8da3108 100644 --- a/examples/files.json +++ b/examples/files.json @@ -379,6 +379,7 @@ "webgpu_postprocessing_pixel", "webgpu_postprocessing_fxaa", "webgpu_postprocessing_sobel", + "webgpu_postprocessing_transition", "webgpu_postprocessing", "webgpu_procedural_texture", "webgpu_reflection", diff --git a/examples/screenshots/webgpu_postprocessing_transition.jpg b/examples/screenshots/webgpu_postprocessing_transition.jpg new file mode 100644 index 00000000000000..1e0cccd8471033 Binary files /dev/null and b/examples/screenshots/webgpu_postprocessing_transition.jpg differ diff --git a/examples/webgpu_postprocessing_transition.html b/examples/webgpu_postprocessing_transition.html new file mode 100644 index 00000000000000..1a23923f68b1b3 --- /dev/null +++ b/examples/webgpu_postprocessing_transition.html @@ -0,0 +1,265 @@ + + + + three.js webgpu - scenes transition + + + + + + +
+ three.js webgpu scene transitions.
+ Original implementation by fernandojsg - github +
+ + + + + + diff --git a/src/nodes/Nodes.js b/src/nodes/Nodes.js index 348ce958598285..b7439ab67a7bce 100644 --- a/src/nodes/Nodes.js +++ b/src/nodes/Nodes.js @@ -138,6 +138,7 @@ export { default as GTAONode, ao } from './display/GTAONode.js'; export { default as DenoiseNode, denoise } from './display/DenoiseNode.js'; export { default as FXAANode, fxaa } from './display/FXAANode.js'; export { default as BloomNode, bloom } from './display/BloomNode.js'; +export { default as TransitionNode, transition } from './display/TransitionNode.js'; export { default as RenderOutputNode, renderOutput } from './display/RenderOutputNode.js'; export { default as PixelationPassNode, pixelationPass } from './display/PixelationPassNode.js'; diff --git a/src/nodes/display/TransitionNode.js b/src/nodes/display/TransitionNode.js new file mode 100644 index 00000000000000..e911d85b28b459 --- /dev/null +++ b/src/nodes/display/TransitionNode.js @@ -0,0 +1,76 @@ +import TempNode from '../core/TempNode.js'; +import { uv } from '../accessors/UVNode.js'; +import { addNodeElement, tslFn, nodeObject, float, int, vec4, If } from '../shadernode/ShaderNode.js'; +import { clamp, mix } from '../math/MathNode.js'; +import { sub } from '../math/OperatorNode.js'; + +class TransitionNode extends TempNode { + + constructor( textureNodeA, textureNodeB, mixTextureNode, mixRatioNode, thresholdNode, useTextureNode ) { + + super(); + + // Input textures + + this.textureNodeA = textureNodeA; + this.textureNodeB = textureNodeB; + this.mixTextureNode = mixTextureNode; + + // Uniforms + + this.mixRatioNode = mixRatioNode; + this.thresholdNode = thresholdNode; + this.useTextureNode = useTextureNode; + + } + + setup() { + + const { textureNodeA, textureNodeB, mixTextureNode, mixRatioNode, thresholdNode, useTextureNode } = this; + + const sampleTexture = ( textureNode ) => { + + const uvNodeTexture = textureNode.uvNode || uv(); + return textureNode.uv( uvNodeTexture ); + + }; + + const transition = tslFn( () => { + + const texelOne = sampleTexture( textureNodeA ); + const texelTwo = sampleTexture( textureNodeB ); + + const color = vec4().toVar(); + + If( useTextureNode.equal( int( 1 ) ), () => { + + const transitionTexel = sampleTexture( mixTextureNode ); + const r = mixRatioNode.mul( thresholdNode.mul( 2.0 ).add( 1.0 ) ).sub( thresholdNode ); + const mixf = clamp( sub( transitionTexel.r, r ).mul( float( 1.0 ).div( thresholdNode ) ), 0.0, 1.0 ); + + color.assign( mix( texelOne, texelTwo, mixf ) ); + + } ).else( () => { + + color.assign( mix( texelTwo, texelOne, mixRatioNode ) ); + + } ); + + return color; + + } ); + + const outputNode = transition(); + + return outputNode; + + } + +} + +export const transition = ( nodeA, nodeB, mixTexture, mixRatio = 0.0, threshold = 0.1, useTexture = 0 ) => nodeObject( new TransitionNode( nodeObject( nodeA ).toTexture(), nodeObject( nodeB ).toTexture(), nodeObject( mixTexture ).toTexture(), nodeObject( mixRatio ), nodeObject( threshold ), nodeObject( useTexture ) ) ); + +addNodeElement( 'transition', transition ); + +export default TransitionNode; +