You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
206 lines
4.4 KiB
JavaScript
206 lines
4.4 KiB
JavaScript
2 months ago
|
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 );
|
||
|
|
||
|
},
|
||
|
},
|
||
|
} );
|
||
|
|
||
|
}
|