Преглед изворни кода

WebGPURenderer: Basic render to texture support for WebGL backend (#26801)

* Support texture backed render targets

* actually use the framebuffer we have cached

* update examples

* update screenshots

---------

Co-authored-by: aardgoose <[email protected]>
aardgoose пре 1 година
родитељ
комит
ef417f0dec

+ 54 - 1
examples/jsm/renderers/webgl/WebGLBackend.js

@@ -54,6 +54,8 @@ class WebGLBackend extends Backend {
 
 		//
 
+		this._setFramebuffer( renderContext );
+
 		let clear = 0;
 
 		if ( renderContext.clearColor ) clear |= gl.COLOR_BUFFER_BIT;
@@ -62,7 +64,7 @@ class WebGLBackend extends Backend {
 
 		const clearColor = renderContext.clearColorValue;
 
-		gl.clearColor( clearColor.x, clearColor.y, clearColor.z, clearColor.a );
+		gl.clearColor( clearColor.r, clearColor.g, clearColor.b, clearColor.a );
 		gl.clear( clear );
 
 		//
@@ -618,6 +620,57 @@ class WebGLBackend extends Backend {
 
 	}
 
+	_setFramebuffer( renderContext ) {
+
+		const { gl } = this;
+
+		if ( renderContext.textures !== null ) {
+
+			const renderContextData = this.get( renderContext );
+
+			let fb = renderContextData.framebuffer;
+
+			if ( fb === undefined ) {
+
+				fb = gl.createFramebuffer();
+
+				gl.bindFramebuffer( gl.FRAMEBUFFER, fb );
+
+				const textures = renderContext.textures;
+
+				for ( let i = 0; i < textures.length; i++ ) {
+
+					const texture = textures[ i ];
+					const { textureGPU } = this.get( texture );
+
+					gl.framebufferTexture2D( gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i, gl.TEXTURE_2D, textureGPU, 0 );
+
+				}
+
+				if ( renderContext.depthTexture !== null ) {
+
+					const { textureGPU } = this.get( renderContext.depthTexture );
+
+					gl.framebufferTexture2D( gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.TEXTURE_2D, textureGPU, 0 );
+
+				}
+
+				renderContextData.framebuffer = fb;
+
+			} else {
+
+				gl.bindFramebuffer( gl.FRAMEBUFFER, fb );
+
+			}
+
+		} else {
+
+			gl.bindFramebuffer( gl.FRAMEBUFFER, null );
+
+		}
+
+	}
+
 }
 
 export default WebGLBackend;

+ 13 - 0
examples/jsm/renderers/webgl/utils/WebGLTextureUtils.js

@@ -140,6 +140,19 @@ class WebGLTextureUtils {
 
 		}
 
+		if ( glFormat === gl.DEPTH_COMPONENT ) {
+
+			if ( glType === gl.UNSIGNED_INT ) internalFormat = gl.DEPTH_COMPONENT24;
+			if ( glType === gl.FLOAT ) internalFormat = gl.DEPTH_COMPONENT32F;
+
+		}
+
+		if ( glFormat === gl.DEPTH_STENCIL ) {
+
+			if ( glType === gl.UNSIGNED_INT_24_8 ) internalFormat = gl.DEPTH24_STENCIL8;
+
+		}
+
 		if ( internalFormat === gl.R16F || internalFormat === gl.R32F ||
 			internalFormat === gl.RG16F || internalFormat === gl.RG32F ||
 			internalFormat === gl.RGBA16F || internalFormat === gl.RGBA32F ) {

BIN
examples/screenshots/webgpu_depth_texture.jpg


BIN
examples/screenshots/webgpu_lights_custom.jpg


BIN
examples/screenshots/webgpu_rtt.jpg


+ 4 - 2
examples/webgpu_depth_texture.html

@@ -29,6 +29,8 @@
 			import { texture, MeshBasicNodeMaterial } from 'three/nodes';
 
 			import WebGPU from 'three/addons/capabilities/WebGPU.js';
+			import WebGL from 'three/addons/capabilities/WebGL.js';
+
 			import WebGPURenderer from 'three/addons/renderers/webgpu/WebGPURenderer.js';
 
 			import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
@@ -43,11 +45,11 @@
 
 			function init() {
 
-				if ( WebGPU.isAvailable() === false ) {
+				if ( WebGPU.isAvailable() === false && WebGL.isWebGL2Available() === false ) {
 
 					document.body.appendChild( WebGPU.getErrorMessage() );
 
-					throw new Error( 'No WebGPU support' );
+					throw new Error( 'No WebGPU or WebGL2 support' );
 
 				}
 

+ 4 - 2
examples/webgpu_rtt.html

@@ -29,6 +29,8 @@
 			import { texture, uniform, vec2, MeshBasicNodeMaterial } from 'three/nodes';
 
 			import WebGPU from 'three/addons/capabilities/WebGPU.js';
+			import WebGL from 'three/addons/capabilities/WebGL.js';
+
 			import WebGPURenderer from 'three/addons/renderers/webgpu/WebGPURenderer.js';
 
 			let camera, scene, renderer;
@@ -44,11 +46,11 @@
 
 			function init() {
 
-				if ( WebGPU.isAvailable() === false ) {
+				if ( WebGPU.isAvailable() === false && WebGL.isWebGL2Available() === false ) {
 
 					document.body.appendChild( WebGPU.getErrorMessage() );
 
-					throw new Error( 'No WebGPU support' );
+					throw new Error( 'No WebGPU or WebGL2 support' );
 
 				}
 

+ 0 - 2
test/e2e/puppeteer.js

@@ -116,7 +116,6 @@ const exceptionList = [
 	'webgpu_compute_texture',
 	'webgpu_compute_texture_pingpong',
 	'webgpu_cubemap_dynamic',
-	'webgpu_depth_texture',
 	'webgpu_instance_mesh',
 	'webgpu_lines_fat',
 	'webgpu_loader_gltf',
@@ -129,7 +128,6 @@ const exceptionList = [
 	"webgpu_multiple_rendertargets",
 	'webgpu_occlusion',
 	'webgpu_particles',
-	'webgpu_rtt',
 	'webgpu_sandbox',
 	'webgpu_shadowmap',
 	'webgpu_skinning',