threejs-fog.js 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. 'use strict';
  2. /* global THREE, threejsLessonUtils */
  3. {
  4. function fogExample(scene, fog) {
  5. scene.fog = fog;
  6. const width = 4;
  7. const height = 3;
  8. const depth = 10;
  9. const geometry = new THREE.BoxBufferGeometry(width, height, depth);
  10. const material = new THREE.MeshPhongMaterial({color: 'hsl(130,50%,50%)'});
  11. return new THREE.Mesh(geometry, material);
  12. }
  13. function houseScene(props, fogInHouse) {
  14. const {scene, camera} = props;
  15. camera.far = 200;
  16. const loader = new THREE.GLTFLoader();
  17. const settings = {
  18. shininess: 0,
  19. roughness: 1,
  20. metalness: 0,
  21. };
  22. loader.load('../resources/models/simple_house_scene/scene.gltf', (gltf) => {
  23. const hackGeometry = new THREE.CircleBufferGeometry(0.5, 32);
  24. const box = new THREE.Box3();
  25. const size = new THREE.Vector3();
  26. const center = new THREE.Vector3();
  27. const materials = new Set();
  28. gltf.scene.traverse((node) => {
  29. const material = node.material;
  30. if (material) {
  31. // hack in the bottom of the trees since I don't have
  32. // the model file
  33. if (node.name === 'mesh_11' || node.name === 'mesh_6') {
  34. node.updateWorldMatrix(true, false);
  35. box.setFromObject(node);
  36. box.getSize(size);
  37. box.getCenter(center);
  38. const hackMesh = new THREE.Mesh(hackGeometry, node.material);
  39. scene.add(hackMesh);
  40. hackMesh.position.copy(center);
  41. hackMesh.rotation.x = Math.PI * 0.5;
  42. hackMesh.position.y -= size.y / 2;
  43. hackMesh.scale.set(size.x, size.z, 1);
  44. }
  45. (Array.isArray(material) ? material : [material]).forEach((material) => {
  46. if (!materials.has(material)) {
  47. materials.add(material);
  48. for (const [key, value] of Object.entries(settings)) {
  49. if (material[key] !== undefined) {
  50. material[key] = value;
  51. }
  52. }
  53. if (!fogInHouse && material.name.startsWith('fogless')) {
  54. material.fog = false;
  55. }
  56. }
  57. });
  58. }
  59. });
  60. scene.add(gltf.scene);
  61. });
  62. camera.fov = 45;
  63. camera.position.set(0.4, 1, 1.7);
  64. camera.lookAt(1, 1, 0.7);
  65. const color = 0xFFFFFF;
  66. const near = 1.5;
  67. const far = 5;
  68. scene.fog = new THREE.Fog(color, near, far);
  69. const light = new THREE.PointLight(0xFFFFFF, 1);
  70. light.position.copy(camera.position);
  71. light.position.y += 0.2;
  72. scene.add(light);
  73. const target = [1, 1, 0.7];
  74. return {
  75. trackball: false,
  76. obj3D: new THREE.Object3D(),
  77. update: (time) => {
  78. camera.lookAt(target[0] + Math.sin(time * .25) * .5, target[1], target[2]);
  79. },
  80. };
  81. }
  82. threejsLessonUtils.addDiagrams({
  83. fog: {
  84. create(props) {
  85. const {scene} = props;
  86. const color = 0xFFFFFF;
  87. const near = 12;
  88. const far = 18;
  89. return fogExample(scene, new THREE.Fog(color, near, far));
  90. },
  91. },
  92. fogExp2: {
  93. create(props) {
  94. const {scene} = props;
  95. const color = 0xFFFFFF;
  96. const density = 0.1;
  97. return fogExample(scene, new THREE.FogExp2(color, density));
  98. },
  99. },
  100. fogBlueBackgroundRed: {
  101. create(props) {
  102. const {scene} = props;
  103. scene.background = new THREE.Color('#F00');
  104. const color = '#00F';
  105. const near = 12;
  106. const far = 18;
  107. return fogExample(scene, new THREE.Fog(color, near, far));
  108. },
  109. },
  110. fogBlueBackgroundBlue: {
  111. create(props) {
  112. const {scene} = props;
  113. scene.background = new THREE.Color('#00F');
  114. const color = '#00F';
  115. const near = 12;
  116. const far = 18;
  117. return fogExample(scene, new THREE.Fog(color, near, far));
  118. },
  119. },
  120. fogHouseAll: {
  121. create(props) {
  122. return houseScene(props, true);
  123. },
  124. },
  125. fogHouseInsideNoFog: {
  126. create(props) {
  127. return houseScene(props, false);
  128. },
  129. },
  130. });
  131. }