Explorar o código

WebGPURenderer: Initial support for render targets.

Mugen87 %!s(int64=4) %!d(string=hai) anos
pai
achega
2876fccf0e

+ 30 - 3
examples/jsm/renderers/webgpu/WebGPURenderer.js

@@ -69,6 +69,8 @@ class WebGPURenderer {
 		this._clearDepth = 1;
 		this._clearStencil = 0;
 
+		this._renderTarget = null;
+
 	}
 
 	init() {
@@ -102,10 +104,23 @@ class WebGPURenderer {
 		}
 
 		const colorAttachment = this._renderPassDescriptor.colorAttachments[ 0 ];
-		colorAttachment.attachment = this._swapChain.getCurrentTexture().createView();
-
 		const depthStencilAttachment = this._renderPassDescriptor.depthStencilAttachment;
-		depthStencilAttachment.attachment = this._depthBuffer.createView();
+
+		if ( this._renderTarget !== null ) {
+
+			const renderTargetProperties = this._properties.get( this._renderTarget );
+
+			colorAttachment.attachment = renderTargetProperties.colorTextureGPU.createView();
+			depthStencilAttachment.attachment = renderTargetProperties.depthTextureGPU.createView();
+
+
+		} else {
+
+			colorAttachment.attachment = this._swapChain.getCurrentTexture().createView();
+			depthStencilAttachment.attachment = this._depthBuffer.createView();
+
+
+		}
 
 		this._background.render( scene );
 
@@ -328,6 +343,18 @@ class WebGPURenderer {
 
 	}
 
+	setRenderTarget( renderTarget ) {
+
+		this._renderTarget = renderTarget;
+
+		if ( renderTarget !== null ) {
+
+			this._textures.initRenderTarget( renderTarget );
+
+		}
+
+	}
+
 	_projectObject( object, camera, groupOrder ) {
 
 		const info = this._info;

+ 73 - 0
examples/jsm/renderers/webgpu/WebGPUTextures.js

@@ -111,6 +111,16 @@ class WebGPUTextures {
 
 		}
 
+		// if the texture is used for RTT, it's necessary to init it once so the binding
+		// group's resource definition points to the respective GPUTexture
+
+		if ( textureProperties.initializedRTT === false ) {
+
+			textureProperties.initializedRTT = true;
+			updated = true;
+
+		}
+
 		return updated;
 
 	}
@@ -157,6 +167,69 @@ class WebGPUTextures {
 
 	}
 
+	initRenderTarget( renderTarget ) {
+
+		const properties = this.properties;
+		const renderTargetProperties = properties.get( renderTarget );
+
+		if ( renderTargetProperties.initialized === undefined ) {
+
+			const device = this.device;
+
+			const width = renderTarget.width;
+			const height = renderTarget.height;
+
+			const colorTextureGPU = device.createTexture( {
+				size: {
+					width: width,
+					height: height,
+					depth: 1
+				},
+				format: GPUTextureFormat.BRGA8Unorm, // TODO: Make configurable
+				usage: GPUTextureUsage.OUTPUT_ATTACHMENT | GPUTextureUsage.SAMPLED
+			} );
+
+			renderTargetProperties.colorTextureGPU = colorTextureGPU;
+
+			// When the ".texture" or ".depthTexture" property of a render target is used as a map,
+			// the renderer has to find the respective GPUTexture objects to setup the bind groups.
+			// Since it's not possible to see just from a texture object whether it belongs to a render
+			// target or not, we need the initializedRTT flag.
+
+			const textureProperties = properties.get( renderTarget.texture );
+			textureProperties.textureGPU = colorTextureGPU;
+			textureProperties.initializedRTT = false;
+
+			if ( renderTarget.depthBuffer === true ) {
+
+				const depthTextureGPU = device.createTexture( {
+					size: {
+						width: width,
+						height: height,
+						depth: 1
+					},
+					format: GPUTextureFormat.Depth24PlusStencil8, // TODO: Make configurable
+					usage: GPUTextureUsage.OUTPUT_ATTACHMENT
+				} );
+
+				renderTargetProperties.depthTextureGPU = depthTextureGPU;
+
+				if ( renderTarget.depthTexture !== null ) {
+
+					const depthTextureProperties = properties.get( renderTarget.depthTexture );
+					depthTextureProperties.textureGPU = depthTextureGPU;
+					depthTextureProperties.initializedRTT = false;
+
+				}
+
+			}
+
+			renderTargetProperties.initialized = true;
+
+		}
+
+	}
+
 	_convertAddressMode( value ) {
 
 		let addressMode = GPUAddressMode.ClampToEdge;