From f7708b66d93bfb0f6b73d15fe71e66fc4a466a29 Mon Sep 17 00:00:00 2001 From: sunag Date: Sat, 15 Nov 2025 04:22:18 -0300 Subject: [PATCH 01/14] add global context --- src/Three.TSL.js | 1 + src/materials/nodes/NodeMaterial.js | 38 ++++++++++- .../nodes/manager/NodeMaterialObserver.js | 2 +- src/nodes/Nodes.js | 1 + src/nodes/TSL.js | 1 + src/nodes/accessors/ModelNode.js | 2 +- src/nodes/accessors/Normal.js | 4 +- src/nodes/core/GlobalContextNode.js | 66 +++++++++++++++++++ src/renderers/common/RenderObject.js | 2 +- src/renderers/common/Renderer.js | 27 ++++---- 10 files changed, 125 insertions(+), 19 deletions(-) create mode 100644 src/nodes/core/GlobalContextNode.js diff --git a/src/Three.TSL.js b/src/Three.TSL.js index e31e626a38a2b9..fd0bb05e4f0b26 100644 --- a/src/Three.TSL.js +++ b/src/Three.TSL.js @@ -211,6 +211,7 @@ export const getShadowRenderObjectFunction = TSL.getShadowRenderObjectFunction; export const getTextureIndex = TSL.getTextureIndex; export const getViewPosition = TSL.getViewPosition; export const globalId = TSL.globalId; +export const globalContext = TSL.globalContext; export const glsl = TSL.glsl; export const glslFn = TSL.glslFn; export const grayscale = TSL.grayscale; diff --git a/src/materials/nodes/NodeMaterial.js b/src/materials/nodes/NodeMaterial.js index a976d86a22db20..95010e2d20a6a7 100644 --- a/src/materials/nodes/NodeMaterial.js +++ b/src/materials/nodes/NodeMaterial.js @@ -25,7 +25,7 @@ import { modelViewMatrix } from '../../nodes/accessors/ModelNode.js'; import { vertexColor } from '../../nodes/accessors/VertexColorNode.js'; import { premultiplyAlpha } from '../../nodes/display/BlendModes.js'; import { subBuild } from '../../nodes/core/SubBuildNode.js'; -import { warn } from '../../utils.js'; +import { error, warn } from '../../utils.js'; /** * Base class for all node materials. @@ -382,6 +382,14 @@ class NodeMaterial extends Material { */ this.vertexNode = null; + /** + * This node can be used as a global context management component for this material. + * + * @type {?GlobalContextNode} + * @default null + */ + this.contextNode = null; + // Deprecated properties Object.defineProperty( this, 'shadowPositionNode', { // @deprecated, r176 @@ -489,6 +497,32 @@ class NodeMaterial extends Material { const renderer = builder.renderer; const renderTarget = renderer.getRenderTarget(); + // < CONTEXT > + + if ( renderer.globalContext.isGlobalContextNode === true ) { + + builder.context = { ...builder.context, ...renderer.globalContext.value }; + + } else { + + error( 'NodeMaterial: "renderer.globalContext" must be an instance of `globalContext()`.' ); + + } + + if ( this.contextNode !== null ) { + + if ( this.contextNode.isGlobalContextNode === true ) { + + builder.context = { ...builder.context, ...this.contextNode.value }; + + } else { + + error( 'NodeMaterial: "material.contextNode" must be an instance of `globalContext()`.' ); + + } + + } + // < VERTEX STAGE > builder.addStack(); @@ -1301,6 +1335,8 @@ class NodeMaterial extends Material { this.fragmentNode = source.fragmentNode; this.vertexNode = source.vertexNode; + this.contextNode = source.contextNode; + return super.copy( source ); } diff --git a/src/materials/nodes/manager/NodeMaterialObserver.js b/src/materials/nodes/manager/NodeMaterialObserver.js index 4f397ae3e9828e..6dabe0e75148d7 100644 --- a/src/materials/nodes/manager/NodeMaterialObserver.js +++ b/src/materials/nodes/manager/NodeMaterialObserver.js @@ -259,7 +259,7 @@ class NodeMaterialObserver { } - if ( builder.renderer.overrideNodes.modelViewMatrix !== null || builder.renderer.overrideNodes.modelNormalViewMatrix !== null ) + if ( builder.context.modelViewMatrix || builder.context.modelNormalViewMatrix ) return true; return false; diff --git a/src/nodes/Nodes.js b/src/nodes/Nodes.js index f014c97882eb72..be8d6d32f1168f 100644 --- a/src/nodes/Nodes.js +++ b/src/nodes/Nodes.js @@ -9,6 +9,7 @@ export { default as BypassNode } from './core/BypassNode.js'; export { default as IsolateNode } from './core/IsolateNode.js'; export { default as ConstNode } from './core/ConstNode.js'; export { default as ContextNode } from './core/ContextNode.js'; +export { default as GlobalContextNode } from './core/GlobalContextNode.js'; export { default as IndexNode } from './core/IndexNode.js'; export { default as LightingModel } from './core/LightingModel.js'; export { default as Node } from './core/Node.js'; diff --git a/src/nodes/TSL.js b/src/nodes/TSL.js index da2f0ca507dd54..b510d4e513bf97 100644 --- a/src/nodes/TSL.js +++ b/src/nodes/TSL.js @@ -7,6 +7,7 @@ export * from './core/AttributeNode.js'; export * from './core/BypassNode.js'; export * from './core/IsolateNode.js'; export * from './core/ContextNode.js'; +export * from './core/GlobalContextNode.js'; export * from './core/IndexNode.js'; export * from './core/ParameterNode.js'; export * from './core/PropertyNode.js'; diff --git a/src/nodes/accessors/ModelNode.js b/src/nodes/accessors/ModelNode.js index dd7293249bbf26..196c29d9f09ce1 100644 --- a/src/nodes/accessors/ModelNode.js +++ b/src/nodes/accessors/ModelNode.js @@ -123,7 +123,7 @@ export const modelWorldMatrixInverse = /*@__PURE__*/ uniform( new Matrix4() ).on */ export const modelViewMatrix = /*@__PURE__*/ ( Fn( ( builder ) => { - return builder.renderer.overrideNodes.modelViewMatrix || mediumpModelViewMatrix; + return builder.context.modelViewMatrix || mediumpModelViewMatrix; } ).once() )().toVar( 'modelViewMatrix' ); diff --git a/src/nodes/accessors/Normal.js b/src/nodes/accessors/Normal.js index 4701974a8961a7..a9134c2adf5697 100644 --- a/src/nodes/accessors/Normal.js +++ b/src/nodes/accessors/Normal.js @@ -182,9 +182,9 @@ export const transformNormal = /*@__PURE__*/ Fn( ( [ normal, matrix = modelWorld */ export const transformNormalToView = /*@__PURE__*/ Fn( ( [ normal ], builder ) => { - const modelNormalViewMatrix = builder.renderer.overrideNodes.modelNormalViewMatrix; + const modelNormalViewMatrix = builder.context.modelNormalViewMatrix; - if ( modelNormalViewMatrix !== null ) { + if ( modelNormalViewMatrix ) { return modelNormalViewMatrix.transformDirection( normal ); diff --git a/src/nodes/core/GlobalContextNode.js b/src/nodes/core/GlobalContextNode.js new file mode 100644 index 00000000000000..021be05483d9a6 --- /dev/null +++ b/src/nodes/core/GlobalContextNode.js @@ -0,0 +1,66 @@ +import Node from './Node.js'; +import { nodeProxy } from '../tsl/TSLCore.js'; + +/** + * This node can be used as a global context management component for another node. + * {@link NodeBuilder} performs its node building process in a specific context and + * this node allows the modify the context. A typical use case is to overwrite `getUV()` e.g.: + * + * ```js + *material.contextNode = globalContext( { getUV: () => customCoord } ); + *\// or + *renderer.globalContext = globalContext( { getUV: () => customCoord } ); + *\// or + *scenePass.globalContext = globalContext( { getUV: () => customCoord } ); + *``` + * @augments Node + */ +class GlobalContextNode extends Node { + + static get type() { + + return 'GlobalContextNode'; + + } + + /** + * Constructs a new global context node. + * + * @param {Object} [value={}] - The modified context data. + */ + constructor( value = {} ) { + + super( 'void' ); + + /** + * This flag can be used for type testing. + * + * @type {boolean} + * @readonly + * @default true + */ + this.isGlobalContextNode = true; + + /** + * The modified context data. + * + * @type {Object} + * @default {} + */ + this.value = value; + + } + +} + +export default GlobalContextNode; + +/** + * TSL function for creating a global context node. + * + * @tsl + * @function + * @param {Object} [value={}] - The modified context data. + * @returns {GlobalContextNode} + */ +export const globalContext = /*@__PURE__*/ nodeProxy( GlobalContextNode ); diff --git a/src/renderers/common/RenderObject.js b/src/renderers/common/RenderObject.js index d02f55c564a182..351fe3074e230d 100644 --- a/src/renderers/common/RenderObject.js +++ b/src/renderers/common/RenderObject.js @@ -871,7 +871,7 @@ class RenderObject { } - cacheKey = hash( cacheKey, this.camera.id ); + cacheKey = hash( cacheKey, this.camera.id, this.renderer.globalContext.id, this.renderer.globalContext.version ); return cacheKey; diff --git a/src/renderers/common/Renderer.js b/src/renderers/common/Renderer.js index 38f9e7c0516d40..9dcf7b850dad4b 100644 --- a/src/renderers/common/Renderer.js +++ b/src/renderers/common/Renderer.js @@ -35,6 +35,7 @@ import { DoubleSide, BackSide, FrontSide, SRGBColorSpace, NoToneMapping, LinearF import { float, vec3, vec4 } from '../../nodes/tsl/TSLCore.js'; import { reference } from '../../nodes/accessors/ReferenceNode.js'; import { highpModelNormalViewMatrix, highpModelViewMatrix } from '../../nodes/accessors/ModelNode.js'; +import { globalContext } from '../../nodes/core/GlobalContextNode.js'; import { error, warn, warnOnce } from '../../utils.js'; const _scene = /*@__PURE__*/ new Scene(); @@ -222,17 +223,13 @@ class Renderer { this.info = new Info(); /** - * Stores override nodes for specific transformations or calculations. + * A global context node that stores override nodes for specific transformations or calculations. * These nodes can be used to replace default behavior in the rendering pipeline. * - * @type {Object} - * @property {?Node} modelViewMatrix - An override node for the model-view matrix. - * @property {?Node} modelNormalViewMatrix - An override node for the model normal view matrix. + * @type {GlobalContextNode} + * @property {Object} value - The context value object. */ - this.overrideNodes = { - modelViewMatrix: null, - modelNormalViewMatrix: null - }; + this.globalContext = globalContext(); /** * The node library defines how certain library objects like materials, lights @@ -1031,15 +1028,17 @@ class Renderer { */ set highPrecision( value ) { + const globalContextData = this.globalContext.value; + if ( value === true ) { - this.overrideNodes.modelViewMatrix = highpModelViewMatrix; - this.overrideNodes.modelNormalViewMatrix = highpModelNormalViewMatrix; + globalContextData.modelViewMatrix = highpModelViewMatrix; + globalContextData.modelNormalViewMatrix = highpModelNormalViewMatrix; } else if ( this.highPrecision ) { - this.overrideNodes.modelViewMatrix = null; - this.overrideNodes.modelNormalViewMatrix = null; + delete globalContextData.modelViewMatrix; + delete globalContextData.modelNormalViewMatrix; } @@ -1053,7 +1052,9 @@ class Renderer { */ get highPrecision() { - return this.overrideNodes.modelViewMatrix === highpModelViewMatrix && this.overrideNodes.modelNormalViewMatrix === highpModelNormalViewMatrix; + const globalContextData = this.globalContext.value; + + return globalContextData.modelViewMatrix === highpModelViewMatrix && globalContextData.modelNormalViewMatrix === highpModelNormalViewMatrix; } From a26d64ff3194448fdfea7af00570509b9597d41b Mon Sep 17 00:00:00 2001 From: sunag Date: Sat, 15 Nov 2025 04:23:57 -0300 Subject: [PATCH 02/14] prepass - wip --- examples/webgpu_postprocessing_ao.html | 10 + .../webgpu_postprocessing_ao_prepass.html | 244 ++++++++++++++++++ src/materials/nodes/NodeMaterial.js | 10 +- src/nodes/core/NodeFrame.js | 6 + src/nodes/display/PassNode.js | 52 ++++ 5 files changed, 321 insertions(+), 1 deletion(-) create mode 100644 examples/webgpu_postprocessing_ao_prepass.html diff --git a/examples/webgpu_postprocessing_ao.html b/examples/webgpu_postprocessing_ao.html index d72879013c49fc..334d71c561329f 100644 --- a/examples/webgpu_postprocessing_ao.html +++ b/examples/webgpu_postprocessing_ao.html @@ -148,6 +148,16 @@ model.position.set( 0, 1, 0 ); scene.add( model ); + // + + const planeRefractor = new THREE.Mesh( new THREE.PlaneGeometry( 1.8, 2 ), new THREE.MeshStandardNodeMaterial( { transparent: true, opacity: .1 } ) ); + planeRefractor.material.transparent = true; + planeRefractor.position.z = 0; + planeRefractor.position.y = 0.5; + scene.add( planeRefractor ); + + // + model.traverse( ( o ) => { // Transparent objects (e.g. loaded via GLTFLoader) might have "depthWrite" set to "false". diff --git a/examples/webgpu_postprocessing_ao_prepass.html b/examples/webgpu_postprocessing_ao_prepass.html new file mode 100644 index 00000000000000..8ec2575970238c --- /dev/null +++ b/examples/webgpu_postprocessing_ao_prepass.html @@ -0,0 +1,244 @@ + + + + three.js webgpu - ambient occlusion + + + + + + +
+ + +
+ three.jsAO +
+ + + Ambient Occlusion based on GTAO.
+ Minimalistic Modern Bedroom by + dylanheyes is licensed under Creative Commons Attribution. +
+
+ + + + + + diff --git a/src/materials/nodes/NodeMaterial.js b/src/materials/nodes/NodeMaterial.js index 95010e2d20a6a7..21918f538aa777 100644 --- a/src/materials/nodes/NodeMaterial.js +++ b/src/materials/nodes/NodeMaterial.js @@ -1052,9 +1052,17 @@ class NodeMaterial extends Material { } + let aoNode = builder.context.ao || null; + if ( this.aoNode !== null || builder.material.aoMap ) { - const aoNode = this.aoNode !== null ? this.aoNode : materialAO; + const mtlAO = this.aoNode !== null ? this.aoNode : materialAO; + + aoNode = aoNode !== null ? aoNode.mul( mtlAO ) : mtlAO; + + } + + if ( aoNode !== null ) { materialLightsNode.push( new AONode( aoNode ) ); diff --git a/src/nodes/core/NodeFrame.js b/src/nodes/core/NodeFrame.js index 932a9f2435cb78..ca64d45d9adc8a 100644 --- a/src/nodes/core/NodeFrame.js +++ b/src/nodes/core/NodeFrame.js @@ -155,6 +155,9 @@ class NodeFrame { if ( nodeUpdateBeforeMap.frameId !== this.frameId ) { + // TODO: Temp fix for recursive calls + nodeUpdateBeforeMap.frameId = this.frameId; + if ( node.updateBefore( this ) !== false ) { nodeUpdateBeforeMap.frameId = this.frameId; @@ -169,6 +172,9 @@ class NodeFrame { if ( nodeUpdateBeforeMap.renderId !== this.renderId ) { + // TODO: Temp fix for recursive calls + nodeUpdateBeforeMap.renderId = this.renderId; + if ( node.updateBefore( this ) !== false ) { nodeUpdateBeforeMap.renderId = this.renderId; diff --git a/src/nodes/display/PassNode.js b/src/nodes/display/PassNode.js index 381d31ef96640e..d2c7897a576adc 100644 --- a/src/nodes/display/PassNode.js +++ b/src/nodes/display/PassNode.js @@ -248,6 +248,36 @@ class PassNode extends TempNode { */ this.renderTarget = renderTarget; + /** + * An optional override material for the pass. + * + * @type {Material|null} + */ + this.overrideMaterial = null; + + /** + * An optional global context for the pass. + * + * @type {GlobalContextNode|null} + */ + this.globalContext = null; + + /** + * Whether the pass is transparent. + * + * @type {boolean} + * @default false + */ + this.transparent = true; + + /** + * Whether the pass is opaque. + * + * @type {boolean} + * @default true + */ + this.opaque = true; + /** * A dictionary holding the internal result textures. * @@ -738,7 +768,11 @@ class PassNode extends TempNode { const currentRenderTarget = renderer.getRenderTarget(); const currentMRT = renderer.getMRT(); const currentAutoClear = renderer.autoClear; + const currentTransparent = renderer.transparent; + const currentOpaque = renderer.opaque; const currentMask = camera.layers.mask; + const currentOverrideMaterial = scene.overrideMaterial; + const currentGlobalContext = renderer.globalContext; this._cameraNear.value = camera.near; this._cameraFar.value = camera.far; @@ -755,9 +789,23 @@ class PassNode extends TempNode { } + if ( this.overrideMaterial !== null ) { + + scene.overrideMaterial = this.overrideMaterial; + + } + renderer.setRenderTarget( this.renderTarget ); renderer.setMRT( this._mrt ); renderer.autoClear = true; + renderer.transparent = this.transparent; + renderer.opaque = this.opaque; + + if ( this.globalContext !== null ) { + + renderer.globalContext = this.globalContext; + + } const currentSceneName = scene.name; @@ -766,10 +814,14 @@ class PassNode extends TempNode { renderer.render( scene, camera ); scene.name = currentSceneName; + scene.overrideMaterial = currentOverrideMaterial; renderer.setRenderTarget( currentRenderTarget ); renderer.setMRT( currentMRT ); renderer.autoClear = currentAutoClear; + renderer.transparent = currentTransparent; + renderer.opaque = currentOpaque; + renderer.globalContext = currentGlobalContext; camera.layers.mask = currentMask; From 7aa3eb5db38ccb54a174635905aa65eb8078f478 Mon Sep 17 00:00:00 2001 From: sunag Date: Sun, 16 Nov 2025 18:47:00 -0300 Subject: [PATCH 03/14] fix resize --- src/materials/nodes/manager/NodeMaterialObserver.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/materials/nodes/manager/NodeMaterialObserver.js b/src/materials/nodes/manager/NodeMaterialObserver.js index 6dabe0e75148d7..acd815d41a1618 100644 --- a/src/materials/nodes/manager/NodeMaterialObserver.js +++ b/src/materials/nodes/manager/NodeMaterialObserver.js @@ -259,7 +259,7 @@ class NodeMaterialObserver { } - if ( builder.context.modelViewMatrix || builder.context.modelNormalViewMatrix ) + if ( builder.context.modelViewMatrix || builder.context.modelNormalViewMatrix || builder.context.ao ) return true; return false; From 2ac5f74176248f1331c962f57099c813f4f3d153 Mon Sep 17 00:00:00 2001 From: sunag Date: Sun, 16 Nov 2025 19:17:41 -0300 Subject: [PATCH 04/14] update example --- examples/webgpu_postprocessing_ao.html | 104 ++++---- .../webgpu_postprocessing_ao_prepass.html | 244 ------------------ 2 files changed, 56 insertions(+), 292 deletions(-) delete mode 100644 examples/webgpu_postprocessing_ao_prepass.html diff --git a/examples/webgpu_postprocessing_ao.html b/examples/webgpu_postprocessing_ao.html index 334d71c561329f..699485695dd1c3 100644 --- a/examples/webgpu_postprocessing_ao.html +++ b/examples/webgpu_postprocessing_ao.html @@ -36,7 +36,7 @@ - - - - From bc62baa6e5bdaf57d8f0665c83d8c291b485e3d8 Mon Sep 17 00:00:00 2001 From: sunag Date: Thu, 20 Nov 2025 23:58:04 -0300 Subject: [PATCH 05/14] remove GlobalContextNode --- src/nodes/Nodes.js | 1 - src/nodes/TSL.js | 1 - src/nodes/core/GlobalContextNode.js | 66 ----------------------------- 3 files changed, 68 deletions(-) delete mode 100644 src/nodes/core/GlobalContextNode.js diff --git a/src/nodes/Nodes.js b/src/nodes/Nodes.js index be8d6d32f1168f..f014c97882eb72 100644 --- a/src/nodes/Nodes.js +++ b/src/nodes/Nodes.js @@ -9,7 +9,6 @@ export { default as BypassNode } from './core/BypassNode.js'; export { default as IsolateNode } from './core/IsolateNode.js'; export { default as ConstNode } from './core/ConstNode.js'; export { default as ContextNode } from './core/ContextNode.js'; -export { default as GlobalContextNode } from './core/GlobalContextNode.js'; export { default as IndexNode } from './core/IndexNode.js'; export { default as LightingModel } from './core/LightingModel.js'; export { default as Node } from './core/Node.js'; diff --git a/src/nodes/TSL.js b/src/nodes/TSL.js index b510d4e513bf97..da2f0ca507dd54 100644 --- a/src/nodes/TSL.js +++ b/src/nodes/TSL.js @@ -7,7 +7,6 @@ export * from './core/AttributeNode.js'; export * from './core/BypassNode.js'; export * from './core/IsolateNode.js'; export * from './core/ContextNode.js'; -export * from './core/GlobalContextNode.js'; export * from './core/IndexNode.js'; export * from './core/ParameterNode.js'; export * from './core/PropertyNode.js'; diff --git a/src/nodes/core/GlobalContextNode.js b/src/nodes/core/GlobalContextNode.js deleted file mode 100644 index 021be05483d9a6..00000000000000 --- a/src/nodes/core/GlobalContextNode.js +++ /dev/null @@ -1,66 +0,0 @@ -import Node from './Node.js'; -import { nodeProxy } from '../tsl/TSLCore.js'; - -/** - * This node can be used as a global context management component for another node. - * {@link NodeBuilder} performs its node building process in a specific context and - * this node allows the modify the context. A typical use case is to overwrite `getUV()` e.g.: - * - * ```js - *material.contextNode = globalContext( { getUV: () => customCoord } ); - *\// or - *renderer.globalContext = globalContext( { getUV: () => customCoord } ); - *\// or - *scenePass.globalContext = globalContext( { getUV: () => customCoord } ); - *``` - * @augments Node - */ -class GlobalContextNode extends Node { - - static get type() { - - return 'GlobalContextNode'; - - } - - /** - * Constructs a new global context node. - * - * @param {Object} [value={}] - The modified context data. - */ - constructor( value = {} ) { - - super( 'void' ); - - /** - * This flag can be used for type testing. - * - * @type {boolean} - * @readonly - * @default true - */ - this.isGlobalContextNode = true; - - /** - * The modified context data. - * - * @type {Object} - * @default {} - */ - this.value = value; - - } - -} - -export default GlobalContextNode; - -/** - * TSL function for creating a global context node. - * - * @tsl - * @function - * @param {Object} [value={}] - The modified context data. - * @returns {GlobalContextNode} - */ -export const globalContext = /*@__PURE__*/ nodeProxy( GlobalContextNode ); From df0299fcc922660872836be8828826ff2122bc42 Mon Sep 17 00:00:00 2001 From: sunag Date: Thu, 20 Nov 2025 23:58:58 -0300 Subject: [PATCH 06/14] Update Three.TSL.js --- src/Three.TSL.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Three.TSL.js b/src/Three.TSL.js index b921a1fb570c88..0ea6849fbe2758 100644 --- a/src/Three.TSL.js +++ b/src/Three.TSL.js @@ -211,7 +211,6 @@ export const getShadowRenderObjectFunction = TSL.getShadowRenderObjectFunction; export const getTextureIndex = TSL.getTextureIndex; export const getViewPosition = TSL.getViewPosition; export const globalId = TSL.globalId; -export const globalContext = TSL.globalContext; export const glsl = TSL.glsl; export const glslFn = TSL.glslFn; export const grayscale = TSL.grayscale; From bffbda935353f4971b6b3cfe980a44a5e03c6f86 Mon Sep 17 00:00:00 2001 From: sunag Date: Thu, 20 Nov 2025 23:59:52 -0300 Subject: [PATCH 07/14] cleanup --- src/nodes/display/PassNode.js | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/nodes/display/PassNode.js b/src/nodes/display/PassNode.js index 4b58d7874aa974..3f8a2566e2cd3f 100644 --- a/src/nodes/display/PassNode.js +++ b/src/nodes/display/PassNode.js @@ -810,12 +810,6 @@ class PassNode extends TempNode { renderer.transparent = this.transparent; renderer.opaque = this.opaque; - if ( this.globalContext !== null ) { - - renderer.globalContext = this.globalContext; - - } - if ( this.contextNode !== null ) { if ( this._contextNodeCache === null || this._contextNodeCache.version !== this.version ) { From 7fb0b4ed0b2194f8dd17c564ef6f126670c043d9 Mon Sep 17 00:00:00 2001 From: sunag Date: Fri, 21 Nov 2025 01:32:37 -0300 Subject: [PATCH 08/14] fix example --- examples/webgpu_postprocessing_ao.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/webgpu_postprocessing_ao.html b/examples/webgpu_postprocessing_ao.html index 699485695dd1c3..ca39fcc669d576 100644 --- a/examples/webgpu_postprocessing_ao.html +++ b/examples/webgpu_postprocessing_ao.html @@ -36,7 +36,7 @@