Skip to content

Commit

Permalink
WebGPURenderer: Basic render to texture support for WebGL backend (#2…
Browse files Browse the repository at this point in the history
…6801)

* Support texture backed render targets

* actually use the framebuffer we have cached

* update examples

* update screenshots

---------

Co-authored-by: aardgoose <angus.sawyer@email.com>
  • Loading branch information
aardgoose and aardgoose committed Sep 20, 2023
1 parent bc69abb commit ef417f0
Show file tree
Hide file tree
Showing 8 changed files with 75 additions and 7 deletions.
55 changes: 54 additions & 1 deletion examples/jsm/renderers/webgl/WebGLBackend.js
Expand Up @@ -54,6 +54,8 @@ class WebGLBackend extends Backend {

//

this._setFramebuffer( renderContext );

let clear = 0;

if ( renderContext.clearColor ) clear |= gl.COLOR_BUFFER_BIT;
Expand All @@ -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 );

//
Expand Down Expand Up @@ -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 changes: 13 additions & 0 deletions examples/jsm/renderers/webgl/utils/WebGLTextureUtils.js
Expand Up @@ -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 ) {
Expand Down
Binary file modified examples/screenshots/webgpu_depth_texture.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified examples/screenshots/webgpu_lights_custom.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified examples/screenshots/webgpu_rtt.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 4 additions & 2 deletions examples/webgpu_depth_texture.html
Expand Up @@ -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';
Expand All @@ -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' );

}

Expand Down
6 changes: 4 additions & 2 deletions examples/webgpu_rtt.html
Expand Up @@ -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;
Expand All @@ -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' );

}

Expand Down
2 changes: 0 additions & 2 deletions test/e2e/puppeteer.js
Expand Up @@ -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',
Expand All @@ -129,7 +128,6 @@ const exceptionList = [
"webgpu_multiple_rendertargets",
'webgpu_occlusion',
'webgpu_particles',
'webgpu_rtt',
'webgpu_sandbox',
'webgpu_shadowmap',
'webgpu_skinning',
Expand Down

0 comments on commit ef417f0

Please sign in to comment.