Skip to content

Commit

Permalink
support multiple screen canvas targets
Browse files Browse the repository at this point in the history
  • Loading branch information
aardgoose committed May 30, 2024
1 parent 14093e1 commit dded9a3
Show file tree
Hide file tree
Showing 17 changed files with 708 additions and 311 deletions.
1 change: 1 addition & 0 deletions examples/files.json
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,7 @@
"webgpu_materials_toon",
"webgpu_materials_video",
"webgpu_materialx_noise",
"webgpu_multiple_canvases",
"webgpu_multiple_rendertargets",
"webgpu_multiple_rendertargets_readback",
"webgpu_morphtargets",
Expand Down
5 changes: 3 additions & 2 deletions examples/jsm/nodes/display/PassNode.js
Original file line number Diff line number Diff line change
Expand Up @@ -135,9 +135,10 @@ class PassNode extends TempNode {
const { renderer } = frame;
const { scene, camera } = this;

this._pixelRatio = renderer.getPixelRatio();
const canvasRenderTarget = renderer.getActiveCanvasRenderTarget();
this._pixelRatio = canvasRenderTarget.getPixelRatio();

const size = renderer.getSize( _size );
const size = canvasRenderTarget.getSize( _size );

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

Expand Down
4 changes: 2 additions & 2 deletions examples/jsm/nodes/display/ViewportNode.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,11 @@ class ViewportNode extends Node {

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

renderer.getViewport( viewportResult );
renderer.getActiveCanvasRenderTarget().getViewport( viewportResult );

} else {

renderer.getDrawingBufferSize( resolution );
renderer.getActiveCanvasRenderTarget().getDrawingBufferSize( resolution );

}

Expand Down
2 changes: 1 addition & 1 deletion examples/jsm/nodes/display/ViewportTextureNode.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class ViewportTextureNode extends TextureNode {
updateBefore( frame ) {

const renderer = frame.renderer;
renderer.getDrawingBufferSize( _size );
renderer.getActiveCanvasRenderTarget().getDrawingBufferSize( _size );

//

Expand Down
4 changes: 2 additions & 2 deletions examples/jsm/nodes/utils/ReflectorNode.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ class ReflectorNode extends TextureNode {

const resolution = this.resolution;

renderer.getDrawingBufferSize( _size );
renderer.getActiveCanvasRenderTarget().getDrawingBufferSize( _size );

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

Expand Down Expand Up @@ -126,7 +126,7 @@ class ReflectorNode extends TextureNode {
const virtualCamera = this.getVirtualCamera( camera );
const renderTarget = this.getRenderTarget( virtualCamera );

renderer.getDrawingBufferSize( _size );
renderer.getActiveCanvasRenderTarget().getDrawingBufferSize( _size );

this._updateResolution( renderTarget, renderer );

Expand Down
22 changes: 1 addition & 21 deletions examples/jsm/renderers/common/Backend.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
let vector2 = null;
let vector4 = null;
let color4 = null;

import Color4 from './Color4.js';
import { Vector2, Vector4, REVISION, createCanvasElement } from 'three';
import { REVISION, createCanvasElement } from 'three';

class Backend {

Expand Down Expand Up @@ -86,8 +84,6 @@ class Backend {

getContext() { }

updateSize() { }

// utils

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

}

getDrawingBufferSize() {

vector2 = vector2 || new Vector2();

return this.renderer.getDrawingBufferSize( vector2 );

}

getScissor() {

vector4 = vector4 || new Vector4();

return this.renderer.getScissor( vector4 );

}

setScissorTest( boolean ) { }

getClearColor() {
Expand Down
225 changes: 225 additions & 0 deletions examples/jsm/renderers/common/CanvasRenderTarget.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,225 @@
import { EventDispatcher, Vector4, REVISION, createCanvasElement, SRGBColorSpace } from 'three';

class CanvasRenderTarget extends EventDispatcher {

constructor( parameters ) {

super();

this.isCanvasRenderTarget = true;

this.canvas = parameters.canvas;
this.context = parameters.context;
this._domElement = parameters.domElement;
this.alpha = ( parameters.alpha === undefined ) ? true : parameters.alpha;

this.antialias = ( parameters.antialias === true );

if ( this.antialias === true ) {

this.sampleCount = ( parameters.sampleCount === undefined ) ? 4 : parameters.sampleCount;

} else {

this.sampleCount = 1;

}

this.outputColorSpace = SRGBColorSpace;

this.depth = true;
this.stencil = false;

this._width = 0;
this._height = 0;
this.pixelRatio = 1;

this.viewport = new Vector4( 0, 0, this._width, this._height );
this.scissor = new Vector4( 0, 0, this._width, this._height );
this.scissorTest = false;

this.version = 0;

}

set needsUpdate( value ) {

if ( value === true ) this.version ++;

}

get domElement() {

let domElement = this._domElement;

if ( ! domElement ) {

domElement = ( this.canvas !== undefined ) ? this.canvas : createCanvasElement();

// OffscreenCanvas does not have setAttribute, see #22811
if ( 'setAttribute' in domElement ) domElement.setAttribute( 'data-engine', `three.js r${REVISION} webgpu` );

this._domElement = domElement;

}

return domElement;

}

get samples() {

return this.sampleCount;

}

get depthBuffer() {

return this.depth;

}

get stencilBuffer() {

return this.stencil;

}

getPixelRatio() {

return this.pixelRatio;

}

getDrawingBufferSize( target ) {

return target.set( this._width * this.pixelRatio, this._height * this.pixelRatio ).floor();

}

getSize( target ) {

return target.set( this._width, this._height );

}

setPixelRatio( value = 1 ) {

this.pixelRatio = value;

this.setSize( this._width, this._height, false );

}

setDrawingBufferSize( width, height, pixelRatio ) {

this._width = width;
this._height = height;

this.pixelRatio = pixelRatio;

this.domElement.width = Math.floor( width * pixelRatio );
this.domElement.height = Math.floor( height * pixelRatio );

this.setViewport( 0, 0, width, height );

this.needsUpdate = true;

}

setSize( width, height, updateStyle = true ) {

this._width = width;
this._height = height;

this.domElement.width = Math.floor( width * this.pixelRatio );
this.domElement.height = Math.floor( height * this.pixelRatio );

if ( updateStyle === true ) {

this.domElement.style.width = width + 'px';
this.domElement.style.height = height + 'px';

}

this.setViewport( 0, 0, width, height );

this.needsUpdate = true;

}

getScissor( target ) {

const scissor = this.scissor;

target.x = scissor.x;
target.y = scissor.y;
target.width = scissor.width;
target.height = scissor.height;

return target;

}

setScissor( x, y, width, height ) {

const scissor = this.scissor;

if ( x.isVector4 ) {

scissor.copy( x );

} else {

scissor.set( x, y, width, height );

}

}

getScissorTest() {

return this.scissorTest;

}

setScissorTest( value ) {

this.scissorTest = value;

}

getViewport( target ) {

return target.copy( this.viewport );

}

setViewport( x, y, width, height, minDepth = 0, maxDepth = 1 ) {

const viewport = this.viewport;

if ( x.isVector4 ) {

viewport.copy( x );

} else {

viewport.set( x, y, width, height );

}

viewport.minDepth = minDepth;
viewport.maxDepth = maxDepth;

}

dispose() {

this.dispatchEvent( { type: 'dispose' } );

}

}

export default CanvasRenderTarget;
12 changes: 7 additions & 5 deletions examples/jsm/renderers/common/RenderContexts.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,15 @@ class RenderContexts {

}

get( scene, camera, renderTarget = null ) {
get( scene, camera, renderTarget ) {

const chainKey = [ scene, camera ];

let attachmentState;

if ( renderTarget === null ) {
if ( renderTarget.isCanvasRenderTarget ) {

attachmentState = 'default';
attachmentState = `${ renderTarget.samples }:${ renderTarget.depth }:${ renderTarget.stencil }`;

} else {

Expand All @@ -38,9 +38,11 @@ class RenderContexts {

chainMap.set( chainKey, renderState );

}
renderState.sampleCount = renderTarget.samples === 0 ? 1 : renderTarget.samples;
renderState.depth = renderTarget.depthBuffer;
renderState.stencil = renderTarget.stencilBuffer;

if ( renderTarget !== null ) renderState.sampleCount = renderTarget.samples === 0 ? 1 : renderTarget.samples;
}

return renderState;

Expand Down
Loading

0 comments on commit dded9a3

Please sign in to comment.