2
0
Эх сурвалжийг харах

WebGPURenderer: Fix .clear() using RenderTarget and revisions (#27233)

* Fix .clear() using RenderTarget

* webgpu_rtt: improve a little

* cleanup

* cleanup

* revisions

* revision

* wip flipY

* update example

* cleanup
sunag 1 жил өмнө
parent
commit
0f94eeae22

+ 2 - 1
examples/jsm/nodes/accessors/TextureNode.js

@@ -157,7 +157,8 @@ class TextureNode extends UniformNode {
 
 
 		const texture = this.value;
 		const texture = this.value;
 
 
-		if ( builder.isFlipY() && ( texture.isFramebufferTexture === true || texture.isDepthTexture === true ) ) {
+		if ( ( builder.isFlipY() && ( texture.isFramebufferTexture === true || texture.isDepthTexture === true ) ) ||
+			( builder.isFlipY() === false && texture.isRenderTargetTexture === true ) ) {
 
 
 			uvNode = uvNode.setY( uvNode.y.fract().oneMinus() );
 			uvNode = uvNode.setY( uvNode.y.fract().oneMinus() );
 
 

+ 1 - 21
examples/jsm/nodes/materials/NodeMaterial.js

@@ -337,27 +337,7 @@ class NodeMaterial extends ShaderMaterial {
 
 
 		if ( this.colorSpaced === true ) {
 		if ( this.colorSpaced === true ) {
 
 
-			const renderTarget = renderer.getRenderTarget();
-
-			let outputColorSpace;
-
-			if ( renderTarget !== null ) {
-
-				if ( Array.isArray( renderTarget.texture ) ) {
-
-					outputColorSpace = renderTarget.texture[ 0 ].colorSpace;
-
-				} else {
-
-					outputColorSpace = renderTarget.texture.colorSpace;
-
-				}
-
-			} else {
-
-				outputColorSpace = renderer.outputColorSpace;
-
-			}
+			const outputColorSpace = renderer.currentColorSpace;
 
 
 			if ( outputColorSpace !== LinearSRGBColorSpace && outputColorSpace !== NoColorSpace ) {
 			if ( outputColorSpace !== LinearSRGBColorSpace && outputColorSpace !== NoColorSpace ) {
 
 

+ 16 - 0
examples/jsm/renderers/common/Backend.js

@@ -1,6 +1,8 @@
 let vector2 = null;
 let vector2 = null;
 let vector4 = null;
 let vector4 = null;
+let color4 = null;
 
 
+import Color4 from './Color4.js';
 import { Vector2, Vector4, REVISION, createCanvasElement } from 'three';
 import { Vector2, Vector4, REVISION, createCanvasElement } from 'three';
 
 
 class Backend {
 class Backend {
@@ -112,6 +114,20 @@ class Backend {
 
 
 	}
 	}
 
 
+	getClearColor() {
+
+		const renderer = this.renderer;
+
+		color4 = color4 || new Color4();
+
+		renderer.getClearColor( color4 );
+
+		color4.getRGB( color4, this.renderer.currentColorSpace );
+
+		return color4;
+
+	}
+
 	getDomElement() {
 	getDomElement() {
 
 
 		let domElement = this.domElement;
 		let domElement = this.domElement;

+ 2 - 2
examples/jsm/renderers/common/Background.js

@@ -30,14 +30,14 @@ class Background extends DataMap {
 
 
 			// no background settings, use clear color configuration from the renderer
 			// no background settings, use clear color configuration from the renderer
 
 
-			_clearColor.copyLinearToSRGB( renderer._clearColor );
+			renderer._clearColor.getRGB( _clearColor, this.renderer.currentColorSpace );
 			_clearColor.a = renderer._clearColor.a;
 			_clearColor.a = renderer._clearColor.a;
 
 
 		} else if ( background.isColor === true ) {
 		} else if ( background.isColor === true ) {
 
 
 			// background is an opaque color
 			// background is an opaque color
 
 
-			_clearColor.copyLinearToSRGB( background );
+			background.getRGB( _clearColor, this.renderer.currentColorSpace );
 			_clearColor.a = 1;
 			_clearColor.a = 1;
 
 
 			forceClear = true;
 			forceClear = true;

+ 1 - 1
examples/jsm/renderers/common/RenderContext.js

@@ -26,7 +26,7 @@ class RenderContext {
 		this.scissor = false;
 		this.scissor = false;
 		this.scissorValue = new Vector4();
 		this.scissorValue = new Vector4();
 
 
-		this.texture = null;
+		this.textures = null;
 		this.depthTexture = null;
 		this.depthTexture = null;
 		this.activeCubeFace = 0;
 		this.activeCubeFace = 0;
 		this.sampleCount = 1;
 		this.sampleCount = 1;

+ 1 - 1
examples/jsm/renderers/common/RenderContexts.js

@@ -35,7 +35,7 @@ class RenderContexts {
 
 
 			}
 			}
 
 
-			attachmentState = `${count}:${format}:${renderTarget.samples}:${renderTarget.depthBuffer}:${renderTarget.stencilBuffer}`;
+			attachmentState = `${ count }:${ format }:${ renderTarget.samples }:${ renderTarget.depthBuffer }:${ renderTarget.stencilBuffer }`;
 
 
 		}
 		}
 
 

+ 31 - 8
examples/jsm/renderers/common/Renderer.js

@@ -73,7 +73,6 @@ class Renderer {
 		this._background = null;
 		this._background = null;
 
 
 		this._currentRenderContext = null;
 		this._currentRenderContext = null;
-		this._lastRenderContext = null;
 
 
 		this._opaqueSort = null;
 		this._opaqueSort = null;
 		this._transparentSort = null;
 		this._transparentSort = null;
@@ -339,8 +338,6 @@ class Renderer {
 		this._currentRenderContext = previousRenderContext;
 		this._currentRenderContext = previousRenderContext;
 		this._currentRenderObjectFunction = previousRenderObjectFunction;
 		this._currentRenderObjectFunction = previousRenderObjectFunction;
 
 
-		this._lastRenderContext = renderContext;
-
 		//
 		//
 
 
 		sceneRef.onAfterRender( this, scene, camera, renderTarget );
 		sceneRef.onAfterRender( this, scene, camera, renderTarget );
@@ -536,7 +533,8 @@ class Renderer {
 
 
 	setClearColor( color, alpha = 1 ) {
 	setClearColor( color, alpha = 1 ) {
 
 
-		this._clearColor.set( color.r, color.g, color.b, alpha );
+		this._clearColor.set( color );
+		this._clearColor.a = alpha;
 
 
 	}
 	}
 
 
@@ -578,7 +576,7 @@ class Renderer {
 
 
 	isOccluded( object ) {
 	isOccluded( object ) {
 
 
-		const renderContext = this._currentRenderContext || this._lastRenderContext;
+		const renderContext = this._currentRenderContext;
 
 
 		return renderContext && this.backend.isOccluded( renderContext, object );
 		return renderContext && this.backend.isOccluded( renderContext, object );
 
 
@@ -586,9 +584,18 @@ class Renderer {
 
 
 	clear( color = true, depth = true, stencil = true ) {
 	clear( color = true, depth = true, stencil = true ) {
 
 
-		const renderContext = this._currentRenderContext || this._lastRenderContext;
+		let renderTargetData = null;
+		const renderTarget = this._renderTarget;
+
+		if ( renderTarget !== null ) {
+
+			this._textures.updateRenderTarget( renderTarget );
 
 
-		if ( renderContext ) this.backend.clear( renderContext, color, depth, stencil );
+			renderTargetData = this._textures.get( renderTarget );
+
+		}
+
+		this.backend.clear( color, depth, stencil, renderTargetData );
 
 
 	}
 	}
 
 
@@ -610,6 +617,22 @@ class Renderer {
 
 
 	}
 	}
 
 
+	get currentColorSpace() {
+
+		const renderTarget = this._renderTarget;
+
+		if ( renderTarget !== null ) {
+
+			const texture = renderTarget.texture;
+
+			return ( Array.isArray( texture ) ? texture[ 0 ] : texture ).colorSpace;
+
+		}
+
+		return this.outputColorSpace;
+
+	}
+
 	dispose() {
 	dispose() {
 
 
 		this.info.dispose();
 		this.info.dispose();
@@ -736,7 +759,7 @@ class Renderer {
 
 
 	copyFramebufferToTexture( framebufferTexture ) {
 	copyFramebufferToTexture( framebufferTexture ) {
 
 
-		const renderContext = this._currentRenderContext || this._lastRenderContext;
+		const renderContext = this._currentRenderContext;
 
 
 		this._textures.updateTexture( framebufferTexture );
 		this._textures.updateTexture( framebufferTexture );
 
 

+ 4 - 1
examples/jsm/renderers/common/Textures.js

@@ -70,6 +70,8 @@ class Textures extends DataMap {
 		renderTargetData.height = size.height;
 		renderTargetData.height = size.height;
 		renderTargetData.textures = textures;
 		renderTargetData.textures = textures;
 		renderTargetData.depthTexture = depthTexture;
 		renderTargetData.depthTexture = depthTexture;
+		renderTargetData.depth = renderTarget.depthBuffer;
+		renderTargetData.stencil = renderTarget.stencilBuffer;
 
 
 		if ( renderTargetData.sampleCount !== sampleCount ) {
 		if ( renderTargetData.sampleCount !== sampleCount ) {
 
 
@@ -80,8 +82,9 @@ class Textures extends DataMap {
 
 
 		}
 		}
 
 
-		const options = { sampleCount };
+		//
 
 
+		const options = { sampleCount };
 
 
 		for ( let i = 0; i < textures.length; i ++ ) {
 		for ( let i = 0; i < textures.length; i ++ ) {
 
 

+ 14 - 5
examples/jsm/renderers/webgl/WebGLBackend.js

@@ -63,7 +63,7 @@ class WebGLBackend extends Backend {
 
 
 		this._setFramebuffer( renderContext );
 		this._setFramebuffer( renderContext );
 
 
-		this.clear( renderContext, renderContext.clearColor, renderContext.clearDepth, renderContext.clearStencil );
+		this.clear( renderContext.clearColor, renderContext.clearDepth, renderContext.clearStencil, renderContext );
 
 
 		//
 		//
 
 
@@ -215,10 +215,19 @@ class WebGLBackend extends Backend {
 
 
 	}
 	}
 
 
-	clear( renderContext, color, depth, stencil ) {
+	clear( color, depth, stencil, descriptor = null ) {
 
 
 		const { gl } = this;
 		const { gl } = this;
 
 
+		if ( descriptor === null ) {
+
+			descriptor = {
+				textures: null,
+				clearColorValue: this.getClearColor()
+			};
+
+		}
+
 		//
 		//
 
 
 		let clear = 0;
 		let clear = 0;
@@ -229,11 +238,11 @@ class WebGLBackend extends Backend {
 
 
 		if ( clear !== 0 ) {
 		if ( clear !== 0 ) {
 
 
-			const clearColor = renderContext.clearColorValue;
+			const clearColor = descriptor.clearColorValue;
 
 
 			if ( depth ) this.state.setDepthMask( true );
 			if ( depth ) this.state.setDepthMask( true );
 
 
-			if ( renderContext.textures === null ) {
+			if ( descriptor.textures === null ) {
 
 
 				gl.clearColor( clearColor.r, clearColor.g, clearColor.b, clearColor.a );
 				gl.clearColor( clearColor.r, clearColor.g, clearColor.b, clearColor.a );
 				gl.clear( clear );
 				gl.clear( clear );
@@ -242,7 +251,7 @@ class WebGLBackend extends Backend {
 
 
 				if ( color ) {
 				if ( color ) {
 
 
-					for ( let i = 0; i < renderContext.textures.length; i ++ ) {
+					for ( let i = 0; i < descriptor.textures.length; i ++ ) {
 
 
 						gl.clearBufferfv( gl.COLOR, i, [ clearColor.r, clearColor.g, clearColor.b, clearColor.a ] );
 						gl.clearBufferfv( gl.COLOR, i, [ clearColor.r, clearColor.g, clearColor.b, clearColor.a ] );
 
 

+ 139 - 125
examples/jsm/renderers/webgpu/WebGPUBackend.js

@@ -7,7 +7,7 @@ import { GPUFeatureName, GPUTextureFormat, GPULoadOp, GPUStoreOp, GPUIndexFormat
 import WGSLNodeBuilder from './nodes/WGSLNodeBuilder.js';
 import WGSLNodeBuilder from './nodes/WGSLNodeBuilder.js';
 import Backend from '../common/Backend.js';
 import Backend from '../common/Backend.js';
 
 
-import { DepthTexture, DepthFormat, DepthStencilFormat, UnsignedInt248Type, UnsignedIntType, WebGPUCoordinateSystem } from 'three';
+import { DepthFormat, WebGPUCoordinateSystem } from 'three';
 
 
 import WebGPUUtils from './utils/WebGPUUtils.js';
 import WebGPUUtils from './utils/WebGPUUtils.js';
 import WebGPUAttributeUtils from './utils/WebGPUAttributeUtils.js';
 import WebGPUAttributeUtils from './utils/WebGPUAttributeUtils.js';
@@ -56,9 +56,6 @@ class WebGPUBackend extends Backend {
 		this.context = null;
 		this.context = null;
 		this.colorBuffer = null;
 		this.colorBuffer = null;
 
 
-		this.defaultDepthTexture = new DepthTexture();
-		this.defaultDepthTexture.name = 'depthBuffer';
-
 		this.utils = new WebGPUUtils( this );
 		this.utils = new WebGPUUtils( this );
 		this.attributeUtils = new WebGPUAttributeUtils( this );
 		this.attributeUtils = new WebGPUAttributeUtils( this );
 		this.bindingUtils = new WebGPUBindingUtils( this );
 		this.bindingUtils = new WebGPUBindingUtils( this );
@@ -117,6 +114,13 @@ class WebGPUBackend extends Backend {
 		this.device = device;
 		this.device = device;
 		this.context = context;
 		this.context = context;
 
 
+		this.context.configure( {
+			device: this.device,
+			format: GPUTextureFormat.BGRA8Unorm,
+			usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.COPY_SRC,
+			alphaMode: 'premultiplied'
+		} );
+
 		this.updateSize();
 		this.updateSize();
 
 
 	}
 	}
@@ -218,7 +222,6 @@ class WebGPUBackend extends Backend {
 					resolveTarget,
 					resolveTarget,
 					loadOp: GPULoadOp.Load,
 					loadOp: GPULoadOp.Load,
 					storeOp: GPUStoreOp.Store
 					storeOp: GPUStoreOp.Store
-
 				} );
 				} );
 
 
 			}
 			}
@@ -247,7 +250,7 @@ class WebGPUBackend extends Backend {
 
 
 			}
 			}
 
 
-			depthStencilAttachment.view = this._getDepthBufferGPU( renderContext ).createView();
+			depthStencilAttachment.view = this.textureUtils.getDepthBuffer( renderContext.depth, renderContext.stencil ).createView();
 
 
 		}
 		}
 
 
@@ -492,75 +495,166 @@ class WebGPUBackend extends Backend {
 
 
 	}
 	}
 
 
-	clear( renderContext, color, depth, stencil ) {
+	clear( color, depth, stencil, renderTargetData = null ) {
 
 
 		const device = this.device;
 		const device = this.device;
-		const renderContextData = this.get( renderContext );
+		const renderer = this.renderer;
 
 
-		const { descriptor } = renderContextData;
+		const colorAttachments = [];
 
 
-		depth = depth && renderContext.depth;
-		stencil = stencil && renderContext.stencil;
+		let depthStencilAttachment;
+		let clearValue;
 
 
-		const colorAttachment = descriptor.colorAttachments[ 0 ];
-		const depthStencilAttachment = descriptor.depthStencilAttachment;
+		let supportsDepth;
+		let supportsStencil;
 
 
-		const antialias = this.parameters.antialias;
+		if ( color ) {
 
 
-		// @TODO: Include render target in clear operation.
-		if ( antialias === true ) {
+			const clearColor = this.getClearColor();
 
 
-			colorAttachment.view = this.colorBuffer.createView();
-			colorAttachment.resolveTarget = this.context.getCurrentTexture().createView();
+			clearValue = { r: clearColor.r, g: clearColor.g, b: clearColor.b, a: clearColor.a };
 
 
-		} else {
+		}
 
 
-			colorAttachment.view = this.context.getCurrentTexture().createView();
-			colorAttachment.resolveTarget = undefined;
+		if ( renderTargetData === null ) {
 
 
-		}
+			supportsDepth = renderer.depth;
+			supportsStencil = renderer.stencil;
 
 
-		descriptor.depthStencilAttachment.view = this._getDepthBufferGPU( renderContext ).createView();
+			depth = depth && supportsDepth;
+			stencil = stencil && supportsStencil;
 
 
-		if ( color ) {
+			if ( color ) {
 
 
-			colorAttachment.loadOp = GPULoadOp.Clear;
-			colorAttachment.clearValue = renderContext.clearColorValue;
+				const antialias = this.parameters.antialias;
 
 
-		} else {
+				const colorAttachment = {};
 
 
-			colorAttachment.loadOp = GPULoadOp.Load;
+				if ( antialias === true ) {
 
 
-		}
+					colorAttachment.view = this.colorBuffer.createView();
+					colorAttachment.resolveTarget = this.context.getCurrentTexture().createView();
+		
+				} else {
+		
+					colorAttachment.view = this.context.getCurrentTexture().createView();
+		
+				}
 
 
-		if ( depth ) {
+				colorAttachment.clearValue = clearValue;
+				colorAttachment.loadOp = GPULoadOp.Clear;
+				colorAttachment.storeOp = GPUStoreOp.Store;
 
 
-			depthStencilAttachment.depthLoadOp = GPULoadOp.Clear;
-			depthStencilAttachment.depthClearValue = renderContext.clearDepthValue;
+				colorAttachments.push( colorAttachment );
+
+			}
+
+			if ( depth || stencil ) {
+
+				depthStencilAttachment = {
+					view: this.textureUtils.getDepthBuffer( renderer.depth, renderer.stencil ).createView()
+				};
+
+			}
 
 
 		} else {
 		} else {
 
 
-			depthStencilAttachment.depthLoadOp = GPULoadOp.Load;
+			supportsDepth = renderTargetData.depth;
+			supportsStencil = renderTargetData.stencil;
+
+			depth = depth && supportsDepth;
+			stencil = stencil && supportsStencil;
+
+			if ( color ) {
+
+				for ( const texture of renderTargetData.textures ) {
+
+					const textureData = this.get( texture );
+					const textureView = textureData.texture.createView();
+
+					let view, resolveTarget;
+
+					if ( textureData.msaaTexture !== undefined ) {
+
+						view = textureData.msaaTexture.createView();
+						resolveTarget = textureView;
+
+					} else {
+
+						view = textureView;
+						resolveTarget = undefined;
+
+					}
+
+					colorAttachments.push( {
+						view,
+						resolveTarget,
+						clearValue,
+						loadOp: GPULoadOp.Clear,
+						storeOp: GPUStoreOp.Store
+					} );
+
+				}
+
+			}
+
+			if ( depth || stencil ) {
+
+				const depthTextureData = this.get( renderTargetData.depthTexture );
+
+				depthStencilAttachment = {
+					view: depthTextureData.texture.createView()
+				};
+
+			}
 
 
 		}
 		}
 
 
-		if ( stencil ) {
+		//
+
+		if ( depthStencilAttachment !== undefined ) {
 
 
-			depthStencilAttachment.stencilLoadOp = GPULoadOp.Clear;
-			depthStencilAttachment.stencilClearValue = renderContext.clearStencilValue;
+			if ( depth ) {
 
 
-		} else {
+				depthStencilAttachment.depthLoadOp = GPULoadOp.Clear;
+				depthStencilAttachment.depthClearValue = renderer.getClearDepth();
+				depthStencilAttachment.depthStoreOp = GPUStoreOp.Store;
+
+			} else if ( supportsDepth ) {
+
+				depthStencilAttachment.depthLoadOp = GPULoadOp.Load;
+				depthStencilAttachment.depthStoreOp = GPUStoreOp.Store;
+
+			}
+
+			//
+
+			if ( stencil ) {
+
+				depthStencilAttachment.stencilLoadOp = GPULoadOp.Clear;
+				depthStencilAttachment.stencilClearValue = renderer.getClearStencil();
+				depthStencilAttachment.stencilStoreOp = GPUStoreOp.Store;
+
+			} else if ( supportsStencil ) {
 
 
-			depthStencilAttachment.stencilLoadOp = GPULoadOp.Load;
+				depthStencilAttachment.stencilLoadOp = GPULoadOp.Load;
+				depthStencilAttachment.stencilStoreOp = GPUStoreOp.Store;
+
+			}
 
 
 		}
 		}
 
 
-		renderContextData.encoder = device.createCommandEncoder( {} );
-		renderContextData.currentPass = renderContextData.encoder.beginRenderPass( descriptor );
+		//
 
 
-		renderContextData.currentPass.end();
+		const encoder = device.createCommandEncoder( {} );
+		const currentPass = encoder.beginRenderPass( {
+			colorAttachments,
+			depthStencilAttachment
+		} );
+
+		currentPass.end();
 
 
-		device.queue.submit( [ renderContextData.encoder.finish() ] );
+		device.queue.submit( [ encoder.finish() ] );
 
 
 	}
 	}
 
 
@@ -956,9 +1050,8 @@ class WebGPUBackend extends Backend {
 
 
 	updateSize() {
 	updateSize() {
 
 
-		this._configureContext();
-		this._setupColorBuffer();
-
+		this.colorBuffer = this.textureUtils.getColorBuffer();
+	
 	}
 	}
 
 
 	// utils public
 	// utils public
@@ -997,7 +1090,7 @@ class WebGPUBackend extends Backend {
 
 
 		} else if ( texture.isDepthTexture ) {
 		} else if ( texture.isDepthTexture ) {
 
 
-			sourceGPU = this._getDepthBufferGPU( renderContext );
+			sourceGPU = this.textureUtils.getDepthBuffer( renderContext.depth, renderContext.stencil );
 
 
 		}
 		}
 
 
@@ -1030,85 +1123,6 @@ class WebGPUBackend extends Backend {
 
 
 	}
 	}
 
 
-	// utils
-
-	_getDepthBufferGPU( renderContext ) {
-
-		const { width, height } = this.getDrawingBufferSize();
-
-		const depthTexture = this.defaultDepthTexture;
-		const depthTextureGPU = this.get( depthTexture ).texture;
-
-		let format, type;
-
-		if ( renderContext.stencil ) {
-
-			format = DepthStencilFormat;
-			type = UnsignedInt248Type;
-
-		} else if ( renderContext.depth ) {
-
-			format = DepthFormat;
-			type = UnsignedIntType;
-
-		}
-
-		if ( depthTextureGPU !== undefined ) {
-
-			if ( depthTexture.image.width === width && depthTexture.image.height === height && depthTexture.format === format && depthTexture.type === type ) {
-
-				return depthTextureGPU;
-
-			}
-
-			this.textureUtils.destroyTexture( depthTexture );
-
-		}
-
-		depthTexture.name = 'depthBuffer';
-		depthTexture.format = format;
-		depthTexture.type = type;
-		depthTexture.image.width = width;
-		depthTexture.image.height = height;
-
-		this.textureUtils.createTexture( depthTexture, { sampleCount: this.parameters.sampleCount, width, height } );
-
-		return this.get( depthTexture ).texture;
-
-	}
-
-	_configureContext() {
-
-		this.context.configure( {
-			device: this.device,
-			format: GPUTextureFormat.BGRA8Unorm,
-			usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.COPY_SRC,
-			alphaMode: 'premultiplied'
-		} );
-
-	}
-
-	_setupColorBuffer() {
-
-		if ( this.colorBuffer ) this.colorBuffer.destroy();
-
-		const { width, height } = this.getDrawingBufferSize();
-		//const format = navigator.gpu.getPreferredCanvasFormat(); // @TODO: Move to WebGPUUtils
-
-		this.colorBuffer = this.device.createTexture( {
-			label: 'colorBuffer',
-			size: {
-				width: width,
-				height: height,
-				depthOrArrayLayers: 1
-			},
-			sampleCount: this.parameters.sampleCount,
-			format: GPUTextureFormat.BGRA8Unorm,
-			usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.COPY_SRC
-		} );
-
-	}
-
 }
 }
 
 
 export default WebGPUBackend;
 export default WebGPUBackend;

+ 76 - 2
examples/jsm/renderers/webgpu/utils/WebGPUTextureUtils.js

@@ -13,7 +13,7 @@ import {
 	NeverCompare, AlwaysCompare, LessCompare, LessEqualCompare, EqualCompare, GreaterEqualCompare, GreaterCompare, NotEqualCompare
 	NeverCompare, AlwaysCompare, LessCompare, LessEqualCompare, EqualCompare, GreaterEqualCompare, GreaterCompare, NotEqualCompare
 } from 'three';
 } from 'three';
 
 
-import { CubeReflectionMapping, CubeRefractionMapping, EquirectangularReflectionMapping, EquirectangularRefractionMapping } from 'three';
+import { CubeReflectionMapping, CubeRefractionMapping, EquirectangularReflectionMapping, EquirectangularRefractionMapping, DepthTexture } from 'three';
 
 
 import WebGPUTexturePassUtils from './WebGPUTexturePassUtils.js';
 import WebGPUTexturePassUtils from './WebGPUTexturePassUtils.js';
 
 
@@ -41,6 +41,11 @@ class WebGPUTextureUtils {
 		this.defaultTexture = null;
 		this.defaultTexture = null;
 		this.defaultCubeTexture = null;
 		this.defaultCubeTexture = null;
 
 
+		this.colorBuffer = null;
+
+		this.depthTexture = new DepthTexture();
+		this.depthTexture.name = 'depthBuffer';
+
 	}
 	}
 
 
 	createSampler( texture ) {
 	createSampler( texture ) {
@@ -106,7 +111,7 @@ class WebGPUTextureUtils {
 		const { width, height, depth, levels } = options;
 		const { width, height, depth, levels } = options;
 
 
 		const dimension = this._getDimension( texture );
 		const dimension = this._getDimension( texture );
-		const format = texture.internalFormat || getFormat( texture, this.device );
+		const format = texture.internalFormat || getFormat( texture, backend.device );
 
 
 		const sampleCount = options.sampleCount !== undefined ? options.sampleCount : 1;
 		const sampleCount = options.sampleCount !== undefined ? options.sampleCount : 1;
 		const primarySampleCount = texture.isRenderTargetTexture ? 1 : sampleCount;
 		const primarySampleCount = texture.isRenderTargetTexture ? 1 : sampleCount;
@@ -226,6 +231,75 @@ class WebGPUTextureUtils {
 
 
 	}
 	}
 
 
+	getColorBuffer() {
+
+		if ( this.colorBuffer ) this.colorBuffer.destroy();
+
+		const backend = this.backend;
+		const { width, height } = backend.getDrawingBufferSize();
+
+		this.colorBuffer = backend.device.createTexture( {
+			label: 'colorBuffer',
+			size: {
+				width: width,
+				height: height,
+				depthOrArrayLayers: 1
+			},
+			sampleCount: backend.parameters.sampleCount,
+			format: GPUTextureFormat.BGRA8Unorm,
+			usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.COPY_SRC
+		} );
+
+		return this.colorBuffer;
+
+	}
+
+	getDepthBuffer( depth = true, stencil = true ) {
+
+		const backend = this.backend;
+		const { width, height } = backend.getDrawingBufferSize();
+
+		const depthTexture = this.depthTexture;
+		const depthTextureGPU = backend.get( depthTexture ).texture;
+
+		let format, type;
+
+		if ( stencil ) {
+
+			format = DepthStencilFormat;
+			type = UnsignedInt248Type;
+
+		} else if ( depth ) {
+
+			format = DepthFormat;
+			type = UnsignedIntType;
+
+		}
+
+		if ( depthTextureGPU !== undefined ) {
+
+			if ( depthTexture.image.width === width && depthTexture.image.height === height && depthTexture.format === format && depthTexture.type === type ) {
+
+				return depthTextureGPU;
+
+			}
+
+			this.destroyTexture( depthTexture );
+
+		}
+
+		depthTexture.name = 'depthBuffer';
+		depthTexture.format = format;
+		depthTexture.type = type;
+		depthTexture.image.width = width;
+		depthTexture.image.height = height;
+
+		this.createTexture( depthTexture, { sampleCount: backend.parameters.sampleCount, width, height } );
+
+		return backend.get( depthTexture ).texture;
+
+	}
+
 	updateTexture( texture, options ) {
 	updateTexture( texture, options ) {
 
 
 		const textureData = this.backend.get( texture );
 		const textureData = this.backend.get( texture );

BIN
examples/screenshots/webgpu_instance_points.jpg


BIN
examples/screenshots/webgpu_lines_fat.jpg


BIN
examples/screenshots/webgpu_multiple_rendertargets.jpg


BIN
examples/screenshots/webgpu_rtt.jpg


+ 12 - 9
examples/webgpu_multiple_rendertargets.html

@@ -28,7 +28,7 @@
 			import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
 			import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
 			//import { GUI } from 'three/addons/libs/lil-gui.module.min.js';
 			//import { GUI } from 'three/addons/libs/lil-gui.module.min.js';
 
 
-			import { NodeMaterial, MeshBasicNodeMaterial, mix, modelNormalMatrix, normalGeometry, normalize, outputStruct, step, texture, uniform, uv, varying, vec2, vec4 } from 'three/nodes';
+			import { NodeMaterial, mix, modelNormalMatrix, normalGeometry, normalize, outputStruct, step, texture, uniform, uv, varying, vec2, vec4 } from 'three/nodes';
 			import WebGPU from 'three/addons/capabilities/WebGPU.js';
 			import WebGPU from 'three/addons/capabilities/WebGPU.js';
 			import WebGL from 'three/addons/capabilities/WebGL.js';
 			import WebGL from 'three/addons/capabilities/WebGL.js';
 
 
@@ -52,13 +52,16 @@
 
 
 			*/
 			*/
 
 
-			class WriteGBufferMaterial extends MeshBasicNodeMaterial {
+			class WriteGBufferMaterial extends NodeMaterial {
 
 
 				constructor( diffuseTexture ) {
 				constructor( diffuseTexture ) {
 
 
 					super();
 					super();
 
 
 					this.lights = false;
 					this.lights = false;
+					this.fog = false;
+					this.colorSpaced = false;
+
 					this.diffuseTexture = diffuseTexture;
 					this.diffuseTexture = diffuseTexture;
 
 
 					const vUv = varying( uv() );
 					const vUv = varying( uv() );
@@ -71,7 +74,7 @@
 					const gColor = texture( this.diffuseTexture, vUv.mul( repeat ) );
 					const gColor = texture( this.diffuseTexture, vUv.mul( repeat ) );
 					const gNormal = vec4( normalize( vNormal ), 1.0 );
 					const gNormal = vec4( normalize( vNormal ), 1.0 );
 
 
-					this.outputNode = outputStruct( gColor, gNormal );
+					this.fragmentNode = outputStruct( gColor, gNormal );
 
 
 				}
 				}
 
 
@@ -83,13 +86,15 @@
 
 
 					super();
 					super();
 
 
+					this.lights = false;
+					this.fog = false;
+
 					const vUv = varying( uv() );
 					const vUv = varying( uv() );
 
 
 					const diffuse = texture( tDiffuse, vUv );
 					const diffuse = texture( tDiffuse, vUv );
 					const normal = texture( tNormal, vUv );
 					const normal = texture( tNormal, vUv );
 
 
-					this.colorNode = mix( diffuse, normal, step( 0.5, vUv.x ) );
-					this.lights = false;
+					this.fragmentNode = mix( diffuse, normal, step( 0.5, vUv.x ) );
 
 
 				}
 				}
 
 
@@ -111,7 +116,6 @@
 				renderer.setPixelRatio( window.devicePixelRatio );
 				renderer.setPixelRatio( window.devicePixelRatio );
 				renderer.setSize( window.innerWidth, window.innerHeight );
 				renderer.setSize( window.innerWidth, window.innerHeight );
 				renderer.setAnimationLoop( render );
 				renderer.setAnimationLoop( render );
-				renderer.outputColorSpace = THREE.LinearSRGBColorSpace;
 				document.body.appendChild( renderer.domElement );
 				document.body.appendChild( renderer.domElement );
 
 
 				// Create a multi render target with Float buffers
 				// Create a multi render target with Float buffers
@@ -120,7 +124,7 @@
 					window.innerWidth * window.devicePixelRatio,
 					window.innerWidth * window.devicePixelRatio,
 					window.innerHeight * window.devicePixelRatio,
 					window.innerHeight * window.devicePixelRatio,
 					2,
 					2,
-					{ minFilter: THREE.NearestFilter, magFilter: THREE.NearestFilter, colorSpace: THREE.LinearSRGBColorSpace }
+					{ minFilter: THREE.NearestFilter, magFilter: THREE.NearestFilter }
 				);
 				);
 
 
 				// Name our G-Buffer attachments for debugging
 				// Name our G-Buffer attachments for debugging
@@ -139,6 +143,7 @@
 				const loader = new THREE.TextureLoader();
 				const loader = new THREE.TextureLoader();
 
 
 				const diffuse = loader.load( 'textures/hardwood2_diffuse.jpg', render );
 				const diffuse = loader.load( 'textures/hardwood2_diffuse.jpg', render );
+				diffuse.colorSpace = THREE.SRGBColorSpace;
 				diffuse.wrapS = THREE.RepeatWrapping;
 				diffuse.wrapS = THREE.RepeatWrapping;
 				diffuse.wrapT = THREE.RepeatWrapping;
 				diffuse.wrapT = THREE.RepeatWrapping;
 
 
@@ -177,8 +182,6 @@
 				const dpr = renderer.getPixelRatio();
 				const dpr = renderer.getPixelRatio();
 				renderTarget.setSize( window.innerWidth * dpr, window.innerHeight * dpr );
 				renderTarget.setSize( window.innerWidth * dpr, window.innerHeight * dpr );
 
 
-				render();
-
 			}
 			}
 
 
 			function render( time ) {
 			function render( time ) {

+ 7 - 7
examples/webgpu_rtt.html

@@ -24,7 +24,7 @@
 		<script type="module">
 		<script type="module">
 
 
 			import * as THREE from 'three';
 			import * as THREE from 'three';
-			import { texture, uniform, vec2, MeshBasicNodeMaterial } from 'three/nodes';
+			import { texture, uniform, MeshBasicNodeMaterial } from 'three/nodes';
 
 
 			import WebGPU from 'three/addons/capabilities/WebGPU.js';
 			import WebGPU from 'three/addons/capabilities/WebGPU.js';
 			import WebGL from 'three/addons/capabilities/WebGL.js';
 			import WebGL from 'three/addons/capabilities/WebGL.js';
@@ -53,10 +53,10 @@
 				}
 				}
 
 
 				camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 0.1, 10 );
 				camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 0.1, 10 );
-				camera.position.z = 4;
+				camera.position.z = 3;
 
 
 				scene = new THREE.Scene();
 				scene = new THREE.Scene();
-				scene.background = new THREE.Color( 0x222222 );
+				scene.background = new THREE.Color( 0x0066FF );
 
 
 				// textured mesh
 				// textured mesh
 
 
@@ -94,10 +94,10 @@
 
 
 				// modulate the final color based on the mouse position
 				// modulate the final color based on the mouse position
 
 
-				const screenFXNode = uniform( mouse ).add( vec2( 0.5, 0.5 ) );
+				const screenFXNode = uniform( mouse );
 
 
 				const materialFX = new MeshBasicNodeMaterial();
 				const materialFX = new MeshBasicNodeMaterial();
-				materialFX.colorNode = texture( renderTarget.texture ).mul( screenFXNode );
+				materialFX.colorNode = texture( renderTarget.texture ).rgb.saturation( screenFXNode.x.oneMinus() ).hue( screenFXNode.y );
 
 
 				const quad = new THREE.Mesh( geometryFX, materialFX );
 				const quad = new THREE.Mesh( geometryFX, materialFX );
 				sceneFX.add( quad );
 				sceneFX.add( quad );
@@ -106,8 +106,8 @@
 
 
 			function onWindowMouseMove( e ) {
 			function onWindowMouseMove( e ) {
 
 
-				mouse.x = e.offsetX / screen.width;
-				mouse.y = e.offsetY / screen.height;
+				mouse.x = e.offsetX / window.innerWidth;
+				mouse.y = e.offsetY / window.innerHeight;
 
 
 			}
 			}