Skip to content

Commit 7a12ec3

Browse files
aardgooseaardgoose
andauthored
WebGPURenderer: Support WebGLCubeRenderTarget (#27071)
* cube render targets * implemenet destroyAttribute() * replicate WebGPU texture filtering * missed ; * allow tests to run * reinstate flip * add missing ; * repair damage --------- Co-authored-by: aardgoose <[email protected]>
1 parent 5ddba19 commit 7a12ec3

File tree

11 files changed

+118
-36
lines changed

11 files changed

+118
-36
lines changed

examples/jsm/nodes/accessors/CubeTextureNode.js

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import TextureNode from './TextureNode.js';
22
import { reflectVector } from './ReflectVectorNode.js';
33
import { addNodeClass } from '../core/Node.js';
44
import { addNodeElement, nodeProxy, vec3 } from '../shadernode/ShaderNode.js';
5+
import { WebGPUCoordinateSystem } from 'three';
56

67
class CubeTextureNode extends TextureNode {
78

@@ -29,7 +30,17 @@ class CubeTextureNode extends TextureNode {
2930

3031
setupUV( builder, uvNode ) {
3132

32-
return vec3( uvNode.x.negate(), uvNode.yz );
33+
const texture = this.value;
34+
35+
if ( builder.renderer.coordinateSystem === WebGPUCoordinateSystem || ! texture.isRenderTargetTexture ) {
36+
37+
return vec3( uvNode.x.negate(), uvNode.yz );
38+
39+
} else {
40+
41+
return uvNode;
42+
43+
}
3344

3445
}
3546

examples/jsm/renderers/common/nodes/Nodes.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,7 @@ class Nodes extends DataMap {
314314
if ( background.mapping === EquirectangularReflectionMapping || background.mapping === EquirectangularRefractionMapping ) {
315315

316316
nodeUV = equirectUV();
317+
background.flipY = false;
317318

318319
} else {
319320

examples/jsm/renderers/webgl/WebGLBackend.js

Lines changed: 63 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import WebGLTextureUtils from './utils/WebGLTextureUtils.js';
1010
import WebGLExtensions from './utils/WebGLExtensions.js';
1111
import WebGLCapabilities from './utils/WebGLCapabilities.js';
1212
import { GLFeatureName } from './utils/WebGLConstants.js';
13+
1314
//
1415

1516
class WebGLBackend extends Backend {
@@ -115,6 +116,24 @@ class WebGLBackend extends Backend {
115116
const renderContextData = this.get( renderContext );
116117
const previousContext = renderContextData.previousContext;
117118

119+
const textures = renderContext.textures;
120+
121+
if ( textures !== null ) {
122+
123+
for ( let i = 0; i < textures.length; i ++ ) {
124+
125+
const texture = textures[ i ];
126+
127+
if ( texture.generateMipmaps ) {
128+
129+
this.generateMipmaps( texture );
130+
131+
}
132+
133+
}
134+
135+
}
136+
118137
this._currentContext = previousContext;
119138

120139

@@ -809,9 +828,9 @@ class WebGLBackend extends Backend {
809828

810829
}
811830

812-
destroyAttribute( /*attribute*/ ) {
831+
destroyAttribute( attribute ) {
813832

814-
console.warn( 'Abstract class.' );
833+
this.attributeUtils.destroyAttribute( attribute );
815834

816835
}
817836

@@ -855,18 +874,36 @@ class WebGLBackend extends Backend {
855874

856875
const { gl, state } = this;
857876

858-
let fb = null;
859877
let currentFrameBuffer = null;
860878

861879
if ( renderContext.textures !== null ) {
862880

863-
const renderTargetContextData = this.get( renderContext.renderTarget );
864-
const { samples } = renderContext.renderTarget;
881+
const renderTarget = renderContext.renderTarget;
882+
const renderTargetContextData = this.get( renderTarget );
883+
const { samples } = renderTarget;
884+
const cubeFace = this.renderer._activeCubeFace;
885+
const isCube = renderTarget.isWebGLCubeRenderTarget === true;
865886

866-
fb = renderTargetContextData.framebuffer;
867887
let msaaFb = renderTargetContextData.msaaFrameBuffer;
868888
let depthRenderbuffer = renderTargetContextData.depthRenderbuffer;
869889

890+
let fb;
891+
892+
if ( isCube ) {
893+
894+
if ( renderTargetContextData.cubeFramebuffers === undefined ) {
895+
896+
renderTargetContextData.cubeFramebuffers = [];
897+
898+
}
899+
900+
fb = renderTargetContextData.cubeFramebuffers[ cubeFace ];
901+
902+
} else {
903+
904+
fb = renderTargetContextData.framebuffer;
905+
906+
}
870907

871908
if ( fb === undefined ) {
872909

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

877914
const textures = renderContext.textures;
878915

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

881-
const texture = textures[ i ];
882-
const textureData = this.get( texture );
883-
textureData.renderTarget = renderContext.renderTarget;
918+
renderTargetContextData.cubeFramebuffers[ cubeFace ] = fb;
919+
const { textureGPU } = this.get( textures[ 0 ] );
884920

885-
const attachment = gl.COLOR_ATTACHMENT0 + i;
921+
gl.framebufferTexture2D( gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_CUBE_MAP_POSITIVE_X + cubeFace, textureGPU, 0 );
922+
923+
} else {
886924

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

888-
gl.framebufferTexture2D( gl.FRAMEBUFFER, attachment, gl.TEXTURE_2D, textureData.textureGPU, 0 );
927+
const texture = textures[ i ];
928+
const textureData = this.get( texture );
929+
textureData.renderTarget = renderContext.renderTarget;
930+
931+
const attachment = gl.COLOR_ATTACHMENT0 + i;
932+
933+
gl.framebufferTexture2D( gl.FRAMEBUFFER, attachment, gl.TEXTURE_2D, textureData.textureGPU, 0 );
934+
935+
}
936+
937+
renderTargetContextData.framebuffer = fb;
938+
939+
state.drawBuffers( renderContext, fb );
889940

890941
}
891942

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

898949
}
899950

900-
901-
renderTargetContextData.framebuffer = fb;
902-
903-
state.drawBuffers( renderContext, fb );
904-
905951
}
906952

907953
if ( samples > 0 ) {

examples/jsm/renderers/webgl/nodes/GLSLNodeBuilder.js

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -99,11 +99,7 @@ ${ flowData.code }
9999

100100
generateTexture( texture, textureProperty, uvSnippet, depthSnippet ) {
101101

102-
if ( texture.isTextureCube ) {
103-
104-
return `textureCube( ${ textureProperty }, ${ uvSnippet } )`;
105-
106-
} else if ( texture.isDepthTexture ) {
102+
if ( texture.isDepthTexture ) {
107103

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

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

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,25 @@ class WebGLAttributeUtils {
134134

135135
}
136136

137+
destroyAttribute( attribute ) {
138+
139+
const backend = this.backend;
140+
const { gl } = backend;
141+
142+
if ( attribute.isInterleavedBufferAttribute ) {
143+
144+
backend.delete( attribute.data );
145+
146+
}
147+
148+
const attributeData = backend.get( attribute );
149+
150+
gl.deleteBuffer( attributeData.bufferGPU );
151+
152+
backend.delete( attribute );
153+
154+
}
155+
137156
async getArrayBufferAsync( attribute ) {
138157

139158
const backend = this.backend;

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,12 @@ class WebGLTextureUtils {
184184
}
185185

186186
gl.texParameteri( textureType, gl.TEXTURE_MAG_FILTER, filterToGL[ texture.magFilter ] );
187-
gl.texParameteri( textureType, gl.TEXTURE_MIN_FILTER, filterToGL[ texture.minFilter ] );
187+
188+
189+
// follow WebGPU backend mapping for texture filtering
190+
const minFilter = texture.minFilter === LinearFilter ? LinearMipmapLinearFilter : texture.minFilter;
191+
192+
gl.texParameteri( textureType, gl.TEXTURE_MIN_FILTER, filterToGL[ minFilter ] );
188193

189194
if ( texture.compareFunction ) {
190195

examples/webgpu_cubemap_dynamic.html

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131
import * as Nodes from 'three/nodes';
3232

3333
import WebGPU from 'three/addons/capabilities/WebGPU.js';
34+
import WebGL from 'three/addons/capabilities/WebGL.js';
35+
3436
import WebGPURenderer from 'three/addons/renderers/webgpu/WebGPURenderer.js';
3537

3638
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
@@ -50,11 +52,11 @@
5052

5153
function init() {
5254

53-
if ( WebGPU.isAvailable() === false ) {
55+
if ( WebGPU.isAvailable() === false && WebGL.isWebGL2Available() === false ) {
5456

5557
document.body.appendChild( WebGPU.getErrorMessage() );
5658

57-
throw new Error( 'No WebGPU support' );
59+
throw new Error( 'No WebGPU or WebGL2 support' );
5860

5961
}
6062

examples/webgpu_loader_gltf.html

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@
2929
import * as THREE from 'three';
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 { RGBELoader } from 'three/addons/loaders/RGBELoader.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_loader_gltf_iridescence.html

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828
import * as THREE from 'three';
2929

3030
import WebGPU from 'three/addons/capabilities/WebGPU.js';
31+
import WebGL from 'three/addons/capabilities/WebGL.js';
32+
3133
import WebGPURenderer from 'three/addons/renderers/webgpu/WebGPURenderer.js';
3234

3335
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
@@ -44,11 +46,11 @@
4446

4547
async 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

examples/webgpu_loader_gltf_sheen.html

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@
3232
import * as THREE from 'three';
3333

3434
import WebGPU from 'three/addons/capabilities/WebGPU.js';
35+
import WebGL from 'three/addons/capabilities/WebGL.js';
36+
3537
import WebGPURenderer from 'three/addons/renderers/webgpu/WebGPURenderer.js';
3638

3739
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
@@ -46,11 +48,11 @@
4648

4749
function init() {
4850

49-
if ( WebGPU.isAvailable() === false ) {
51+
if ( WebGPU.isAvailable() === false && WebGL.isWebGL2Available() === false ) {
5052

5153
document.body.appendChild( WebGPU.getErrorMessage() );
5254

53-
throw new Error( 'No WebGPU support' );
55+
throw new Error( 'No WebGPU or WebGL2 support' );
5456

5557
}
5658

0 commit comments

Comments
 (0)