You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

161 lines
4.7 KiB

import * as THREE from 'three';
import {GLTFLoader} from '../../examples/jsm/loaders/GLTFLoader.js';
import {threejsLessonUtils} from './threejs-lesson-utils.js';
{
const darkColors = {
background: '#333',
};
const lightColors = {
background: '#FFF',
};
const darkMatcher = window.matchMedia('(prefers-color-scheme: dark)');
function fogExample(scene, fog, update) {
scene.fog = fog;
const width = 4;
const height = 3;
const depth = 10;
const geometry = new THREE.BoxGeometry(width, height, depth);
const material = new THREE.MeshPhongMaterial({color: 'hsl(130,50%,50%)'});
return {
obj3D: new THREE.Mesh(geometry, material),
update,
};
}
function houseScene(props, fogInHouse) {
const {scene, camera} = props;
scene.background = new THREE.Color('#FFF');
camera.far = 200;
const loader = new GLTFLoader();
const settings = {
shininess: 0,
roughness: 1,
metalness: 0,
};
loader.load('/manual/examples/resources/models/simple_house_scene/scene.gltf', (gltf) => {
const hackGeometry = new THREE.CircleGeometry(0.5, 32);
const box = new THREE.Box3();
const size = new THREE.Vector3();
const center = new THREE.Vector3();
const materials = new Set();
gltf.scene.traverse((node) => {
const material = node.material;
if (material) {
// hack in the bottom of the trees since I don't have
// the model file
if (node.name === 'mesh_11' || node.name === 'mesh_6') {
node.updateWorldMatrix(true, false);
box.setFromObject(node);
box.getSize(size);
box.getCenter(center);
const hackMesh = new THREE.Mesh(hackGeometry, node.material);
scene.add(hackMesh);
hackMesh.position.copy(center);
hackMesh.rotation.x = Math.PI * 0.5;
hackMesh.position.y -= size.y / 2;
hackMesh.scale.set(size.x, size.z, 1);
}
(Array.isArray(material) ? material : [material]).forEach((material) => {
if (!materials.has(material)) {
materials.add(material);
for (const [key, value] of Object.entries(settings)) {
if (material[key] !== undefined) {
material[key] = value;
}
}
if (!fogInHouse && material.name.startsWith('fogless')) {
material.fog = false;
}
}
});
}
});
scene.add(gltf.scene);
});
camera.fov = 45;
camera.position.set(0.4, 1, 1.7);
camera.lookAt(1, 1, 0.7);
const color = 0xFFFFFF;
const near = 1.5;
const far = 5;
scene.fog = new THREE.Fog(color, near, far);
const light = new THREE.PointLight(0xFFFFFF, 1);
light.position.copy(camera.position);
light.position.y += 0.2;
scene.add(light);
const target = [1, 1, 0.7];
return {
trackball: false,
obj3D: new THREE.Object3D(),
update: (time) => {
camera.lookAt(target[0] + Math.sin(time * .25) * .5, target[1], target[2]);
},
};
}
function createLightDarkFogUpdater(fog) {
return function() {
const isDarkMode = darkMatcher.matches;
const colors = isDarkMode ? darkColors : lightColors;
fog.color.set(colors.background);
};
}
threejsLessonUtils.addDiagrams({
fog: {
create(props) {
const {scene} = props;
const color = 0xFFFFFF;
const near = 12;
const far = 18;
const fog = new THREE.Fog(color, near, far);
return fogExample(scene, fog, createLightDarkFogUpdater(fog));
},
},
fogExp2: {
create(props) {
const {scene} = props;
const color = 0xFFFFFF;
const density = 0.1;
const fog = new THREE.FogExp2(color, density);
return fogExample(scene, fog, createLightDarkFogUpdater(fog));
},
},
fogBlueBackgroundRed: {
create(props) {
const {scene} = props;
scene.background = new THREE.Color('#F00');
const color = '#00F';
const near = 12;
const far = 18;
return fogExample(scene, new THREE.Fog(color, near, far));
},
},
fogBlueBackgroundBlue: {
create(props) {
const {scene} = props;
scene.background = new THREE.Color('#00F');
const color = '#00F';
const near = 12;
const far = 18;
return fogExample(scene, new THREE.Fog(color, near, far));
},
},
fogHouseAll: {
create(props) {
return houseScene(props, true);
},
},
fogHouseInsideNoFog: {
create(props) {
return houseScene(props, false);
},
},
});
}