|
| 1 | +<!DOCTYPE html> |
| 2 | +<html lang="en"> |
| 3 | + <head> |
| 4 | + <title>threejs webgl - materials - hdr environment mapping</title> |
| 5 | + <meta charset="utf-8"> |
| 6 | + <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0"> |
| 7 | + <style> |
| 8 | + body { |
| 9 | + color: #fff; |
| 10 | + font-family:Monospace; |
| 11 | + font-size:13px; |
| 12 | + text-align:center; |
| 13 | + |
| 14 | + background-color: #000; |
| 15 | + |
| 16 | + margin: 0px; |
| 17 | + overflow: hidden; |
| 18 | + } |
| 19 | + a { color: #00f } |
| 20 | + |
| 21 | + #info { |
| 22 | + position: absolute; |
| 23 | + top: 0px; width: 100%; |
| 24 | + padding: 5px; |
| 25 | + } |
| 26 | + </style> |
| 27 | + </head> |
| 28 | + <body> |
| 29 | + |
| 30 | + <div id="container"></div> |
| 31 | + <div id="info"><a href="http://threejs.org" target="_blank" rel="noopener">threejs</a> - High dynamic range (RGBE) Image-based Lighting (IBL)<br />using run-time generated pre-filtered roughness mipmaps (PMREM)<br/> |
| 32 | + Created by Prashant Sharma and <a href="http://clara.io/" target="_blank" rel="noopener">Ben Houston</a>.</div> |
| 33 | + |
| 34 | + <script src="../build/three.js"></script> |
| 35 | + <script src="js/controls/OrbitControls.js"></script> |
| 36 | + |
| 37 | + <script src="js/loaders/RGBELoader.js"></script> |
| 38 | + <script src="js/loaders/HDRCubeTextureLoader.js"></script> |
| 39 | + |
| 40 | + <script src="js/WebGL.js"></script> |
| 41 | + <script src="js/libs/stats.min.js"></script> |
| 42 | + |
| 43 | + <script src="js/pmrem/PMREMGenerator.js"></script> |
| 44 | + <script src="js/pmrem/PMREMCubeUVPacker.js"></script> |
| 45 | + <script src="js/libs/dat.gui.min.js"></script> |
| 46 | + |
| 47 | + <script type="module"> |
| 48 | + /* |
| 49 | + * COPIED FROM webgl_materials_envmaps_hdr.html |
| 50 | + * |
| 51 | + * |
| 52 | + * |
| 53 | + */ |
| 54 | + import './js/nodes/THREE.Nodes.js'; |
| 55 | + |
| 56 | + if ( WEBGL.isWebGLAvailable() === false ) { |
| 57 | + |
| 58 | + document.body.appendChild( WEBGL.getWebGLErrorMessage() ); |
| 59 | + |
| 60 | + } |
| 61 | + |
| 62 | + var params = { |
| 63 | + envMap: 'HDR', |
| 64 | + roughness: 0.0, |
| 65 | + metalness: 0.0, |
| 66 | + exposure: 1.0, |
| 67 | + debug: false, |
| 68 | + }; |
| 69 | + |
| 70 | + var container, stats; |
| 71 | + var camera, scene, renderer, controls; |
| 72 | + var torusMesh, planeMesh; |
| 73 | + var nodeMaterial; |
| 74 | + var ldrCubeRenderTarget, hdrCubeRenderTarget, rgbmCubeRenderTarget; |
| 75 | + var ldrCubeMap, hdrCubeMap, rgbmCubeMap; |
| 76 | + |
| 77 | + init(); |
| 78 | + animate(); |
| 79 | + |
| 80 | + function init() { |
| 81 | + |
| 82 | + container = document.createElement( 'div' ); |
| 83 | + document.body.appendChild( container ); |
| 84 | + |
| 85 | + camera = new THREE.PerspectiveCamera( 40, window.innerWidth / window.innerHeight, 1, 1000 ); |
| 86 | + camera.position.set( 0, 0, 120 ); |
| 87 | + |
| 88 | + scene = new THREE.Scene(); |
| 89 | + scene.background = new THREE.Color( 0x000000 ); |
| 90 | + |
| 91 | + renderer = new THREE.WebGLRenderer(); |
| 92 | + renderer.toneMapping = THREE.LinearToneMapping; |
| 93 | + |
| 94 | + // |
| 95 | + |
| 96 | + var geometry = new THREE.TorusKnotBufferGeometry( 18, 8, 150, 20 ); |
| 97 | + //geometry = new THREE.SphereBufferGeometry(20, 100, 100); |
| 98 | + var material = new THREE.MeshStandardMaterial( { |
| 99 | + color: 0xffffff, |
| 100 | + metalness: params.metalness, |
| 101 | + roughness: params.roughness |
| 102 | + } ); |
| 103 | + |
| 104 | + torusMesh = new THREE.Mesh( geometry, material ); |
| 105 | + torusMesh.position.y = 35; |
| 106 | + scene.add( torusMesh ); |
| 107 | + |
| 108 | + nodeMaterial = new THREE.StandardNodeMaterial(); |
| 109 | + nodeMaterial.color = new THREE.ColorNode(new THREE.Color(1, 1, 1)) |
| 110 | + nodeMaterial.roughness = new THREE.FloatNode(params.metalness); |
| 111 | + nodeMaterial.metalness = new THREE.FloatNode(params.roguhness); |
| 112 | + |
| 113 | + var torusMeshNode = new THREE.Mesh( geometry, nodeMaterial ); |
| 114 | + torusMeshNode.position.y = -35; |
| 115 | + scene.add( torusMeshNode ); |
| 116 | + |
| 117 | + |
| 118 | + var geometry = new THREE.PlaneBufferGeometry( 200, 200 ); |
| 119 | + var material = new THREE.MeshBasicMaterial(); |
| 120 | + |
| 121 | + planeMesh = new THREE.Mesh( geometry, material ); |
| 122 | + planeMesh.position.y = - 50; |
| 123 | + planeMesh.rotation.x = - Math.PI * 0.5; |
| 124 | + scene.add( planeMesh ); |
| 125 | + |
| 126 | + var hdrUrls = [ 'px.hdr', 'nx.hdr', 'py.hdr', 'ny.hdr', 'pz.hdr', 'nz.hdr' ]; |
| 127 | + hdrCubeMap = new THREE.HDRCubeTextureLoader() |
| 128 | + .setPath( './textures/cube/pisaHDR/' ) |
| 129 | + .load( THREE.UnsignedByteType, hdrUrls, function () { |
| 130 | + |
| 131 | + var pmremGenerator = new THREE.PMREMGenerator( hdrCubeMap ); |
| 132 | + pmremGenerator.update( renderer ); |
| 133 | + |
| 134 | + var pmremCubeUVPacker = new THREE.PMREMCubeUVPacker( pmremGenerator.cubeLods ); |
| 135 | + pmremCubeUVPacker.update( renderer ); |
| 136 | + |
| 137 | + hdrCubeRenderTarget = pmremCubeUVPacker.CubeUVRenderTarget; |
| 138 | + |
| 139 | + hdrCubeMap.magFilter = THREE.LinearFilter; |
| 140 | + hdrCubeMap.needsUpdate = true; |
| 141 | + |
| 142 | + pmremGenerator.dispose(); |
| 143 | + pmremCubeUVPacker.dispose(); |
| 144 | + |
| 145 | + } ); |
| 146 | + |
| 147 | + var ldrUrls = [ 'px.png', 'nx.png', 'py.png', 'ny.png', 'pz.png', 'nz.png' ]; |
| 148 | + ldrCubeMap = new THREE.CubeTextureLoader() |
| 149 | + .setPath( './textures/cube/pisa/' ) |
| 150 | + .load( ldrUrls, function () { |
| 151 | + |
| 152 | + ldrCubeMap.encoding = THREE.GammaEncoding; |
| 153 | + |
| 154 | + var pmremGenerator = new THREE.PMREMGenerator( ldrCubeMap ); |
| 155 | + pmremGenerator.update( renderer ); |
| 156 | + |
| 157 | + var pmremCubeUVPacker = new THREE.PMREMCubeUVPacker( pmremGenerator.cubeLods ); |
| 158 | + pmremCubeUVPacker.update( renderer ); |
| 159 | + |
| 160 | + ldrCubeRenderTarget = pmremCubeUVPacker.CubeUVRenderTarget; |
| 161 | + |
| 162 | + pmremGenerator.dispose(); |
| 163 | + pmremCubeUVPacker.dispose(); |
| 164 | + |
| 165 | + } ); |
| 166 | + |
| 167 | + |
| 168 | + var rgbmUrls = [ 'px.png', 'nx.png', 'py.png', 'ny.png', 'pz.png', 'nz.png' ]; |
| 169 | + rgbmCubeMap = new THREE.CubeTextureLoader() |
| 170 | + .setPath( './textures/cube/pisaRGBM16/' ) |
| 171 | + .load( rgbmUrls, function () { |
| 172 | + |
| 173 | + rgbmCubeMap.encoding = THREE.RGBM16Encoding; |
| 174 | + rgbmCubeMap.format = THREE.RGBAFormat; |
| 175 | + |
| 176 | + var pmremGenerator = new THREE.PMREMGenerator( rgbmCubeMap ); |
| 177 | + pmremGenerator.update( renderer ); |
| 178 | + |
| 179 | + var pmremCubeUVPacker = new THREE.PMREMCubeUVPacker( pmremGenerator.cubeLods ); |
| 180 | + pmremCubeUVPacker.update( renderer ); |
| 181 | + |
| 182 | + rgbmCubeRenderTarget = pmremCubeUVPacker.CubeUVRenderTarget; |
| 183 | + |
| 184 | + rgbmCubeMap.magFilter = THREE.LinearFilter; |
| 185 | + rgbmCubeMap.needsUpdate = true; |
| 186 | + |
| 187 | + pmremGenerator.dispose(); |
| 188 | + pmremCubeUVPacker.dispose(); |
| 189 | + |
| 190 | + } ); |
| 191 | + |
| 192 | + renderer.setPixelRatio( window.devicePixelRatio ); |
| 193 | + renderer.setSize( window.innerWidth, window.innerHeight ); |
| 194 | + container.appendChild( renderer.domElement ); |
| 195 | + |
| 196 | + //renderer.toneMapping = THREE.ReinhardToneMapping; |
| 197 | + renderer.gammaInput = true; // ??? |
| 198 | + renderer.gammaOutput = true; |
| 199 | + |
| 200 | + stats = new Stats(); |
| 201 | + container.appendChild( stats.dom ); |
| 202 | + |
| 203 | + controls = new THREE.OrbitControls( camera, renderer.domElement ); |
| 204 | + controls.minDistance = 50; |
| 205 | + controls.maxDistance = 300; |
| 206 | + |
| 207 | + window.addEventListener( 'resize', onWindowResize, false ); |
| 208 | + |
| 209 | + var gui = new dat.GUI(); |
| 210 | + |
| 211 | + gui.add( params, 'envMap', [ 'LDR', 'HDR', 'RGBM16' ] ); |
| 212 | + gui.add( params, 'roughness', 0, 1, 0.01 ); |
| 213 | + gui.add( params, 'metalness', 0, 1, 0.01 ); |
| 214 | + gui.add( params, 'exposure', 0, 2, 0.01 ); |
| 215 | + gui.add( params, 'debug', false ); |
| 216 | + gui.open(); |
| 217 | + |
| 218 | + } |
| 219 | + |
| 220 | + function onWindowResize() { |
| 221 | + |
| 222 | + var width = window.innerWidth; |
| 223 | + var height = window.innerHeight; |
| 224 | + |
| 225 | + camera.aspect = width / height; |
| 226 | + camera.updateProjectionMatrix(); |
| 227 | + |
| 228 | + renderer.setSize( width, height ); |
| 229 | + |
| 230 | + } |
| 231 | + |
| 232 | + function animate() { |
| 233 | + |
| 234 | + requestAnimationFrame( animate ); |
| 235 | + |
| 236 | + stats.begin(); |
| 237 | + render(); |
| 238 | + stats.end(); |
| 239 | + |
| 240 | + } |
| 241 | + |
| 242 | + function render() { |
| 243 | + |
| 244 | + torusMesh.material.roughness = params.roughness; |
| 245 | + torusMesh.material.metalness = params.metalness; |
| 246 | + |
| 247 | + nodeMaterial.roughness.value = params.roughness; |
| 248 | + nodeMaterial.metalness.value = params.metalness; |
| 249 | + |
| 250 | + var renderTarget, cubeMap; |
| 251 | + |
| 252 | + switch ( params.envMap ) { |
| 253 | + |
| 254 | + case 'LDR': |
| 255 | + renderTarget = ldrCubeRenderTarget; |
| 256 | + cubeMap = ldrCubeMap; |
| 257 | + break; |
| 258 | + case 'HDR': |
| 259 | + renderTarget = hdrCubeRenderTarget; |
| 260 | + cubeMap = hdrCubeMap; |
| 261 | + break; |
| 262 | + case 'RGBM16': |
| 263 | + renderTarget = rgbmCubeRenderTarget; |
| 264 | + cubeMap = rgbmCubeMap; |
| 265 | + break; |
| 266 | + } |
| 267 | + |
| 268 | + var newEnvMap = renderTarget ? renderTarget.texture : null; |
| 269 | + |
| 270 | + if ( newEnvMap && newEnvMap !== torusMesh.material.envMap ) { |
| 271 | + |
| 272 | + torusMesh.material.envMap = newEnvMap; |
| 273 | + torusMesh.material.needsUpdate = true; |
| 274 | + |
| 275 | + planeMesh.material.map = newEnvMap; |
| 276 | + planeMesh.material.needsUpdate = true; |
| 277 | + |
| 278 | + var textureNode = new THREE.TextureNode(newEnvMap); |
| 279 | + textureNode.encodingOverride = newEnvMap.encoding; |
| 280 | + |
| 281 | + nodeMaterial.environment = new THREE.TextureCubeNode( |
| 282 | + textureNode |
| 283 | + ); |
| 284 | + nodeMaterial.environment.uv.blinnExponentToRoughness = nodeMaterial.roughness; |
| 285 | + |
| 286 | + nodeMaterial.ambient = new THREE.TextureCubeNode( |
| 287 | + textureNode |
| 288 | + ); |
| 289 | + nodeMaterial.ambient.uv.blinnExponentToRoughness = new THREE.FloatNode(1); |
| 290 | + nodeMaterial.ambient.uv.uv = new THREE.NormalNode(THREE.NormalNode.WORLD); |
| 291 | + nodeMaterial.ambient = new THREE.OperatorNode( |
| 292 | + nodeMaterial.ambient, |
| 293 | + new THREE.FloatNode(Math.PI), |
| 294 | + THREE.OperatorNode.MUL); |
| 295 | + |
| 296 | + nodeMaterial.needsUpdate = true; |
| 297 | + |
| 298 | + } |
| 299 | + |
| 300 | + //torusMesh.rotation.y += 0.005; |
| 301 | + planeMesh.visible = params.debug; |
| 302 | + |
| 303 | + scene.background = cubeMap; |
| 304 | + renderer.toneMappingExposure = params.exposure; |
| 305 | + |
| 306 | + renderer.render( scene, camera ); |
| 307 | + |
| 308 | + } |
| 309 | + |
| 310 | + </script> |
| 311 | + |
| 312 | + </body> |
| 313 | +</html> |
0 commit comments