forked from mrdoob/three.js
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(examples): Add alpha hash example.
- Loading branch information
1 parent
9c03ed5
commit 4a474d4
Showing
3 changed files
with
225 additions
and
0 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
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,224 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<title>three.js webgl - materials - alpha hash</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> | ||
<!-- Import maps polyfill --> | ||
<!-- Remove this when import maps will be widely supported --> | ||
<script async src="https://unpkg.com/[email protected]/dist/es-module-shims.js"></script> | ||
|
||
<script type="importmap"> | ||
{ | ||
"imports": { | ||
"three": "../build/three.module.js", | ||
"three/addons/": "./jsm/" | ||
} | ||
} | ||
</script> | ||
|
||
<script type="module"> | ||
|
||
import * as THREE from 'three'; | ||
|
||
import Stats from 'three/addons/libs/stats.module.js'; | ||
import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; | ||
import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; | ||
|
||
import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js'; | ||
import { RenderPass } from 'three/addons/postprocessing/RenderPass.js'; | ||
import { TAARenderPass } from 'three/addons/postprocessing/TAARenderPass.js'; | ||
import { OutputPass } from 'three/addons/postprocessing/OutputPass.js'; | ||
|
||
let camera, scene, renderer, controls, stats, mesh, material; | ||
|
||
let composer, renderPass, taaRenderPass, outputPass; | ||
|
||
let needsUpdate = false; | ||
|
||
const amount = parseInt( window.location.search.slice( 1 ) ) || 3; | ||
const count = Math.pow( amount, 3 ); | ||
|
||
const color = new THREE.Color(); | ||
|
||
const params = { | ||
alpha: 0.4, | ||
alphaHash: true, | ||
taa: true, | ||
sampleLevel: 2, | ||
}; | ||
|
||
init(); | ||
animate(); | ||
|
||
function init() { | ||
|
||
camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 0.1, 100 ); | ||
camera.position.set( amount, amount, amount ); | ||
camera.lookAt( 0, 0, 0 ); | ||
|
||
scene = new THREE.Scene(); | ||
|
||
const light = new THREE.HemisphereLight( 0xffffff, 0x888888 ); | ||
light.position.set( 0, 1, 0 ); | ||
scene.add( light ); | ||
|
||
const geometry = new THREE.IcosahedronGeometry( 0.5, 3 ); | ||
|
||
material = new THREE.MeshStandardMaterial( { | ||
color: 0xffffff, | ||
alphaHash: true, | ||
opacity: 0.5 | ||
} ); | ||
|
||
mesh = new THREE.InstancedMesh( geometry, material, count ); | ||
|
||
let i = 0; | ||
const offset = ( amount - 1 ) / 2; | ||
|
||
const matrix = new THREE.Matrix4(); | ||
|
||
for ( let x = 0; x < amount; x ++ ) { | ||
|
||
for ( let y = 0; y < amount; y ++ ) { | ||
|
||
for ( let z = 0; z < amount; z ++ ) { | ||
|
||
matrix.setPosition( offset - x, offset - y, offset - z ); | ||
|
||
mesh.setMatrixAt( i, matrix ); | ||
mesh.setColorAt( i, color.setHex( Math.random() * 0xffffff ) ); | ||
|
||
i ++; | ||
|
||
} | ||
|
||
} | ||
|
||
} | ||
|
||
scene.add( mesh ); | ||
|
||
// | ||
|
||
renderer = new THREE.WebGLRenderer( { antialias: true } ); | ||
renderer.setPixelRatio( window.devicePixelRatio ); | ||
renderer.setSize( window.innerWidth, window.innerHeight ); | ||
document.body.appendChild( renderer.domElement ); | ||
|
||
// | ||
|
||
composer = new EffectComposer( renderer ); | ||
|
||
renderPass = new RenderPass( scene, camera ); | ||
renderPass.enabled = false; | ||
|
||
taaRenderPass = new TAARenderPass( scene, camera ); | ||
taaRenderPass.params = { type: THREE.HalfFloatType }; | ||
|
||
outputPass = new OutputPass(); | ||
|
||
composer.addPass( renderPass ); | ||
composer.addPass( taaRenderPass ); | ||
composer.addPass( outputPass ); | ||
|
||
// | ||
|
||
controls = new OrbitControls( camera, renderer.domElement ); | ||
controls.enableDamping = true; | ||
controls.enableZoom = false; | ||
controls.enablePan = false; | ||
controls.dampingFactor = 0.2; | ||
|
||
controls.addEventListener( 'change', () => ( needsUpdate = true ) ); | ||
|
||
// | ||
|
||
const gui = new GUI(); | ||
|
||
gui.add( params, 'alpha', 0, 1 ).onChange( onMaterialUpdate ); | ||
gui.add( params, 'alphaHash' ).onChange( onMaterialUpdate ); | ||
|
||
const taaFolder = gui.addFolder( 'Temporal Anti-Aliasing' ); | ||
|
||
taaFolder.add( params, 'taa' ).name( 'enabled' ).onChange( () => { | ||
|
||
renderPass.enabled = ! params.taa; | ||
taaRenderPass.enabled = params.taa; | ||
|
||
sampleLevelCtrl.enable( params.taa ); | ||
|
||
needsUpdate = true; | ||
|
||
} ); | ||
|
||
const sampleLevelCtrl = taaFolder.add( params, 'sampleLevel', 0, 6, 1 ).onChange( () => ( needsUpdate = true ) ); | ||
|
||
// | ||
|
||
stats = new Stats(); | ||
document.body.appendChild( stats.dom ); | ||
|
||
window.addEventListener( 'resize', onWindowResize ); | ||
|
||
} | ||
|
||
function onWindowResize() { | ||
|
||
camera.aspect = window.innerWidth / window.innerHeight; | ||
camera.updateProjectionMatrix(); | ||
|
||
renderer.setSize( window.innerWidth, window.innerHeight ); | ||
|
||
} | ||
|
||
function onMaterialUpdate() { | ||
|
||
material.opacity = params.alpha; | ||
material.alphaHash = params.alphaHash; | ||
material.transparent = ! params.alphaHash; | ||
material.depthWrite = params.alphaHash; | ||
|
||
material.needsUpdate = true; | ||
needsUpdate = true; | ||
|
||
} | ||
|
||
function animate() { | ||
|
||
requestAnimationFrame( animate ); | ||
|
||
controls.update(); | ||
|
||
render(); | ||
|
||
stats.update(); | ||
|
||
} | ||
|
||
function render() { | ||
|
||
if ( needsUpdate ) { | ||
|
||
taaRenderPass.accumulate = false; | ||
taaRenderPass.sampleLevel = 0; | ||
|
||
needsUpdate = false; | ||
|
||
} else { | ||
|
||
taaRenderPass.accumulate = true; | ||
taaRenderPass.sampleLevel = params.sampleLevel; | ||
|
||
} | ||
|
||
composer.render(); | ||
|
||
} | ||
|
||
</script> | ||
</body> | ||
</html> |