-
-
Notifications
You must be signed in to change notification settings - Fork 35.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
WebGPURenderer: Add
textureGrad
support (#28048)
* support texture grad * cleanup * add texture vs textureGrad example
- Loading branch information
1 parent
7a08fc4
commit 75b06a1
Showing
6 changed files
with
198 additions
and
4 deletions.
There are no files selected for viewing
This file contains 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 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 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 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 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,154 @@ | ||
<html lang="en"> | ||
<head> | ||
<title>three.js - WebGPU - Texture Gradient</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"> | ||
</head> | ||
<body> | ||
|
||
<div id="info"> | ||
<a href="https://threejs.org" target="_blank" rel="noopener">three.js</a> | ||
<br />This example demonstrate texture gradient | ||
<br /> Left canvas is using WebGPU Backend, right canvas is WebGL Backend. | ||
<br /> The bottom half of the texture benefits from the gradient to achieve better blur quality. | ||
</div> | ||
|
||
<script type="importmap"> | ||
{ | ||
"imports": { | ||
"three": "../build/three.module.js", | ||
"three/addons/": "./jsm/", | ||
"three/nodes": "./jsm/nodes/Nodes.js" | ||
} | ||
} | ||
</script> | ||
|
||
<script type="module"> | ||
|
||
import * as THREE from 'three'; | ||
import { If, vec4, float, timerLocal, cos, pow, vec2, uv, texture, tslFn, MeshBasicNodeMaterial } from 'three/nodes'; | ||
|
||
import WebGPURenderer from 'three/addons/renderers/webgpu/WebGPURenderer.js'; | ||
|
||
|
||
// WebGPU Backend | ||
init(); | ||
|
||
// WebGL Backend | ||
init( true ); | ||
|
||
async function init( forceWebGL = false ) { | ||
|
||
const aspect = ( window.innerWidth / 2 ) / window.innerHeight; | ||
const camera = new THREE.OrthographicCamera( - aspect, aspect ); | ||
camera.position.z = 2; | ||
|
||
const scene = new THREE.Scene(); | ||
|
||
// texture | ||
|
||
const material = new MeshBasicNodeMaterial( { color: 0xffffff } ); | ||
|
||
// load async brick_diffuse | ||
const map = await new THREE.TextureLoader().loadAsync( 'textures/uv_grid_opengl.jpg' ); | ||
|
||
const elapsedTime = timerLocal(); | ||
material.colorNode = tslFn( () => { | ||
|
||
const color = vec4( 1. ).toVar(); | ||
|
||
const vuv = uv().toVar(); | ||
const blur = pow( float( 0.0625 ).sub( cos( vuv.x.mul( 20.0 ).add( elapsedTime ) ) ).mul( 0.0625 ), 2.0 ); | ||
|
||
const grad = vec2( blur ).toVar(); | ||
|
||
If( vuv.y.greaterThan( 0.5 ), () => { | ||
|
||
grad.assign( 0 ); | ||
|
||
} ); | ||
|
||
color.assign( | ||
texture( map, vuv.add( vec2( blur, blur ).mul( 0.5 ) ) ).grad( grad, grad ).mul( 0.25 ) | ||
.add( texture( map, vuv.add( vec2( blur, blur.negate() ).mul( 0.5 ) ) ).grad( grad, grad ).mul( 0.25 ) ) | ||
.add( texture( map, vuv.add( vec2( blur.negate(), blur ).mul( 0.5 ) ) ).grad( grad, grad ).mul( 0.25 ) ) | ||
.add( texture( map, vuv.add( vec2( blur.negate(), blur.negate() ).mul( 0.5 ) ) ).grad( grad, grad ).mul( 0.25 ) ) | ||
); | ||
|
||
|
||
If( vuv.y.greaterThan( 0.497 ).and( vuv.y.lessThan( 0.503 ) ), () => { | ||
|
||
color.assign( 1 ); | ||
|
||
} ); | ||
|
||
|
||
return color; | ||
|
||
} )(); | ||
|
||
// | ||
|
||
const box = new THREE.Mesh( new THREE.PlaneGeometry( 1, 1 ), material ); | ||
scene.add( box ); | ||
|
||
const renderer = new WebGPURenderer( { antialias: false, forceWebGL: forceWebGL, trackTimestamp: true } ); | ||
renderer.setPixelRatio( window.devicePixelRatio ); | ||
renderer.setSize( window.innerWidth / 2, window.innerHeight ); | ||
|
||
document.body.appendChild( renderer.domElement ); | ||
renderer.domElement.style.position = 'absolute'; | ||
renderer.domElement.style.top = '0'; | ||
renderer.domElement.style.left = '0'; | ||
renderer.domElement.style.width = '50%'; | ||
renderer.domElement.style.height = '100%'; | ||
|
||
if ( forceWebGL ) { | ||
|
||
renderer.domElement.style.left = '50%'; | ||
|
||
scene.background = new THREE.Color( 0x212121 ); | ||
|
||
} else { | ||
|
||
scene.background = new THREE.Color( 0x313131 ); | ||
|
||
} | ||
|
||
// | ||
|
||
|
||
const animate = async function () { | ||
|
||
await renderer.renderAsync( scene, camera ); | ||
|
||
|
||
}; | ||
|
||
renderer.setAnimationLoop( animate ); | ||
|
||
window.addEventListener( 'resize', onWindowResize ); | ||
|
||
function onWindowResize() { | ||
|
||
renderer.setSize( window.innerWidth / 2, window.innerHeight ); | ||
|
||
const aspect = ( window.innerWidth / 2 ) / window.innerHeight; | ||
|
||
const frustumHeight = camera.top - camera.bottom; | ||
|
||
camera.left = - frustumHeight * aspect / 2; | ||
camera.right = frustumHeight * aspect / 2; | ||
|
||
camera.updateProjectionMatrix(); | ||
|
||
renderer.render( scene, camera ); | ||
|
||
} | ||
|
||
} | ||
|
||
</script> | ||
</body> | ||
</html> |