-
-
Notifications
You must be signed in to change notification settings - Fork 35.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[WebGLMultipleRenderTarget] Support Multisampling
[WebGLMultipleRenderTarget] Support Multisampling clean bufferattributes code clean bufferattributes code
- Loading branch information
1 parent
e4ecf73
commit ded9004
Showing
7 changed files
with
413 additions
and
56 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
323 changes: 323 additions & 0 deletions
323
examples/webgl2_multiple_rendertargets_multisampled.html
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,323 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<title>three.js webgl - Multiple Render Targets MultiSampled</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"> | ||
|
||
<!-- Write to G-Buffer --> | ||
<script id="gbuffer-vert" type="x-shader/x-vertex"> | ||
in vec3 position; | ||
in vec3 normal; | ||
in vec2 uv; | ||
|
||
out vec3 vNormal; | ||
out vec2 vUv; | ||
|
||
uniform mat4 modelViewMatrix; | ||
uniform mat4 projectionMatrix; | ||
uniform mat3 normalMatrix; | ||
|
||
void main() { | ||
|
||
vUv = uv; | ||
|
||
// get smooth normals | ||
vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 ); | ||
|
||
vec3 transformedNormal = normalMatrix * normal; | ||
vNormal = normalize( transformedNormal ); | ||
|
||
gl_Position = projectionMatrix * mvPosition; | ||
|
||
} | ||
</script> | ||
<script id="gbuffer-frag" type="x-shader/x-fragment"> | ||
precision highp float; | ||
precision highp int; | ||
|
||
layout(location = 0) out vec4 gColor; | ||
layout(location = 1) out vec4 gNormal; | ||
|
||
uniform sampler2D tDiffuse; | ||
uniform vec2 repeat; | ||
|
||
in vec3 vNormal; | ||
in vec2 vUv; | ||
|
||
void main() { | ||
|
||
// write color to G-Buffer | ||
gColor = texture( tDiffuse, vUv * repeat ); | ||
|
||
// write normals to G-Buffer | ||
gNormal = vec4( normalize( vNormal ), 0.0 ); | ||
|
||
} | ||
</script> | ||
|
||
<!-- Read G-Buffer and render to screen --> | ||
<script id="render-vert" type="x-shader/x-vertex"> | ||
in vec3 position; | ||
in vec2 uv; | ||
|
||
out vec2 vUv; | ||
|
||
uniform mat4 modelViewMatrix; | ||
uniform mat4 projectionMatrix; | ||
|
||
void main() { | ||
|
||
vUv = uv; | ||
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); | ||
|
||
} | ||
</script> | ||
<script id="render-frag" type="x-shader/x-fragment"> | ||
precision highp float; | ||
precision highp int; | ||
|
||
layout(location = 0) out vec4 pc_FragColor; | ||
|
||
in vec2 vUv; | ||
|
||
uniform sampler2D tDiffuse; | ||
uniform sampler2D tNormal; | ||
|
||
void main() { | ||
|
||
vec3 diffuse = texture( tDiffuse, vUv ).rgb; | ||
vec3 normal = texture( tNormal, vUv ).rgb; | ||
|
||
pc_FragColor = vec4(vec3(0.), 1.); | ||
pc_FragColor.rgb += mix( diffuse, normal, step( 0.5, vUv.x ) ); | ||
|
||
} | ||
</script> | ||
|
||
</head> | ||
<body> | ||
<div id="info"> | ||
<a href="http://threejs.org" target="_blank">threejs</a> - WebGL - Multiple Render Targets Multisampled<br/> | ||
Created by <a href="http://twitter.com/onirenaud" target="_blank">@onirenaud</a> with the help of <a href="http://twitter.com/Cody_J_Bennett" target="_blank">@Cody_J_Bennett</a>. | ||
</div> | ||
<div id="container"> | ||
</div> | ||
<!-- 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" | ||
} | ||
} | ||
</script> | ||
|
||
<script type="module"> | ||
|
||
import * as THREE from 'three'; | ||
|
||
import WebGL from './jsm/capabilities/WebGL.js'; | ||
import { OrbitControls } from './jsm/controls/OrbitControls.js'; | ||
import { GUI } from './jsm/libs/lil-gui.module.min.js'; | ||
import Stats from './jsm/libs/stats.module.js'; | ||
|
||
let camera, scene, renderer, controls, container, group; | ||
let renderTarget; | ||
let postScene, postCamera; | ||
let stats; | ||
|
||
const clock = new THREE.Clock(); | ||
// Create a multi render target with Float buffers | ||
const gui = new GUI(); | ||
|
||
const effectController = { | ||
msaa: true, | ||
}; | ||
|
||
init(); | ||
gui.add( effectController, 'msaa', true ).onChange(() => { | ||
|
||
renderTarget.samples = effectController.msaa ? 4 : 0; | ||
render(); | ||
|
||
}) | ||
|
||
function init() { | ||
|
||
container = document.getElementById( 'container' ); | ||
|
||
if ( WebGL.isWebGL2Available() === false ) { | ||
|
||
document.body.appendChild( WebGL.getWebGL2ErrorMessage() ); | ||
return; | ||
|
||
} | ||
|
||
renderer = new THREE.WebGLRenderer(); | ||
renderer.setPixelRatio( window.devicePixelRatio ); | ||
renderer.setSize( window.innerWidth, window.innerHeight ); | ||
container.appendChild( renderer.domElement ); | ||
|
||
stats = new Stats(); | ||
stats.domElement.style.position = 'absolute'; | ||
stats.domElement.style.top = '0px'; | ||
container.appendChild( stats.domElement ); | ||
|
||
|
||
renderTarget = new THREE.WebGLMultipleRenderTargets( | ||
window.innerWidth * window.devicePixelRatio, | ||
window.innerHeight * window.devicePixelRatio, | ||
2, | ||
{ | ||
samples: effectController.msaa ? 4 : 0 | ||
} | ||
); | ||
|
||
for ( let i = 0, il = renderTarget.texture.length; i < il; i ++ ) { | ||
|
||
renderTarget.texture[ i ].minFilter = THREE.NearestFilter; | ||
renderTarget.texture[ i ].magFilter = THREE.NearestFilter; | ||
renderTarget.texture[ i ].type = THREE.FloatType; | ||
|
||
} | ||
|
||
// Name our G-Buffer attachments for debugging | ||
|
||
renderTarget.texture[ 0 ].name = 'diffuse'; | ||
renderTarget.texture[ 1 ].name = 'normal'; | ||
|
||
// Scene setup | ||
|
||
scene = new THREE.Scene(); | ||
scene.background = new THREE.Color( 0xa0a0a0 ); | ||
|
||
const hemiLight = new THREE.HemisphereLight( 0xffffff, 0x444444 ); | ||
hemiLight.position.set( 0, 20, 0 ); | ||
scene.add( hemiLight ); | ||
container = document.getElementById( 'container' ); | ||
|
||
camera = new THREE.PerspectiveCamera( 45, container.offsetWidth / container.offsetHeight, 1, 2000 ); | ||
camera.position.z = 500; | ||
|
||
const diffuse = new THREE.TextureLoader().load( | ||
|
||
'textures/brick_diffuse.jpg', | ||
|
||
function () { | ||
|
||
// ready to render | ||
render(); | ||
|
||
} | ||
|
||
); | ||
|
||
diffuse.wrapS = diffuse.wrapT = THREE.RepeatWrapping; | ||
|
||
group = new THREE.Group(); | ||
|
||
const geometry = new THREE.SphereGeometry( 10, 64, 40 ); | ||
|
||
for ( let i = 0; i < 20; i ++ ) { | ||
|
||
const material = new THREE.RawShaderMaterial( { | ||
vertexShader: document.querySelector( '#gbuffer-vert' ).textContent.trim(), | ||
fragmentShader: document.querySelector( '#gbuffer-frag' ).textContent.trim(), | ||
uniforms: { | ||
tDiffuse: { value: diffuse }, | ||
repeat: { value: new THREE.Vector2( 5, 0.5 ) } | ||
}, | ||
wireframe: i % 2 === 0, | ||
glslVersion: THREE.GLSL3 | ||
} ) | ||
|
||
const mesh = new THREE.Mesh( geometry, material ); | ||
mesh.position.x = Math.random() * 600 - 300; | ||
mesh.position.y = Math.random() * 600 - 300; | ||
mesh.position.z = Math.random() * 600 - 300; | ||
mesh.rotation.x = Math.random(); | ||
mesh.rotation.z = Math.random(); | ||
mesh.scale.setScalar( Math.random() * 5 + 5 ); | ||
group.add( mesh ); | ||
|
||
|
||
} | ||
scene.add( group ); | ||
// PostProcessing setup | ||
|
||
postScene = new THREE.Scene(); | ||
postCamera = new THREE.OrthographicCamera( - 1, 1, 1, - 1, 0, 1 ); | ||
|
||
postScene.add( new THREE.Mesh( | ||
new THREE.PlaneGeometry( 2, 2 ), | ||
new THREE.RawShaderMaterial( { | ||
vertexShader: document.querySelector( '#render-vert' ).textContent.trim(), | ||
fragmentShader: document.querySelector( '#render-frag' ).textContent.trim(), | ||
uniforms: { | ||
tDiffuse: { value: renderTarget.texture[ 0 ] }, | ||
tNormal: { value: renderTarget.texture[ 1 ] }, | ||
}, | ||
glslVersion: THREE.GLSL3 | ||
} ) | ||
) ); | ||
|
||
// Controls | ||
|
||
controls = new OrbitControls( camera, renderer.domElement ); | ||
controls.addEventListener( 'change', render ); | ||
controls.enableZoom = false; | ||
controls.screenSpacePanning = true; | ||
|
||
|
||
window.addEventListener( 'resize', onWindowResize ); | ||
|
||
animate() | ||
} | ||
|
||
function onWindowResize() { | ||
|
||
camera.aspect = window.innerWidth / window.innerHeight; | ||
camera.updateProjectionMatrix(); | ||
|
||
renderer.setSize( window.innerWidth, window.innerHeight ); | ||
|
||
const dpr = renderer.getPixelRatio(); | ||
renderTarget.setSize( window.innerWidth * dpr, window.innerHeight * dpr ); | ||
|
||
render(); | ||
|
||
} | ||
|
||
function render() { | ||
|
||
// render scene into target | ||
renderer.setRenderTarget( renderTarget ); | ||
renderer.render( scene, camera ); | ||
|
||
// render post FX | ||
renderer.setRenderTarget( null ); | ||
renderer.render( postScene, postCamera ); | ||
|
||
} | ||
|
||
function animate() { | ||
|
||
requestAnimationFrame( animate ); | ||
|
||
controls.update(); | ||
|
||
group.rotation.y += clock.getDelta() * 0.1; | ||
|
||
stats.update(); | ||
render(); | ||
|
||
} | ||
|
||
</script> | ||
|
||
</body> | ||
</html> |
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
Oops, something went wrong.