|
@@ -46,18 +46,19 @@ function main() {
|
|
const near = 0.1;
|
|
const near = 0.1;
|
|
const far = 5000;
|
|
const far = 5000;
|
|
const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
|
|
const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
|
|
- camera.position.x = -0.;
|
|
|
|
- camera.position.y = 350;
|
|
|
|
- camera.position.z = 40.;
|
|
|
|
|
|
+ camera.position.set(-580, 55, 390);
|
|
|
|
|
|
|
|
+ const maxFovX = 40;
|
|
|
|
+ const numBirds = 40;
|
|
|
|
+ const minMax = 700;
|
|
|
|
+ const birdSpeed = 100;
|
|
const useFog = true;
|
|
const useFog = true;
|
|
- const useOrbitCamera = false;
|
|
|
|
|
|
+ const useOrbitCamera = true;
|
|
const showHelpers = false;
|
|
const showHelpers = false;
|
|
- const camSpeed = 0.2;
|
|
|
|
|
|
|
|
if (useOrbitCamera) {
|
|
if (useOrbitCamera) {
|
|
const controls = new THREE.OrbitControls(camera);
|
|
const controls = new THREE.OrbitControls(camera);
|
|
- controls.target.set(0, 100.01, 0.2);
|
|
|
|
|
|
+ controls.target.set(0, 0, 0);
|
|
controls.update();
|
|
controls.update();
|
|
}
|
|
}
|
|
|
|
|
|
@@ -66,8 +67,8 @@ function main() {
|
|
renderer.shadowMap.enabled = true;
|
|
renderer.shadowMap.enabled = true;
|
|
|
|
|
|
const hemiLight = new THREE.HemisphereLight(0xffffff, 0xffffff, 0.6);
|
|
const hemiLight = new THREE.HemisphereLight(0xffffff, 0xffffff, 0.6);
|
|
- hemiLight.color.setHSL(0.6, 1, 0.6);
|
|
|
|
- hemiLight.groundColor.setHSL(0.095, 1, 0.75);
|
|
|
|
|
|
+ hemiLight.color.setHSL(0.6, 1, 0.5);
|
|
|
|
+ hemiLight.groundColor.setHSL(0.095, 1, 0.5);
|
|
hemiLight.position.set(0, 50, 0);
|
|
hemiLight.position.set(0, 50, 0);
|
|
scene.add(hemiLight);
|
|
scene.add(hemiLight);
|
|
|
|
|
|
@@ -97,20 +98,48 @@ function main() {
|
|
scene.add(dirLightHeper);
|
|
scene.add(dirLightHeper);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ const birds = [];
|
|
const loader = new THREE.GLTFLoader();
|
|
const loader = new THREE.GLTFLoader();
|
|
- const camRadius = 600;
|
|
|
|
- const camHeight = 160;
|
|
|
|
- const camTarget = [0, 30, 0];
|
|
|
|
const fogNear = 1350;
|
|
const fogNear = 1350;
|
|
const fogFar = 1500;
|
|
const fogFar = 1500;
|
|
- loader.load('resources/models/mountain_landscape/scene.gltf', (gltf) => {
|
|
|
|
- gltf.scene.traverse((child) => {
|
|
|
|
- if ( child.isMesh ) {
|
|
|
|
- child.castShadow = true;
|
|
|
|
- child.receiveShadow = true;
|
|
|
|
- }
|
|
|
|
- });
|
|
|
|
- scene.add(gltf.scene);
|
|
|
|
|
|
+
|
|
|
|
+ function rand(min, max) {
|
|
|
|
+ if (min === undefined) {
|
|
|
|
+ min = 0;
|
|
|
|
+ max = 1;
|
|
|
|
+ } else if (max === undefined) {
|
|
|
|
+ max = min;
|
|
|
|
+ min = 0;
|
|
|
|
+ }
|
|
|
|
+ return min + Math.random() * (max - min);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ loader.load( 'resources/models/flamingo/Flamingo.glb', (gltf) => {
|
|
|
|
+ const orig = gltf.scene.children[0];
|
|
|
|
+ orig.castShadow = true;
|
|
|
|
+ orig.receiveShadow = true;
|
|
|
|
+
|
|
|
|
+ for (let i = 0; i < numBirds; ++i) {
|
|
|
|
+ const u = i / (numBirds - 1);
|
|
|
|
+ const mesh = orig.clone();
|
|
|
|
+ mesh.position.set(
|
|
|
|
+ rand(-150, 150),
|
|
|
|
+ (u * 2 - 1) * 200,
|
|
|
|
+ (minMax * 2 * i * 1.7) % (minMax * 2) - minMax / 2,
|
|
|
|
+ );
|
|
|
|
+ scene.add(mesh);
|
|
|
|
+ mesh.material = mesh.material.clone();
|
|
|
|
+ mesh.material.color.setHSL(rand(), 1, 0.8);
|
|
|
|
+
|
|
|
|
+ const mixer = new THREE.AnimationMixer(mesh);
|
|
|
|
+ mixer.clipAction(gltf.animations[0]).setDuration(1).play();
|
|
|
|
+ mixer.update(rand(10));
|
|
|
|
+ mixer.timeScale = rand(0.9, 1.1);
|
|
|
|
+ birds.push({
|
|
|
|
+ mixer,
|
|
|
|
+ mesh,
|
|
|
|
+ });
|
|
|
|
+ }
|
|
});
|
|
});
|
|
|
|
|
|
window.s = scene;
|
|
window.s = scene;
|
|
@@ -146,7 +175,7 @@ function main() {
|
|
uniforms.topColor.value.copy(hemiLight.color);
|
|
uniforms.topColor.value.copy(hemiLight.color);
|
|
scene.fog = new THREE.Fog(scene.background, fogNear, fogFar);
|
|
scene.fog = new THREE.Fog(scene.background, fogNear, fogFar);
|
|
scene.fog.color.copy(uniforms.bottomColor.value);
|
|
scene.fog.color.copy(uniforms.bottomColor.value);
|
|
- const skyGeo = new THREE.SphereBufferGeometry(4000, 32, 15);
|
|
|
|
|
|
+ const skyGeo = new THREE.SphereBufferGeometry(3000, 32, 15);
|
|
const skyMat = new THREE.ShaderMaterial( { vertexShader: vertexShader, fragmentShader: fragmentShader, uniforms: uniforms, side: THREE.BackSide } );
|
|
const skyMat = new THREE.ShaderMaterial( { vertexShader: vertexShader, fragmentShader: fragmentShader, uniforms: uniforms, side: THREE.BackSide } );
|
|
const sky = new THREE.Mesh( skyGeo, skyMat );
|
|
const sky = new THREE.Mesh( skyGeo, skyMat );
|
|
scene.add(sky);
|
|
scene.add(sky);
|
|
@@ -164,19 +193,24 @@ function main() {
|
|
return true;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
|
|
- function render(time) {
|
|
|
|
- time *= 0.001;
|
|
|
|
- time += 80;
|
|
|
|
|
|
+ let then = 0;
|
|
|
|
+ function render(now) {
|
|
|
|
+ now *= 0.001;
|
|
|
|
+ const deltaTime = now - then;
|
|
|
|
+ then = now;
|
|
|
|
|
|
if (resizeRendererToDisplaySize(renderer)) {
|
|
if (resizeRendererToDisplaySize(renderer)) {
|
|
- camera.aspect = canvas.clientWidth / canvas.clientHeight;
|
|
|
|
|
|
+ const aspect = canvas.clientWidth / canvas.clientHeight;
|
|
|
|
+ const fovX = THREE.Math.radToDeg(2 * Math.atan(Math.tan(THREE.Math.degToRad(fov) * 0.5) * aspect));
|
|
|
|
+ const newFovY = THREE.Math.radToDeg(2 * Math.atan(Math.tan(THREE.Math.degToRad(maxFovX) * .5) / aspect));
|
|
|
|
+ camera.fov = fovX > maxFovX ? newFovY : fov;
|
|
|
|
+ camera.aspect = aspect;
|
|
camera.updateProjectionMatrix();
|
|
camera.updateProjectionMatrix();
|
|
}
|
|
}
|
|
|
|
|
|
- if (!useOrbitCamera) {
|
|
|
|
- const angle = Math.sin(time * camSpeed) + Math.PI * .75;
|
|
|
|
- camera.position.set(Math.cos(angle) * camRadius, camHeight, Math.sin(angle) * camRadius);
|
|
|
|
- camera.lookAt(...camTarget);
|
|
|
|
|
|
+ for (const {mesh, mixer} of birds) {
|
|
|
|
+ mixer.update(deltaTime);
|
|
|
|
+ mesh.position.z = (mesh.position.z + minMax + mixer.timeScale * birdSpeed * deltaTime) % (minMax * 2) - minMax;
|
|
}
|
|
}
|
|
|
|
|
|
renderer.render(scene, camera);
|
|
renderer.render(scene, camera);
|