threejs-fog.js 4.2 KB

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