Skip to content

Commit

Permalink
WebGPURenderer: Support WebGLCubeRenderTarget (mrdoob#27071)
Browse files Browse the repository at this point in the history
* cube render targets

* implemenet destroyAttribute()

* replicate WebGPU texture filtering

* missed ;

* allow tests to run

* reinstate flip

* add missing ;

* repair damage

---------

Co-authored-by: aardgoose <angus.sawyer@email.com>
  • Loading branch information
2 people authored and AdaRoseCannon committed Jan 15, 2024
1 parent e17a838 commit 31daa7a
Show file tree
Hide file tree
Showing 11 changed files with 118 additions and 36 deletions.
13 changes: 12 additions & 1 deletion examples/jsm/nodes/accessors/CubeTextureNode.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import TextureNode from './TextureNode.js';
import { reflectVector } from './ReflectVectorNode.js';
import { addNodeClass } from '../core/Node.js';
import { addNodeElement, nodeProxy, vec3 } from '../shadernode/ShaderNode.js';
import { WebGPUCoordinateSystem } from 'three';

class CubeTextureNode extends TextureNode {

Expand Down Expand Up @@ -29,7 +30,17 @@ class CubeTextureNode extends TextureNode {

setupUV( builder, uvNode ) {

return vec3( uvNode.x.negate(), uvNode.yz );
const texture = this.value;

if ( builder.renderer.coordinateSystem === WebGPUCoordinateSystem || ! texture.isRenderTargetTexture ) {

return vec3( uvNode.x.negate(), uvNode.yz );

} else {

return uvNode;

}

}

Expand Down
1 change: 1 addition & 0 deletions examples/jsm/renderers/common/nodes/Nodes.js
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,7 @@ class Nodes extends DataMap {
if ( background.mapping === EquirectangularReflectionMapping || background.mapping === EquirectangularRefractionMapping ) {

nodeUV = equirectUV();
background.flipY = false;

} else {

Expand Down
80 changes: 63 additions & 17 deletions examples/jsm/renderers/webgl/WebGLBackend.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import WebGLTextureUtils from './utils/WebGLTextureUtils.js';
import WebGLExtensions from './utils/WebGLExtensions.js';
import WebGLCapabilities from './utils/WebGLCapabilities.js';
import { GLFeatureName } from './utils/WebGLConstants.js';

//

class WebGLBackend extends Backend {
Expand Down Expand Up @@ -115,6 +116,24 @@ class WebGLBackend extends Backend {
const renderContextData = this.get( renderContext );
const previousContext = renderContextData.previousContext;

const textures = renderContext.textures;

if ( textures !== null ) {

for ( let i = 0; i < textures.length; i ++ ) {

const texture = textures[ i ];

if ( texture.generateMipmaps ) {

this.generateMipmaps( texture );

}

}

}

this._currentContext = previousContext;


Expand Down Expand Up @@ -809,9 +828,9 @@ class WebGLBackend extends Backend {

}

destroyAttribute( /*attribute*/ ) {
destroyAttribute( attribute ) {

console.warn( 'Abstract class.' );
this.attributeUtils.destroyAttribute( attribute );

}

Expand Down Expand Up @@ -855,18 +874,36 @@ class WebGLBackend extends Backend {

const { gl, state } = this;

let fb = null;
let currentFrameBuffer = null;

if ( renderContext.textures !== null ) {

const renderTargetContextData = this.get( renderContext.renderTarget );
const { samples } = renderContext.renderTarget;
const renderTarget = renderContext.renderTarget;
const renderTargetContextData = this.get( renderTarget );
const { samples } = renderTarget;
const cubeFace = this.renderer._activeCubeFace;
const isCube = renderTarget.isWebGLCubeRenderTarget === true;

fb = renderTargetContextData.framebuffer;
let msaaFb = renderTargetContextData.msaaFrameBuffer;
let depthRenderbuffer = renderTargetContextData.depthRenderbuffer;

let fb;

if ( isCube ) {

if ( renderTargetContextData.cubeFramebuffers === undefined ) {

renderTargetContextData.cubeFramebuffers = [];

}

fb = renderTargetContextData.cubeFramebuffers[ cubeFace ];

} else {

fb = renderTargetContextData.framebuffer;

}

if ( fb === undefined ) {

Expand All @@ -876,16 +913,30 @@ class WebGLBackend extends Backend {

const textures = renderContext.textures;

for ( let i = 0; i < textures.length; i ++ ) {
if ( isCube ) {

const texture = textures[ i ];
const textureData = this.get( texture );
textureData.renderTarget = renderContext.renderTarget;
renderTargetContextData.cubeFramebuffers[ cubeFace ] = fb;
const { textureGPU } = this.get( textures[ 0 ] );

const attachment = gl.COLOR_ATTACHMENT0 + i;
gl.framebufferTexture2D( gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_CUBE_MAP_POSITIVE_X + cubeFace, textureGPU, 0 );

} else {

for ( let i = 0; i < textures.length; i ++ ) {

gl.framebufferTexture2D( gl.FRAMEBUFFER, attachment, gl.TEXTURE_2D, textureData.textureGPU, 0 );
const texture = textures[ i ];
const textureData = this.get( texture );
textureData.renderTarget = renderContext.renderTarget;

const attachment = gl.COLOR_ATTACHMENT0 + i;

gl.framebufferTexture2D( gl.FRAMEBUFFER, attachment, gl.TEXTURE_2D, textureData.textureGPU, 0 );

}

renderTargetContextData.framebuffer = fb;

state.drawBuffers( renderContext, fb );

}

Expand All @@ -897,11 +948,6 @@ class WebGLBackend extends Backend {

}


renderTargetContextData.framebuffer = fb;

state.drawBuffers( renderContext, fb );

}

if ( samples > 0 ) {
Expand Down
6 changes: 1 addition & 5 deletions examples/jsm/renderers/webgl/nodes/GLSLNodeBuilder.js
Original file line number Diff line number Diff line change
Expand Up @@ -99,11 +99,7 @@ ${ flowData.code }

generateTexture( texture, textureProperty, uvSnippet, depthSnippet ) {

if ( texture.isTextureCube ) {

return `textureCube( ${ textureProperty }, ${ uvSnippet } )`;

} else if ( texture.isDepthTexture ) {
if ( texture.isDepthTexture ) {

return `texture( ${ textureProperty }, ${ uvSnippet } ).x`;

Expand Down
19 changes: 19 additions & 0 deletions examples/jsm/renderers/webgl/utils/WebGLAttributeUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,25 @@ class WebGLAttributeUtils {

}

destroyAttribute( attribute ) {

const backend = this.backend;
const { gl } = backend;

if ( attribute.isInterleavedBufferAttribute ) {

backend.delete( attribute.data );

}

const attributeData = backend.get( attribute );

gl.deleteBuffer( attributeData.bufferGPU );

backend.delete( attribute );

}

async getArrayBufferAsync( attribute ) {

const backend = this.backend;
Expand Down
7 changes: 6 additions & 1 deletion examples/jsm/renderers/webgl/utils/WebGLTextureUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,12 @@ class WebGLTextureUtils {
}

gl.texParameteri( textureType, gl.TEXTURE_MAG_FILTER, filterToGL[ texture.magFilter ] );
gl.texParameteri( textureType, gl.TEXTURE_MIN_FILTER, filterToGL[ texture.minFilter ] );


// follow WebGPU backend mapping for texture filtering
const minFilter = texture.minFilter === LinearFilter ? LinearMipmapLinearFilter : texture.minFilter;

gl.texParameteri( textureType, gl.TEXTURE_MIN_FILTER, filterToGL[ minFilter ] );

if ( texture.compareFunction ) {

Expand Down
6 changes: 4 additions & 2 deletions examples/webgpu_cubemap_dynamic.html
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@
import * as Nodes 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 @@ -50,11 +52,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_loader_gltf.html
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
import * as THREE from 'three';

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 { RGBELoader } from 'three/addons/loaders/RGBELoader.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_loader_gltf_iridescence.html
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
import * as THREE from 'three';

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 @@ -44,11 +46,11 @@

async 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_loader_gltf_sheen.html
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
import * as THREE from 'three';

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 @@ -46,11 +48,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
4 changes: 0 additions & 4 deletions test/e2e/puppeteer.js
Original file line number Diff line number Diff line change
Expand Up @@ -117,11 +117,7 @@ const exceptionList = [
'webgpu_compute_points',
'webgpu_compute_texture',
'webgpu_compute_texture_pingpong',
'webgpu_cubemap_dynamic',
'webgpu_loader_gltf',
'webgpu_loader_gltf_compressed',
'webgpu_loader_gltf_iridescence',
'webgpu_loader_gltf_sheen',
'webgpu_materials',
'webgpu_portal',
'webgpu_sandbox',
Expand Down

0 comments on commit 31daa7a

Please sign in to comment.