Skip to content

Commit 666bb55

Browse files
author
aardgoose
committed
support multiple screen canvas targets
1 parent 936402c commit 666bb55

File tree

17 files changed

+708
-311
lines changed

17 files changed

+708
-311
lines changed

examples/files.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,7 @@
351351
"webgpu_materials_toon",
352352
"webgpu_materials_video",
353353
"webgpu_materialx_noise",
354+
"webgpu_multiple_canvases",
354355
"webgpu_multiple_rendertargets",
355356
"webgpu_multiple_rendertargets_readback",
356357
"webgpu_morphtargets",

examples/jsm/nodes/display/PassNode.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,9 +135,10 @@ class PassNode extends TempNode {
135135
const { renderer } = frame;
136136
const { scene, camera } = this;
137137

138-
this._pixelRatio = renderer.getPixelRatio();
138+
const canvasRenderTarget = renderer.getActiveCanvasRenderTarget();
139+
this._pixelRatio = canvasRenderTarget.getPixelRatio();
139140

140-
const size = renderer.getSize( _size );
141+
const size = canvasRenderTarget.getSize( _size );
141142

142143
this.setSize( size.width, size.height );
143144

examples/jsm/nodes/display/ViewportNode.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,11 @@ class ViewportNode extends Node {
4747

4848
if ( this.scope === ViewportNode.VIEWPORT ) {
4949

50-
renderer.getViewport( viewportResult );
50+
renderer.getActiveCanvasRenderTarget().getViewport( viewportResult );
5151

5252
} else {
5353

54-
renderer.getDrawingBufferSize( resolution );
54+
renderer.getActiveCanvasRenderTarget().getDrawingBufferSize( resolution );
5555

5656
}
5757

examples/jsm/nodes/display/ViewportTextureNode.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ class ViewportTextureNode extends TextureNode {
3131
updateBefore( frame ) {
3232

3333
const renderer = frame.renderer;
34-
renderer.getDrawingBufferSize( _size );
34+
renderer.getActiveCanvasRenderTarget().getDrawingBufferSize( _size );
3535

3636
//
3737

examples/jsm/nodes/utils/ReflectorNode.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ class ReflectorNode extends TextureNode {
5555

5656
const resolution = this.resolution;
5757

58-
renderer.getDrawingBufferSize( _size );
58+
renderer.getActiveCanvasRenderTarget().getDrawingBufferSize( _size );
5959

6060
renderTarget.setSize( Math.round( _size.width * resolution ), Math.round( _size.height * resolution ) );
6161

@@ -126,7 +126,7 @@ class ReflectorNode extends TextureNode {
126126
const virtualCamera = this.getVirtualCamera( camera );
127127
const renderTarget = this.getRenderTarget( virtualCamera );
128128

129-
renderer.getDrawingBufferSize( _size );
129+
renderer.getActiveCanvasRenderTarget().getDrawingBufferSize( _size );
130130

131131
this._updateResolution( renderTarget, renderer );
132132

examples/jsm/renderers/common/Backend.js

Lines changed: 1 addition & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
1-
let vector2 = null;
2-
let vector4 = null;
31
let color4 = null;
42

53
import Color4 from './Color4.js';
6-
import { Vector2, Vector4, REVISION, createCanvasElement } from 'three';
4+
import { REVISION, createCanvasElement } from 'three';
75

86
class Backend {
97

@@ -86,8 +84,6 @@ class Backend {
8684

8785
getContext() { }
8886

89-
updateSize() { }
90-
9187
// utils
9288

9389
resolveTimestampAsync( renderContext, type ) { }
@@ -104,22 +100,6 @@ class Backend {
104100

105101
}
106102

107-
getDrawingBufferSize() {
108-
109-
vector2 = vector2 || new Vector2();
110-
111-
return this.renderer.getDrawingBufferSize( vector2 );
112-
113-
}
114-
115-
getScissor() {
116-
117-
vector4 = vector4 || new Vector4();
118-
119-
return this.renderer.getScissor( vector4 );
120-
121-
}
122-
123103
setScissorTest( boolean ) { }
124104

125105
getClearColor() {
Lines changed: 225 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,225 @@
1+
import { EventDispatcher, Vector4, REVISION, createCanvasElement, SRGBColorSpace } from 'three';
2+
3+
class CanvasRenderTarget extends EventDispatcher {
4+
5+
constructor( parameters ) {
6+
7+
super();
8+
9+
this.isCanvasRenderTarget = true;
10+
11+
this.canvas = parameters.canvas;
12+
this.context = parameters.context;
13+
this._domElement = parameters.domElement;
14+
this.alpha = ( parameters.alpha === undefined ) ? true : parameters.alpha;
15+
16+
this.antialias = ( parameters.antialias === true );
17+
18+
if ( this.antialias === true ) {
19+
20+
this.sampleCount = ( parameters.sampleCount === undefined ) ? 4 : parameters.sampleCount;
21+
22+
} else {
23+
24+
this.sampleCount = 1;
25+
26+
}
27+
28+
this.outputColorSpace = SRGBColorSpace;
29+
30+
this.depth = true;
31+
this.stencil = false;
32+
33+
this._width = 0;
34+
this._height = 0;
35+
this.pixelRatio = 1;
36+
37+
this.viewport = new Vector4( 0, 0, this._width, this._height );
38+
this.scissor = new Vector4( 0, 0, this._width, this._height );
39+
this.scissorTest = false;
40+
41+
this.version = 0;
42+
43+
}
44+
45+
set needsUpdate( value ) {
46+
47+
if ( value === true ) this.version ++;
48+
49+
}
50+
51+
get domElement() {
52+
53+
let domElement = this._domElement;
54+
55+
if ( ! domElement ) {
56+
57+
domElement = ( this.canvas !== undefined ) ? this.canvas : createCanvasElement();
58+
59+
// OffscreenCanvas does not have setAttribute, see #22811
60+
if ( 'setAttribute' in domElement ) domElement.setAttribute( 'data-engine', `three.js r${REVISION} webgpu` );
61+
62+
this._domElement = domElement;
63+
64+
}
65+
66+
return domElement;
67+
68+
}
69+
70+
get samples() {
71+
72+
return this.sampleCount;
73+
74+
}
75+
76+
get depthBuffer() {
77+
78+
return this.depth;
79+
80+
}
81+
82+
get stencilBuffer() {
83+
84+
return this.stencil;
85+
86+
}
87+
88+
getPixelRatio() {
89+
90+
return this.pixelRatio;
91+
92+
}
93+
94+
getDrawingBufferSize( target ) {
95+
96+
return target.set( this._width * this.pixelRatio, this._height * this.pixelRatio ).floor();
97+
98+
}
99+
100+
getSize( target ) {
101+
102+
return target.set( this._width, this._height );
103+
104+
}
105+
106+
setPixelRatio( value = 1 ) {
107+
108+
this.pixelRatio = value;
109+
110+
this.setSize( this._width, this._height, false );
111+
112+
}
113+
114+
setDrawingBufferSize( width, height, pixelRatio ) {
115+
116+
this._width = width;
117+
this._height = height;
118+
119+
this.pixelRatio = pixelRatio;
120+
121+
this.domElement.width = Math.floor( width * pixelRatio );
122+
this.domElement.height = Math.floor( height * pixelRatio );
123+
124+
this.setViewport( 0, 0, width, height );
125+
126+
this.needsUpdate = true;
127+
128+
}
129+
130+
setSize( width, height, updateStyle = true ) {
131+
132+
this._width = width;
133+
this._height = height;
134+
135+
this.domElement.width = Math.floor( width * this.pixelRatio );
136+
this.domElement.height = Math.floor( height * this.pixelRatio );
137+
138+
if ( updateStyle === true ) {
139+
140+
this.domElement.style.width = width + 'px';
141+
this.domElement.style.height = height + 'px';
142+
143+
}
144+
145+
this.setViewport( 0, 0, width, height );
146+
147+
this.needsUpdate = true;
148+
149+
}
150+
151+
getScissor( target ) {
152+
153+
const scissor = this.scissor;
154+
155+
target.x = scissor.x;
156+
target.y = scissor.y;
157+
target.width = scissor.width;
158+
target.height = scissor.height;
159+
160+
return target;
161+
162+
}
163+
164+
setScissor( x, y, width, height ) {
165+
166+
const scissor = this.scissor;
167+
168+
if ( x.isVector4 ) {
169+
170+
scissor.copy( x );
171+
172+
} else {
173+
174+
scissor.set( x, y, width, height );
175+
176+
}
177+
178+
}
179+
180+
getScissorTest() {
181+
182+
return this.scissorTest;
183+
184+
}
185+
186+
setScissorTest( value ) {
187+
188+
this.scissorTest = value;
189+
190+
}
191+
192+
getViewport( target ) {
193+
194+
return target.copy( this.viewport );
195+
196+
}
197+
198+
setViewport( x, y, width, height, minDepth = 0, maxDepth = 1 ) {
199+
200+
const viewport = this.viewport;
201+
202+
if ( x.isVector4 ) {
203+
204+
viewport.copy( x );
205+
206+
} else {
207+
208+
viewport.set( x, y, width, height );
209+
210+
}
211+
212+
viewport.minDepth = minDepth;
213+
viewport.maxDepth = maxDepth;
214+
215+
}
216+
217+
dispose() {
218+
219+
this.dispatchEvent( { type: 'dispose' } );
220+
221+
}
222+
223+
}
224+
225+
export default CanvasRenderTarget;

examples/jsm/renderers/common/RenderContexts.js

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,15 @@ class RenderContexts {
99

1010
}
1111

12-
get( scene, camera, renderTarget = null ) {
12+
get( scene, camera, renderTarget ) {
1313

1414
const chainKey = [ scene, camera ];
1515

1616
let attachmentState;
1717

18-
if ( renderTarget === null ) {
18+
if ( renderTarget.isCanvasRenderTarget ) {
1919

20-
attachmentState = 'default';
20+
attachmentState = `${ renderTarget.samples }:${ renderTarget.depth }:${ renderTarget.stencil }`;
2121

2222
} else {
2323

@@ -38,9 +38,11 @@ class RenderContexts {
3838

3939
chainMap.set( chainKey, renderState );
4040

41-
}
41+
renderState.sampleCount = renderTarget.samples === 0 ? 1 : renderTarget.samples;
42+
renderState.depth = renderTarget.depthBuffer;
43+
renderState.stencil = renderTarget.stencilBuffer;
4244

43-
if ( renderTarget !== null ) renderState.sampleCount = renderTarget.samples === 0 ? 1 : renderTarget.samples;
45+
}
4446

4547
return renderState;
4648

0 commit comments

Comments
 (0)