webgl_furnace_test.html 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <title>three.js white furnace test</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. <link type="text/css" rel="stylesheet" href="main.css">
  8. <style>
  9. body {
  10. color: #444;
  11. }
  12. </style>
  13. </head>
  14. <body>
  15. <div id="container">
  16. <div id="info">
  17. <a href="http://threejs.org" target="_blank" rel="noopener">three.js</a> -
  18. <a href="https://google.github.io/filament/Filament.md.html#toc4.7.2" target="_blank" rel="noopener">White Furnace</a> energy conservation test by <a href="https://jsantell.com/" target="_blank" rel="noopener">Jordan Santell</a><br/><br/>
  19. There are 11 fully metal spheres with full white specular color and increasing roughness values rendered here. A metal object, no matter how rough, fully reflects all energy. If uniformly lit, the spheres should be indistinguishable from the environment. If spheres are visible, then some energy has been lost or gained after reflection.<br />
  20. </div>
  21. </div>
  22. <script type="module">
  23. import {
  24. Color,
  25. CubeCamera,
  26. DoubleSide,
  27. Mesh,
  28. MeshBasicMaterial,
  29. MeshPhysicalMaterial,
  30. OrthographicCamera,
  31. Scene,
  32. SphereBufferGeometry,
  33. WebGLRenderer
  34. } from "../build/three.module.js";
  35. import { PMREMGenerator } from './jsm/pmrem/PMREMGenerator.js';
  36. import { PMREMCubeUVPacker } from './jsm/pmrem/PMREMCubeUVPacker.js';
  37. var scene, camera, renderer, envMap, radianceMap;
  38. var right = 6;
  39. function init() {
  40. var width = window.innerWidth;
  41. var height = window.innerHeight;
  42. var aspect = width / height;
  43. // renderer
  44. renderer = new WebGLRenderer( { antialias: true } );
  45. renderer.setSize( width, height );
  46. renderer.setPixelRatio( window.devicePixelRatio );
  47. document.body.appendChild( renderer.domElement );
  48. window.addEventListener( 'resize', onResize, false );
  49. // scene
  50. scene = new Scene();
  51. // camera
  52. camera = new OrthographicCamera( - right, right, right / aspect, - right / aspect, 1, 30 );
  53. camera.position.set( 0, 0, 9 );
  54. }
  55. function createObjects() {
  56. var geo = new SphereBufferGeometry( 0.4, 32, 32 );
  57. var count = 10;
  58. for ( var x = 0; x <= count; x ++ ) {
  59. var mesh = new Mesh( geo, new MeshPhysicalMaterial( {
  60. roughness: x / count,
  61. metalness: 1,
  62. color: 0xffffff,
  63. envMap: radianceMap,
  64. envMapIntensity: 1,
  65. reflectivity: 1,
  66. } ) );
  67. mesh.position.x = x - ( Math.floor( count / 2 ) );
  68. scene.add( mesh );
  69. }
  70. }
  71. function createEnvironment() {
  72. var color = new Color( 0xcccccc );
  73. var sky = new Mesh( new SphereBufferGeometry( 1, 32, 32 ), new MeshBasicMaterial( {
  74. color: color,
  75. side: DoubleSide,
  76. } ) );
  77. sky.scale.setScalar( 100 );
  78. var envScene = new Scene();
  79. envScene.add( sky );
  80. envScene.background = color;
  81. var cubeCamera = new CubeCamera( 1, 100, 256, 256 );
  82. cubeCamera.update( renderer, envScene );
  83. envMap = cubeCamera.renderTarget.texture;
  84. scene.background = color;
  85. }
  86. function getRadiance() {
  87. return new Promise( function ( resolve ) {
  88. var pmremGenerator = new PMREMGenerator( envMap );
  89. pmremGenerator.update( renderer );
  90. var pmremCubeUVPacker = new PMREMCubeUVPacker( pmremGenerator.cubeLods );
  91. pmremCubeUVPacker.update( renderer );
  92. var cubeRenderTarget = pmremCubeUVPacker.CubeUVRenderTarget;
  93. pmremGenerator.dispose();
  94. pmremCubeUVPacker.dispose();
  95. radianceMap = cubeRenderTarget.texture;
  96. resolve();
  97. } );
  98. }
  99. function onResize() {
  100. var aspect = window.innerWidth / window.innerHeight;
  101. camera.top = right / aspect;
  102. camera.bottom = - camera.top;
  103. camera.updateProjectionMatrix();
  104. renderer.setSize( window.innerWidth, window.innerHeight );
  105. render();
  106. }
  107. function render() {
  108. renderer.render( scene, camera );
  109. }
  110. Promise.resolve()
  111. .then( init )
  112. .then( createEnvironment )
  113. .then( getRadiance )
  114. .then( createObjects )
  115. .then( render );
  116. </script>
  117. </body>
  118. </html>