Skip to content

Commit ef417f0

Browse files
aardgooseaardgoose
and
aardgoose
authored
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]>
1 parent bc69abb commit ef417f0

File tree

8 files changed

+75
-7
lines changed

8 files changed

+75
-7
lines changed

examples/jsm/renderers/webgl/WebGLBackend.js

+54-1
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ class WebGLBackend extends Backend {
5454

5555
//
5656

57+
this._setFramebuffer( renderContext );
58+
5759
let clear = 0;
5860

5961
if ( renderContext.clearColor ) clear |= gl.COLOR_BUFFER_BIT;
@@ -62,7 +64,7 @@ class WebGLBackend extends Backend {
6264

6365
const clearColor = renderContext.clearColorValue;
6466

65-
gl.clearColor( clearColor.x, clearColor.y, clearColor.z, clearColor.a );
67+
gl.clearColor( clearColor.r, clearColor.g, clearColor.b, clearColor.a );
6668
gl.clear( clear );
6769

6870
//
@@ -618,6 +620,57 @@ class WebGLBackend extends Backend {
618620

619621
}
620622

623+
_setFramebuffer( renderContext ) {
624+
625+
const { gl } = this;
626+
627+
if ( renderContext.textures !== null ) {
628+
629+
const renderContextData = this.get( renderContext );
630+
631+
let fb = renderContextData.framebuffer;
632+
633+
if ( fb === undefined ) {
634+
635+
fb = gl.createFramebuffer();
636+
637+
gl.bindFramebuffer( gl.FRAMEBUFFER, fb );
638+
639+
const textures = renderContext.textures;
640+
641+
for ( let i = 0; i < textures.length; i++ ) {
642+
643+
const texture = textures[ i ];
644+
const { textureGPU } = this.get( texture );
645+
646+
gl.framebufferTexture2D( gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i, gl.TEXTURE_2D, textureGPU, 0 );
647+
648+
}
649+
650+
if ( renderContext.depthTexture !== null ) {
651+
652+
const { textureGPU } = this.get( renderContext.depthTexture );
653+
654+
gl.framebufferTexture2D( gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.TEXTURE_2D, textureGPU, 0 );
655+
656+
}
657+
658+
renderContextData.framebuffer = fb;
659+
660+
} else {
661+
662+
gl.bindFramebuffer( gl.FRAMEBUFFER, fb );
663+
664+
}
665+
666+
} else {
667+
668+
gl.bindFramebuffer( gl.FRAMEBUFFER, null );
669+
670+
}
671+
672+
}
673+
621674
}
622675

623676
export default WebGLBackend;

examples/jsm/renderers/webgl/utils/WebGLTextureUtils.js

+13
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,19 @@ class WebGLTextureUtils {
140140

141141
}
142142

143+
if ( glFormat === gl.DEPTH_COMPONENT ) {
144+
145+
if ( glType === gl.UNSIGNED_INT ) internalFormat = gl.DEPTH_COMPONENT24;
146+
if ( glType === gl.FLOAT ) internalFormat = gl.DEPTH_COMPONENT32F;
147+
148+
}
149+
150+
if ( glFormat === gl.DEPTH_STENCIL ) {
151+
152+
if ( glType === gl.UNSIGNED_INT_24_8 ) internalFormat = gl.DEPTH24_STENCIL8;
153+
154+
}
155+
143156
if ( internalFormat === gl.R16F || internalFormat === gl.R32F ||
144157
internalFormat === gl.RG16F || internalFormat === gl.RG32F ||
145158
internalFormat === gl.RGBA16F || internalFormat === gl.RGBA32F ) {
8.09 KB
Loading
-586 Bytes
Loading

examples/screenshots/webgpu_rtt.jpg

2.31 KB
Loading

examples/webgpu_depth_texture.html

+4-2
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@
2929
import { texture, MeshBasicNodeMaterial } from 'three/nodes';
3030

3131
import WebGPU from 'three/addons/capabilities/WebGPU.js';
32+
import WebGL from 'three/addons/capabilities/WebGL.js';
33+
3234
import WebGPURenderer from 'three/addons/renderers/webgpu/WebGPURenderer.js';
3335

3436
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
@@ -43,11 +45,11 @@
4345

4446
function init() {
4547

46-
if ( WebGPU.isAvailable() === false ) {
48+
if ( WebGPU.isAvailable() === false && WebGL.isWebGL2Available() === false ) {
4749

4850
document.body.appendChild( WebGPU.getErrorMessage() );
4951

50-
throw new Error( 'No WebGPU support' );
52+
throw new Error( 'No WebGPU or WebGL2 support' );
5153

5254
}
5355

examples/webgpu_rtt.html

+4-2
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@
2929
import { texture, uniform, vec2, MeshBasicNodeMaterial } from 'three/nodes';
3030

3131
import WebGPU from 'three/addons/capabilities/WebGPU.js';
32+
import WebGL from 'three/addons/capabilities/WebGL.js';
33+
3234
import WebGPURenderer from 'three/addons/renderers/webgpu/WebGPURenderer.js';
3335

3436
let camera, scene, renderer;
@@ -44,11 +46,11 @@
4446

4547
function init() {
4648

47-
if ( WebGPU.isAvailable() === false ) {
49+
if ( WebGPU.isAvailable() === false && WebGL.isWebGL2Available() === false ) {
4850

4951
document.body.appendChild( WebGPU.getErrorMessage() );
5052

51-
throw new Error( 'No WebGPU support' );
53+
throw new Error( 'No WebGPU or WebGL2 support' );
5254

5355
}
5456

test/e2e/puppeteer.js

-2
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,6 @@ const exceptionList = [
116116
'webgpu_compute_texture',
117117
'webgpu_compute_texture_pingpong',
118118
'webgpu_cubemap_dynamic',
119-
'webgpu_depth_texture',
120119
'webgpu_instance_mesh',
121120
'webgpu_lines_fat',
122121
'webgpu_loader_gltf',
@@ -129,7 +128,6 @@ const exceptionList = [
129128
"webgpu_multiple_rendertargets",
130129
'webgpu_occlusion',
131130
'webgpu_particles',
132-
'webgpu_rtt',
133131
'webgpu_sandbox',
134132
'webgpu_shadowmap',
135133
'webgpu_skinning',

0 commit comments

Comments
 (0)