|
31 | 31 | </head> |
32 | 32 | <body> |
33 | 33 |
|
34 | | - <div id="container"></div> |
35 | 34 | <div id="info"> |
36 | | - <a href="http://threejs.org" target="_blank" rel="noopener">three.js</a> - webgl HDR texture loader example - |
37 | | - based on <a href="http://spidergl.org/example.php?id=13" target="_blank" rel="noopener">SpiderGL</a> |
| 35 | + <a href="http://threejs.org" target="_blank" rel="noopener">three.js</a> - webgl HDR (RGBE) texture loader example |
38 | 36 | </div> |
39 | 37 |
|
40 | 38 | <script src="../build/three.js"></script> |
41 | 39 | <script src="js/loaders/RGBELoader.js"></script> |
42 | 40 |
|
43 | | - <script src="js/Detector.js"></script> |
44 | | - <script src="js/libs/stats.min.js"></script> |
45 | | - |
46 | | - <!-- HDR fragment shader --> |
47 | | - |
48 | | - <script id="fs-hdr" type="x-shader/x-fragment"> |
49 | | - |
50 | | - uniform sampler2D tDiffuse; |
51 | | - uniform float exposure; |
52 | | - uniform float brightMax; |
53 | | - |
54 | | - varying vec2 vUv; |
55 | | - |
56 | | - vec3 decode_pnghdr( const in vec4 color ) { |
57 | | - |
58 | | - vec4 rgbcolor = vec4( 0.0, 0.0, 0.0, 0.0 ); |
59 | | - |
60 | | - if ( color.w > 0.0 ) { |
61 | | - float f = pow(2.0, 127.0*(color.w-0.5)); |
62 | | - rgbcolor.xyz = color.xyz * f; |
63 | | - } |
64 | | - return rgbcolor.xyz; |
| 41 | + <script src="js/libs/dat.gui.min.js"></script> |
65 | 42 |
|
66 | | - /* |
67 | | - // remove gamma correction |
68 | | - vec4 res = color * color; |
69 | | -
|
70 | | - // decoded RI |
71 | | - float ri = pow( 2.0, res.w * 32.0 - 16.0 ); |
72 | | -
|
73 | | - // decoded HDR pixel |
74 | | - res.xyz = res.xyz * ri; |
75 | | - return res.xyz; |
76 | | - */ |
77 | | - } |
78 | | - |
79 | | - void main() { |
80 | | - |
81 | | - vec4 color = texture2D( tDiffuse, vUv ); |
82 | | - color.xyz = decode_pnghdr( color ); |
83 | | - |
84 | | - // apply gamma correction and exposure |
85 | | - //gl_FragColor = vec4( pow( exposure * color.xyz, vec3( 0.474 ) ), 1.0 ); |
| 43 | + <script src="js/Detector.js"></script> |
86 | 44 |
|
87 | | - // Perform tone-mapping |
88 | | - float Y = dot(vec4(0.30, 0.59, 0.11, 0.0), color); |
89 | | - float YD = exposure * (exposure/brightMax + 1.0) / (exposure + 1.0); |
90 | | - color *= YD; |
| 45 | + <script> |
91 | 46 |
|
92 | | - gl_FragColor = vec4( color.xyz, 1.0 ); |
| 47 | + if ( ! Detector.webgl ) Detector.addGetWebGLMessage(); |
93 | 48 |
|
94 | | - } |
| 49 | + var params = { |
| 50 | + exposure: 1.0 |
| 51 | + }; |
95 | 52 |
|
96 | | - </script> |
| 53 | + var renderer, scene, camera; |
97 | 54 |
|
98 | | - <!-- HDR vertex shader --> |
| 55 | + init(); |
99 | 56 |
|
100 | | - <script id="vs-hdr" type="x-shader/x-vertex"> |
| 57 | + function init() { |
101 | 58 |
|
102 | | - varying vec2 vUv; |
| 59 | + renderer = new THREE.WebGLRenderer(); |
| 60 | + renderer.setPixelRatio( window.devicePixelRatio ); |
| 61 | + renderer.setSize( window.innerWidth, window.innerHeight ); |
| 62 | + document.body.appendChild( renderer.domElement ); |
103 | 63 |
|
104 | | - void main() { |
| 64 | + renderer.toneMapping = THREE.ReinhardToneMapping; |
| 65 | + renderer.toneMappingExposure = params.exposure; |
105 | 66 |
|
106 | | - vUv = uv; |
107 | | - gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); |
| 67 | + renderer.gammaOutput = true; |
108 | 68 |
|
109 | | - } |
| 69 | + scene = new THREE.Scene(); |
110 | 70 |
|
111 | | - </script> |
| 71 | + var aspect = window.innerWidth / window.innerHeight; |
112 | 72 |
|
| 73 | + camera = new THREE.OrthographicCamera( - aspect, aspect, 1, - 1, 0, 1 ); |
113 | 74 |
|
114 | | - <script> |
| 75 | + new THREE.RGBELoader().load( 'textures/miranda_uncropped.hdr', function( texture, textureData ) { |
115 | 76 |
|
116 | | - if ( ! Detector.webgl ) Detector.addGetWebGLMessage(); |
| 77 | + //console.log( textureData ); |
| 78 | + //console.log( texture ); |
117 | 79 |
|
118 | | - var container, stats; |
| 80 | + texture.encoding = THREE.RGBEEncoding; |
| 81 | + texture.minFilter = THREE.NearestFilter; |
| 82 | + texture.magFilter = THREE.NearestFilter; |
| 83 | + texture.flipY = true; |
119 | 84 |
|
120 | | - var camera, scene, renderer; |
121 | | - var materialHDR, quad, gamma, exposure; |
| 85 | + var material = new THREE.MeshBasicMaterial( { map: texture } ); |
122 | 86 |
|
123 | | - var sign = 1, rate = 1; |
| 87 | + var quad = new THREE.PlaneBufferGeometry( textureData.width / textureData.height, 1 ); |
124 | 88 |
|
125 | | - var clock = new THREE.Clock(); |
| 89 | + var mesh = new THREE.Mesh( quad, material ); |
126 | 90 |
|
127 | | - init(); |
| 91 | + scene.add( mesh ); |
128 | 92 |
|
129 | | - function init() { |
| 93 | + render(); |
130 | 94 |
|
131 | | - container = document.getElementById( 'container' ); |
132 | | - |
133 | | - camera = new THREE.PerspectiveCamera( 50, window.innerWidth / window.innerHeight, 1, 10000 ); |
134 | | - camera.position.z = 900; |
135 | | - |
136 | | - scene = new THREE.Scene(); |
137 | | - |
138 | | - var loader = new THREE.RGBELoader(); |
139 | | - |
140 | | - var texture = loader.load( "textures/miranda_uncropped.hdr", function( texture, textureData ){ |
141 | | - console.log( textureData.header ); // header string |
142 | | - console.log( [textureData.width, textureData.height] ); // dimensions |
143 | | - materialHDR = new THREE.ShaderMaterial( { |
144 | | - |
145 | | - uniforms: { |
146 | | - tDiffuse: { value: texture }, |
147 | | - exposure: { value: textureData.exposure }, |
148 | | - brightMax: { value: textureData.gamma } |
149 | | - }, |
150 | | - vertexShader: getText( 'vs-hdr' ), |
151 | | - fragmentShader: getText( 'fs-hdr' ) |
152 | | - |
153 | | - } ); |
154 | | - quad = new THREE.Mesh( new THREE.PlaneBufferGeometry( textureData.width, textureData.height ), materialHDR ); |
155 | | - quad.position.z = -100; |
156 | | - scene.add( quad ); |
157 | | - animate(); |
158 | 95 | } ); |
159 | | - texture.minFilter = THREE.LinearFilter; |
160 | | - texture.magFilter = THREE.NearestFilter; |
161 | 96 |
|
| 97 | + // |
162 | 98 |
|
163 | | - renderer = new THREE.WebGLRenderer(); |
164 | | - renderer.setPixelRatio( window.devicePixelRatio ); |
165 | | - renderer.setSize( window.innerWidth, window.innerHeight ); |
166 | | - container.appendChild( renderer.domElement ); |
| 99 | + var gui = new dat.GUI(); |
167 | 100 |
|
168 | | - stats = new Stats(); |
169 | | - container.appendChild( stats.dom ); |
| 101 | + gui.add( params, 'exposure', 0, 2 ).onChange( render ); |
| 102 | + gui.open(); |
170 | 103 |
|
171 | 104 | // |
172 | 105 |
|
173 | 106 | window.addEventListener( 'resize', onWindowResize, false ); |
174 | 107 |
|
175 | 108 | } |
176 | 109 |
|
| 110 | + function onWindowResize() { |
177 | 111 |
|
| 112 | + var aspect = window.innerWidth / window.innerHeight; |
178 | 113 |
|
179 | | - function onWindowResize() { |
| 114 | + var frustumHeight = camera.top - camera.bottom; |
| 115 | + |
| 116 | + camera.left = - frustumHeight * aspect / 2; |
| 117 | + camera.right = frustumHeight * aspect / 2; |
180 | 118 |
|
181 | | - camera.aspect = window.innerWidth / window.innerHeight; |
182 | 119 | camera.updateProjectionMatrix(); |
183 | 120 |
|
184 | 121 | renderer.setSize( window.innerWidth, window.innerHeight ); |
185 | 122 |
|
186 | | - } |
187 | | - |
188 | | - function getText( id ) { |
189 | | - |
190 | | - return document.getElementById( id ).textContent; |
| 123 | + render(); |
191 | 124 |
|
192 | 125 | } |
193 | 126 |
|
194 | 127 | // |
195 | 128 |
|
196 | | - function animate() { |
197 | | - |
198 | | - requestAnimationFrame( animate ); |
199 | | - |
200 | | - render(); |
201 | | - stats.update(); |
202 | | - |
203 | | - } |
204 | | - |
205 | 129 | function render() { |
206 | 130 |
|
207 | | - var delta = clock.getDelta() * 5; |
208 | | - |
209 | | - if ( materialHDR.uniforms.exposure.value > 0 || materialHDR.uniforms.exposure.value < 1 ) { |
210 | | - |
211 | | - rate = 0.25; |
212 | | - |
213 | | - } else { |
214 | | - |
215 | | - rate = 1; |
216 | | - |
217 | | - } |
218 | | - |
219 | | - if ( materialHDR.uniforms.exposure.value > 5 || materialHDR.uniforms.exposure.value <= 0 ) { |
220 | | - |
221 | | - sign *= -1; |
222 | | - |
223 | | - } |
224 | | - |
225 | | - materialHDR.uniforms.exposure.value += sign * rate * delta; |
| 131 | + renderer.toneMappingExposure = params.exposure; |
226 | 132 |
|
227 | 133 | renderer.render( scene, camera ); |
228 | 134 |
|
|
0 commit comments