forked from mrdoob/three.js
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* MRT Support * Add MRT example * Rename AttachnemtsNum to NumAttachments * Reflect the review comments to webgl2_mrt.html * Define texture parameter via WebGLMultiRenderTarget constructor in MRT example * Minor clean up * Fix setupFrameBufferTextre(). Use texture.format/type instead of renderTarget.texture's * Use module in MRT example * Replace var with let or const * Replace ShaderMaterial with RawShaderMaterial for MRT example * Fix formatting * Fix for lint * Add MRT example screenshot * Reflect the review comments for WebGLMultiRenderTarget * Rename .textures to .texture in WebGLMultiRenderTarget * WebGLMultiRenderTarget: Remove setCount() * WebGLMultiRenderTarget: Method chain * WebGLMultiRenderTarget: More proper setTexture() and copy() * WebGLCapabilities: Use extensions.has() instead of .get() * WebGLMultiRenderTarget: Remove setTexture() * Rename WebGLMultiRenderTarget to WebGLMultipleRenderTargets
- Loading branch information
Showing
9 changed files
with
523 additions
and
22 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,277 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<title>three.js webgl - Multiple Render Targets</title> | ||
<meta charset="utf-8"> | ||
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0"> | ||
<style> | ||
body { | ||
font-family: Monospace; | ||
background-color: #000; | ||
color: #fff; | ||
margin: 0px; | ||
overflow: hidden; | ||
} | ||
#info { | ||
color: #fff; | ||
position: absolute; | ||
top: 10px; | ||
width: 100%; | ||
text-align: center; | ||
display:block; | ||
} | ||
#info a, .button { color: #f00; font-weight: bold; text-decoration: underline; cursor: pointer } | ||
</style> | ||
|
||
<!-- 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.rgb = mix( diffuse, normal, step( 0.5, vUv.x ) ); | ||
pc_FragColor.a = 1.0; | ||
|
||
} | ||
</script> | ||
|
||
</head> | ||
<body> | ||
<div id="info"> | ||
<a href="http://threejs.org" target="_blank">threejs</a> - WebGL - Multiple Render Targets<br/> | ||
Renders geometry into a G-Buffer.<br/> | ||
Visualized here is the color and normal data from the G-Buffer.<br/> | ||
Created by <a href="http://twitter.com/mattdesl" target="_blank">@mattdesl</a>. | ||
</div> | ||
|
||
<script type="module"> | ||
|
||
import * as THREE from '../build/three.module.js'; | ||
|
||
import { WEBGL } from './jsm/WebGL.js'; | ||
import { OrbitControls } from './jsm/controls/OrbitControls.js'; | ||
|
||
let container; | ||
let camera, scene, renderer, controls; | ||
let renderTarget; | ||
let postScene, postCamera; | ||
|
||
init(); | ||
|
||
function init() { | ||
|
||
if ( WEBGL.isWebGL2Available() === false ) { | ||
|
||
document.body.appendChild( WEBGL.getWebGL2ErrorMessage() ); | ||
return; | ||
|
||
} | ||
|
||
container = document.createElement( 'div' ); | ||
document.body.appendChild( container ); | ||
|
||
const canvas = document.createElement( 'canvas' ); | ||
const context = canvas.getContext( 'webgl2' ); | ||
|
||
renderer = new THREE.WebGLRenderer( { | ||
canvas: canvas, | ||
context: context | ||
} ); | ||
|
||
renderer.setPixelRatio( window.devicePixelRatio ); | ||
renderer.setSize( window.innerWidth, window.innerHeight ); | ||
container.appendChild( renderer.domElement ); | ||
|
||
// Create a multi render target with Float buffers | ||
|
||
renderTarget = new THREE.WebGLMultipleRenderTargets( | ||
window.innerWidth * window.devicePixelRatio, | ||
window.innerHeight * window.devicePixelRatio, | ||
2 | ||
); | ||
|
||
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(); | ||
|
||
camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 1, 10 ); | ||
camera.position.z = 4; | ||
|
||
const diffuse = new THREE.TextureLoader().load( | ||
|
||
'textures/brick_diffuse.jpg', | ||
|
||
function () { | ||
|
||
// ready to render | ||
render(); | ||
|
||
} | ||
|
||
); | ||
|
||
diffuse.wrapS = diffuse.wrapT = THREE.RepeatWrapping; | ||
|
||
scene.add( new THREE.Mesh( | ||
new THREE.TorusKnotGeometry( 1, 0.3, 128, 64 ), | ||
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 ) } | ||
}, | ||
glslVersion: THREE.GLSL3 | ||
} ) | ||
) ); | ||
|
||
// 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, false ); | ||
|
||
} | ||
|
||
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 ); | ||
|
||
} | ||
|
||
</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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
import { WebGLRenderTarget } from './WebGLRenderTarget.js'; | ||
|
||
class WebGLMultipleRenderTargets extends WebGLRenderTarget { | ||
|
||
constructor( width, height, count ) { | ||
|
||
super( width, height ); | ||
|
||
const texture = this.texture; | ||
|
||
this.texture = []; | ||
|
||
for ( let i = 0; i < count; i ++ ) { | ||
|
||
this.texture[ i ] = texture.clone(); | ||
|
||
} | ||
|
||
} | ||
|
||
setSize( width, height, depth = 1 ) { | ||
|
||
if ( this.width !== width || this.height !== height || this.depth !== depth ) { | ||
|
||
this.width = width; | ||
this.height = height; | ||
this.depth = depth; | ||
|
||
for ( let i = 0, il = this.texture.length; i < il; i ++ ) { | ||
|
||
this.texture[ i ].image.width = width; | ||
this.texture[ i ].image.height = height; | ||
this.texture[ i ].image.depth = depth; | ||
|
||
} | ||
|
||
this.dispose(); | ||
|
||
} | ||
|
||
this.viewport.set( 0, 0, width, height ); | ||
this.scissor.set( 0, 0, width, height ); | ||
|
||
return this; | ||
|
||
} | ||
|
||
copy( source ) { | ||
|
||
this.dispose(); | ||
|
||
this.width = source.width; | ||
this.height = source.height; | ||
this.depth = source.depth; | ||
|
||
this.viewport.set( 0, 0, this.width, this.height ); | ||
this.scissor.set( 0, 0, this.width, this.height ); | ||
|
||
this.depthBuffer = source.depthBuffer; | ||
this.stencilBuffer = source.stencilBuffer; | ||
this.depthTexture = source.depthTexture; | ||
|
||
this.texture.length = 0; | ||
|
||
for ( let i = 0, il = source.texture.length; i < il; i ++ ) { | ||
|
||
this.texture[ i ] = source.texture[ i ].clone(); | ||
|
||
} | ||
|
||
return this; | ||
|
||
} | ||
|
||
} | ||
|
||
WebGLMultipleRenderTargets.prototype.isWebGLMultipleRenderTargets = true; | ||
|
||
export { WebGLMultipleRenderTargets }; |
Oops, something went wrong.