|
@@ -31,142 +31,75 @@
|
|
|
</head>
|
|
|
<body>
|
|
|
|
|
|
- <div id="container"></div>
|
|
|
<div id="info">
|
|
|
- <a href="http://threejs.org" target="_blank" rel="noopener">three.js</a> - webgl HDR texture loader example -
|
|
|
- based on <a href="http://spidergl.org/example.php?id=13" target="_blank" rel="noopener">SpiderGL</a>
|
|
|
+ <a href="http://threejs.org" target="_blank" rel="noopener">three.js</a> - webgl HDR (RGBE) texture loader example
|
|
|
</div>
|
|
|
|
|
|
<script src="../build/three.js"></script>
|
|
|
<script src="js/loaders/RGBELoader.js"></script>
|
|
|
|
|
|
- <script src="js/Detector.js"></script>
|
|
|
- <script src="js/libs/stats.min.js"></script>
|
|
|
-
|
|
|
- <!-- HDR fragment shader -->
|
|
|
-
|
|
|
- <script id="fs-hdr" type="x-shader/x-fragment">
|
|
|
-
|
|
|
- uniform sampler2D tDiffuse;
|
|
|
- uniform float exposure;
|
|
|
- uniform float brightMax;
|
|
|
-
|
|
|
- varying vec2 vUv;
|
|
|
-
|
|
|
- vec3 decode_pnghdr( const in vec4 color ) {
|
|
|
-
|
|
|
- vec4 rgbcolor = vec4( 0.0, 0.0, 0.0, 0.0 );
|
|
|
-
|
|
|
- if ( color.w > 0.0 ) {
|
|
|
- float f = pow(2.0, 127.0*(color.w-0.5));
|
|
|
- rgbcolor.xyz = color.xyz * f;
|
|
|
- }
|
|
|
- return rgbcolor.xyz;
|
|
|
+ <script src="js/libs/dat.gui.min.js"></script>
|
|
|
|
|
|
- /*
|
|
|
- // remove gamma correction
|
|
|
- vec4 res = color * color;
|
|
|
-
|
|
|
- // decoded RI
|
|
|
- float ri = pow( 2.0, res.w * 32.0 - 16.0 );
|
|
|
-
|
|
|
- // decoded HDR pixel
|
|
|
- res.xyz = res.xyz * ri;
|
|
|
- return res.xyz;
|
|
|
- */
|
|
|
- }
|
|
|
-
|
|
|
- void main() {
|
|
|
-
|
|
|
- vec4 color = texture2D( tDiffuse, vUv );
|
|
|
- color.xyz = decode_pnghdr( color );
|
|
|
-
|
|
|
- // apply gamma correction and exposure
|
|
|
- //gl_FragColor = vec4( pow( exposure * color.xyz, vec3( 0.474 ) ), 1.0 );
|
|
|
+ <script src="js/Detector.js"></script>
|
|
|
|
|
|
- // Perform tone-mapping
|
|
|
- float Y = dot(vec4(0.30, 0.59, 0.11, 0.0), color);
|
|
|
- float YD = exposure * (exposure/brightMax + 1.0) / (exposure + 1.0);
|
|
|
- color *= YD;
|
|
|
+ <script>
|
|
|
|
|
|
- gl_FragColor = vec4( color.xyz, 1.0 );
|
|
|
+ if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
|
|
|
|
|
|
- }
|
|
|
+ var params = {
|
|
|
+ exposure: 1.0
|
|
|
+ };
|
|
|
|
|
|
- </script>
|
|
|
+ var renderer, scene, camera;
|
|
|
|
|
|
- <!-- HDR vertex shader -->
|
|
|
+ init();
|
|
|
|
|
|
- <script id="vs-hdr" type="x-shader/x-vertex">
|
|
|
+ function init() {
|
|
|
|
|
|
- varying vec2 vUv;
|
|
|
+ renderer = new THREE.WebGLRenderer();
|
|
|
+ renderer.setPixelRatio( window.devicePixelRatio );
|
|
|
+ renderer.setSize( window.innerWidth, window.innerHeight );
|
|
|
+ document.body.appendChild( renderer.domElement );
|
|
|
|
|
|
- void main() {
|
|
|
+ renderer.toneMapping = THREE.ReinhardToneMapping;
|
|
|
+ renderer.toneMappingExposure = params.exposure;
|
|
|
|
|
|
- vUv = uv;
|
|
|
- gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
|
|
|
+ renderer.gammaOutput = true;
|
|
|
|
|
|
- }
|
|
|
+ scene = new THREE.Scene();
|
|
|
|
|
|
- </script>
|
|
|
+ var aspect = window.innerWidth / window.innerHeight;
|
|
|
|
|
|
+ camera = new THREE.OrthographicCamera( - aspect, aspect, 1, - 1, 0, 1 );
|
|
|
|
|
|
- <script>
|
|
|
+ new THREE.RGBELoader().load( 'textures/miranda_uncropped.hdr', function( texture, textureData ) {
|
|
|
|
|
|
- if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
|
|
|
+ //console.log( textureData );
|
|
|
+ //console.log( texture );
|
|
|
|
|
|
- var container, stats;
|
|
|
+ texture.encoding = THREE.RGBEEncoding;
|
|
|
+ texture.minFilter = THREE.NearestFilter;
|
|
|
+ texture.magFilter = THREE.NearestFilter;
|
|
|
+ texture.flipY = true;
|
|
|
|
|
|
- var camera, scene, renderer;
|
|
|
- var materialHDR, quad, gamma, exposure;
|
|
|
+ var material = new THREE.MeshBasicMaterial( { map: texture } );
|
|
|
|
|
|
- var sign = 1, rate = 1;
|
|
|
+ var quad = new THREE.PlaneBufferGeometry( textureData.width / textureData.height, 1 );
|
|
|
|
|
|
- var clock = new THREE.Clock();
|
|
|
+ var mesh = new THREE.Mesh( quad, material );
|
|
|
|
|
|
- init();
|
|
|
+ scene.add( mesh );
|
|
|
|
|
|
- function init() {
|
|
|
+ render();
|
|
|
|
|
|
- container = document.getElementById( 'container' );
|
|
|
-
|
|
|
- camera = new THREE.PerspectiveCamera( 50, window.innerWidth / window.innerHeight, 1, 10000 );
|
|
|
- camera.position.z = 900;
|
|
|
-
|
|
|
- scene = new THREE.Scene();
|
|
|
-
|
|
|
- var loader = new THREE.RGBELoader();
|
|
|
-
|
|
|
- var texture = loader.load( "textures/miranda_uncropped.hdr", function( texture, textureData ){
|
|
|
- console.log( textureData.header ); // header string
|
|
|
- console.log( [textureData.width, textureData.height] ); // dimensions
|
|
|
- materialHDR = new THREE.ShaderMaterial( {
|
|
|
-
|
|
|
- uniforms: {
|
|
|
- tDiffuse: { value: texture },
|
|
|
- exposure: { value: textureData.exposure },
|
|
|
- brightMax: { value: textureData.gamma }
|
|
|
- },
|
|
|
- vertexShader: getText( 'vs-hdr' ),
|
|
|
- fragmentShader: getText( 'fs-hdr' )
|
|
|
-
|
|
|
- } );
|
|
|
- quad = new THREE.Mesh( new THREE.PlaneBufferGeometry( textureData.width, textureData.height ), materialHDR );
|
|
|
- quad.position.z = -100;
|
|
|
- scene.add( quad );
|
|
|
- animate();
|
|
|
} );
|
|
|
- texture.minFilter = THREE.LinearFilter;
|
|
|
- texture.magFilter = THREE.NearestFilter;
|
|
|
|
|
|
+ //
|
|
|
|
|
|
- renderer = new THREE.WebGLRenderer();
|
|
|
- renderer.setPixelRatio( window.devicePixelRatio );
|
|
|
- renderer.setSize( window.innerWidth, window.innerHeight );
|
|
|
- container.appendChild( renderer.domElement );
|
|
|
+ var gui = new dat.GUI();
|
|
|
|
|
|
- stats = new Stats();
|
|
|
- container.appendChild( stats.dom );
|
|
|
+ gui.add( params, 'exposure', 0, 2 ).onChange( render );
|
|
|
+ gui.open();
|
|
|
|
|
|
//
|
|
|
|
|
@@ -174,55 +107,28 @@
|
|
|
|
|
|
}
|
|
|
|
|
|
+ function onWindowResize() {
|
|
|
|
|
|
+ var aspect = window.innerWidth / window.innerHeight;
|
|
|
|
|
|
- function onWindowResize() {
|
|
|
+ var frustumHeight = camera.top - camera.bottom;
|
|
|
+
|
|
|
+ camera.left = - frustumHeight * aspect / 2;
|
|
|
+ camera.right = frustumHeight * aspect / 2;
|
|
|
|
|
|
- camera.aspect = window.innerWidth / window.innerHeight;
|
|
|
camera.updateProjectionMatrix();
|
|
|
|
|
|
renderer.setSize( window.innerWidth, window.innerHeight );
|
|
|
|
|
|
- }
|
|
|
-
|
|
|
- function getText( id ) {
|
|
|
-
|
|
|
- return document.getElementById( id ).textContent;
|
|
|
+ render();
|
|
|
|
|
|
}
|
|
|
|
|
|
//
|
|
|
|
|
|
- function animate() {
|
|
|
-
|
|
|
- requestAnimationFrame( animate );
|
|
|
-
|
|
|
- render();
|
|
|
- stats.update();
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
function render() {
|
|
|
|
|
|
- var delta = clock.getDelta() * 5;
|
|
|
-
|
|
|
- if ( materialHDR.uniforms.exposure.value > 0 || materialHDR.uniforms.exposure.value < 1 ) {
|
|
|
-
|
|
|
- rate = 0.25;
|
|
|
-
|
|
|
- } else {
|
|
|
-
|
|
|
- rate = 1;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- if ( materialHDR.uniforms.exposure.value > 5 || materialHDR.uniforms.exposure.value <= 0 ) {
|
|
|
-
|
|
|
- sign *= -1;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- materialHDR.uniforms.exposure.value += sign * rate * delta;
|
|
|
+ renderer.toneMappingExposure = params.exposure;
|
|
|
|
|
|
renderer.render( scene, camera );
|
|
|
|