-
-
Notifications
You must be signed in to change notification settings - Fork 36k
WebGPURenderer: Introduce CanvasRenderTarget
#31730
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
+349
−5
Closed
Changes from all commits
Commits
Show all changes
17 commits
Select commit
Hold shift + click to select a range
27cd9ec
Introduce `CanvasRenderTarget`
sunag b508986
add `webgpu_multiple_canvas` example
sunag 6320c01
Update Renderer.js
sunag e984691
Update puppeteer.js
sunag 11f20dd
Merge branch 'dev' into dev-canvas-render-target
sunag d1dd08e
use internalFormat for now
sunag 255f9dc
respect pixel ratio
sunag 6e83427
cleanup
sunag f00f900
improve antialiasing performance - wip
sunag 6ab90e3
cleanup
sunag 976b9a2
cleanup
sunag d96bac8
cleanup
sunag 7eb1acb
Update PassNode.js
sunag b5530bd
Merge branch 'dev-aa' into dev-canvas-render-target
sunag 3440446
fix canvas texture check
sunag e54dd1b
Merge branch 'dev-canvas-render-target' of https://github.com/sunag/t…
sunag 0f164e3
Merge branch 'dev' into dev-canvas-render-target
sunag File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,200 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<title>three.js webgpu - multiple canvas</title> | ||
<meta charset="utf-8"> | ||
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0"> | ||
<link type="text/css" rel="stylesheet" href="main.css"> | ||
<style> | ||
|
||
* { | ||
box-sizing: border-box; | ||
-moz-box-sizing: border-box; | ||
} | ||
|
||
body { | ||
background-color: #fff; | ||
color: #444; | ||
} | ||
|
||
a { | ||
color: #08f; | ||
} | ||
|
||
#content { | ||
position: absolute; | ||
top: 0; width: 100%; | ||
z-index: 1; | ||
padding: 3em 0 0 0; | ||
} | ||
|
||
.list-item { | ||
display: inline-block; | ||
margin: 1em; | ||
padding: 1em; | ||
box-shadow: 1px 2px 4px 0px rgba(0,0,0,0.25); | ||
} | ||
|
||
.list-item > canvas:nth-child(1) { | ||
width: 200px; | ||
height: 200px; | ||
} | ||
|
||
.list-item > div:nth-child(2) { | ||
color: #888; | ||
font-family: sans-serif; | ||
font-size: large; | ||
width: 200px; | ||
margin-top: 0.5em; | ||
} | ||
|
||
</style> | ||
</head> | ||
<body> | ||
|
||
<div id="content"> | ||
<div id="info"><a href="https://threejs.org" target="_blank" rel="noopener">three.js</a> - multiple canvas</div> | ||
</div> | ||
|
||
<script type="importmap"> | ||
{ | ||
"imports": { | ||
"three": "../build/three.webgpu.js", | ||
"three/webgpu": "../build/three.webgpu.js", | ||
"three/tsl": "../build/three.tsl.js", | ||
"three/addons/": "./jsm/" | ||
} | ||
} | ||
</script> | ||
|
||
<script type="module"> | ||
|
||
import * as THREE from 'three'; | ||
import { color } from 'three/tsl'; | ||
|
||
import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; | ||
|
||
import WebGPU from 'three/addons/capabilities/WebGPU.js'; | ||
|
||
// | ||
|
||
if ( WebGPU.isAvailable() === false ) { | ||
|
||
document.body.appendChild( WebGPU.getErrorMessage() ); | ||
|
||
throw new Error( 'No WebGPU support' ); | ||
|
||
} | ||
|
||
// | ||
|
||
let renderer; | ||
|
||
const scenes = []; | ||
|
||
init(); | ||
|
||
function init() { | ||
|
||
const geometries = [ | ||
new THREE.BoxGeometry( 1, 1, 1 ), | ||
new THREE.SphereGeometry( 0.5, 12, 8 ), | ||
new THREE.DodecahedronGeometry( 0.5 ), | ||
new THREE.CylinderGeometry( 0.5, 0.5, 1, 12 ) | ||
]; | ||
|
||
const content = document.getElementById( 'content' ); | ||
|
||
for ( let i = 0; i < 40; i ++ ) { | ||
|
||
const scene = new THREE.Scene(); | ||
scene.backgroundNode = color( 0xeeeeee ); | ||
|
||
// make a list item | ||
const element = document.createElement( 'div' ); | ||
element.className = 'list-item'; | ||
|
||
const sceneCanvas = document.createElement( 'canvas' ); | ||
sceneCanvas.width = Math.floor( 200 * window.devicePixelRatio ); | ||
sceneCanvas.height = Math.floor( 200 * window.devicePixelRatio ); | ||
element.appendChild( sceneCanvas ); | ||
|
||
const descriptionElement = document.createElement( 'div' ); | ||
descriptionElement.innerText = 'Scene ' + ( i + 1 ); | ||
element.appendChild( descriptionElement ); | ||
|
||
// the element that represents the area we want to render the scene | ||
scene.userData.canvasRenderTarget = new THREE.CanvasRenderTarget( sceneCanvas ); | ||
content.appendChild( element ); | ||
|
||
const camera = new THREE.PerspectiveCamera( 50, 1, 1, 10 ); | ||
camera.position.z = 2; | ||
scene.userData.camera = camera; | ||
|
||
const controls = new OrbitControls( scene.userData.camera, scene.userData.canvasRenderTarget.canvas ); | ||
controls.minDistance = 2; | ||
controls.maxDistance = 5; | ||
controls.enablePan = false; | ||
controls.enableZoom = false; | ||
scene.userData.controls = controls; | ||
|
||
// add one random mesh to each scene | ||
const geometry = geometries[ geometries.length * Math.random() | 0 ]; | ||
|
||
const material = new THREE.MeshStandardMaterial( { | ||
|
||
color: new THREE.Color().setHSL( Math.random(), 1, 0.75, THREE.SRGBColorSpace ), | ||
roughness: 0.5, | ||
metalness: 0, | ||
flatShading: true | ||
|
||
} ); | ||
|
||
scene.add( new THREE.Mesh( geometry, material ) ); | ||
|
||
scene.add( new THREE.HemisphereLight( 0xaaaaaa, 0x444444, 3 ) ); | ||
|
||
const light = new THREE.DirectionalLight( 0xffffff, 1.5 ); | ||
light.position.set( 1, 1, 1 ); | ||
scene.add( light ); | ||
|
||
scenes.push( scene ); | ||
|
||
} | ||
|
||
renderer = new THREE.WebGPURenderer( { antialias: true } ); | ||
renderer.setClearColor( 0xffffff, 1 ); | ||
renderer.setPixelRatio( window.devicePixelRatio ); | ||
renderer.setAnimationLoop( animate ); | ||
|
||
} | ||
|
||
function animate() { | ||
|
||
scenes.forEach( function ( scene ) { | ||
|
||
// so something moves | ||
//scene.children[ 0 ].rotation.y = Date.now() * 0.001; | ||
|
||
// get the canvas render target | ||
const canvasRenderTarget = scene.userData.canvasRenderTarget; | ||
|
||
// get the camera | ||
const camera = scene.userData.camera; | ||
|
||
//camera.aspect = width / height; // not changing in this example | ||
//camera.updateProjectionMatrix(); | ||
|
||
//scene.userData.controls.update(); | ||
|
||
renderer.setOutputRenderTarget( canvasRenderTarget ); | ||
renderer.render( scene, camera ); | ||
|
||
} ); | ||
|
||
} | ||
|
||
</script> | ||
|
||
</body> | ||
</html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
import { RenderTarget } from './RenderTarget.js'; | ||
import { REVISION } from '../constants.js'; | ||
|
||
/** | ||
* CanvasRenderTarget is a specialized RenderTarget for rendering to a Canvas element. | ||
* | ||
* @augments RenderTarget | ||
*/ | ||
class CanvasRenderTarget extends RenderTarget { | ||
|
||
/** | ||
* @param {HTMLCanvasElement|OffscreenCanvas} canvas - The canvas to use as the render target. | ||
* @param {Object} [options={}] - Optional parameters for the render target. | ||
*/ | ||
constructor( canvas, options = {} ) { | ||
|
||
super( canvas.width, canvas.height, options ); | ||
|
||
// OffscreenCanvas does not have setAttribute, see #22811 | ||
if ( 'setAttribute' in canvas ) canvas.setAttribute( 'data-engine', `three.js r${ REVISION } webgpu` ); | ||
|
||
this.canvas = canvas; | ||
|
||
this.isCanvasRenderTarget = true; | ||
|
||
} | ||
|
||
/** | ||
* Sets the size of the canvas. | ||
* | ||
* @param {number} width - The new width of the canvas. | ||
* @param {number} height - The new height of the canvas. | ||
* @returns {CanvasRenderTarget} The updated render target. | ||
*/ | ||
setSize( width, height ) { | ||
|
||
this.canvas.width = width; | ||
this.canvas.height = height; | ||
|
||
return super.setSize( width, height ); | ||
|
||
} | ||
|
||
} | ||
|
||
export { CanvasRenderTarget }; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you mind explaining why you have added this line?
We should check if this addition does not break XR.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After setting
setRenderTarget()
asoutputRenderTarget
it does not restore the previous state, making the currentgetRenderTarget()
the same asgetOutputRenderTarget()
after the render, thus being a bug.Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I try to make a test with a Quest 2 tomorrorw. Just to be on the safe side since r180 is released next week.