commit 2d3e3a6b7249d8eef971e524d68611297114a326
parent 6e2641f555d0d672025a5f87418436e3f4d29999
Author: Martin J. Klöckner <mjkloeckner@gmail.com>
Date: Sat, 13 Jul 2024 18:23:44 -0300
Merge pull request #3 from mjkloeckner/shadows
Add shadows to all objects in scene
Diffstat:
6 files changed, 256 insertions(+), 124 deletions(-)
diff --git a/tp/src/bridge.js b/tp/src/bridge.js
@@ -228,13 +228,10 @@ export function generateBridge(arcCount=1, arcRadius=3,
textures.ladrillos.object.wrapS = THREE.RepeatWrapping;
textures.ladrillos.object.wrapT = THREE.RepeatWrapping;
textures.ladrillos.object.repeat.set(0.75*0.15, 0.75*0.35);
- textures.ladrillos.object.anisotropy = 16;
+ // textures.ladrillos.object.anisotropy = 16;
const bridgeMaterial = new THREE.MeshPhongMaterial({
- side: THREE.DoubleSide,
- transparent: false,
- opacity: 1.0,
- shininess: 10,
+ side: THREE.FrontSide,
map: textures.ladrillos.object
});
@@ -258,6 +255,9 @@ export function generateBridge(arcCount=1, arcRadius=3,
*/
const bridgeColumns = new THREE.Mesh(bridgeColumnsGeometry, bridgeMaterial);
+ bridgeColumns.castShadow = true;
+ bridgeColumns.receiveShadow = true;
+
bridge.add(bridgeColumns);
// para reutilizar la textura de ladrillos usada en los arcos se escalan las
@@ -270,11 +270,14 @@ export function generateBridge(arcCount=1, arcRadius=3,
const bridgeRoadway = new THREE.Mesh(bridgeRoadwayGeometry, bridgeMaterial);
bridge.add(bridgeRoadway);
+ bridgeRoadway.castShadow = true;
+ bridgeRoadway.receiveShadow = true;
+
const cageGeometry = generateBridgeCage(squaresCount)
cageGeometry.translate(0, bridgeHeight+roadwayHeight-squareTubeRadius*2, 0);
const cageMaterial = new THREE.MeshPhongMaterial({
- side: THREE.DoubleSide,
+ side: THREE.FrontSide,
transparent: false,
opacity: 1.0,
shininess: 10,
@@ -282,6 +285,10 @@ export function generateBridge(arcCount=1, arcRadius=3,
});
const bridgeCage = new THREE.Mesh(cageGeometry, cageMaterial);
+
+ bridgeCage.castShadow = true;
+ bridgeCage.receiveShadow = true;
+
bridge.add(bridgeCage);
const roadwayFloorGeometry = new THREE.BoxGeometry(
@@ -298,14 +305,14 @@ export function generateBridge(arcCount=1, arcRadius=3,
textures.tierra.object.anisotropy = 16;
const roadwayFloorMaterial = new THREE.MeshPhongMaterial({
- side: THREE.DoubleSide,
- transparent: false,
- opacity: 1.0,
- shininess: 10,
+ side: THREE.FrontSide,
map: textures.tierra.object
});
const roadwayFloor = new THREE.Mesh(roadwayFloorGeometry, roadwayFloorMaterial);
+ roadwayFloor.receiveShadow = true;
+ roadwayFloor.castShadow = false;
+
bridge.add(roadwayFloor)
return bridge;
}
diff --git a/tp/src/scene.js b/tp/src/scene.js
@@ -3,28 +3,27 @@ import * as dat from 'dat.gui';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
import { FirstPersonControls } from 'three/addons/controls/FirstPersonControls.js';
import { PointerLockControls } from 'three/addons/controls/PointerLockControls.js';
-import { vertexShader, fragmentShader } from '/src/shaders.js';
-
+import Stats from 'three/examples/jsm/libs/stats.module.js';
+import { updateTrainCrankPosition } from '/src/train.js';
import { generateTunnelGeometry } from '/src/tunnel.js';
import { createInstancedTrees } from '/src/trees.js';
import { elevationGeometry } from '/src/terrain.js';
+import { generateBridge } from '/src/bridge.js';
+import { buildTrain } from '/src/train.js';
import {
getRailsPathPosAt,
buildRailsGeometry,
buildRailsFoundationGeometry
} from '/src/rails.js';
-import { buildTrain } from '/src/train.js';
-import { generateBridge } from '/src/bridge.js';
-import { updateTrainCrankPosition } from '/src/train.js';
-
-let scene, camera, renderer, terrainGeometry, terrain, time, gui;
-let treesForbiddenMapData, treesForbiddenMap, elevationMap, elevationMapData;
+let scene, camera, renderer, time, prevTime, gui, stats;
+let terrainGeometry, terrain, treesForbiddenMapData, treesForbiddenMap, elevationMap, elevationMapData;
let firstPersonControls, orbitControls;
-
let train, trainLight, trainLight2, trainLight3;
+let helpers = [];
let cameras = [];
+let camerasName = [];
let objects = [];
let lights = {
ambient: { object: null },
@@ -38,6 +37,9 @@ let settings = {
currCameraIndex: 0,
nightMode: true,
showHelpers: false,
+ showFps: true,
+ currCameraName: "",
+ shadows: false
};
let raycaster;
@@ -48,7 +50,6 @@ let moveBackward = false;
let moveLeft = false;
let moveRight = false;
-let prevTime = performance.now();
const velocity = new THREE.Vector3();
const direction = new THREE.Vector3();
@@ -94,50 +95,63 @@ function onResize() {
renderer.setSize( window.innerWidth, window.innerHeight );
}
-function prevCamera() {
- const camerasCount = cameras.length;
+function updateCamera() {
+ orbitControls.enabled = false;
+ blocker.style.display = 'none';
+ instructions.style.display = 'none';
+ if(settings.nightMode == true) {
+ trainLight.intensity = 200;
+ trainLight.distance = 100;
+ }
+
+ firstPersonControls.unlock();
- if(cameras[settings.currCameraIndex].name == "firstPersonCamera") {
- firstPersonControls.unlock();
- blocker.style.display = 'none';
- instructions.style.display = 'flex';
+ let currCamera = cameras[settings.currCameraIndex];
+ switch(currCamera.name) {
+ case "topView":
+ orbitControls.enabled = true;
+ break;
+ case "firstPersonCamera":
+ blocker.style.display = 'block';
+ instructions.style.display = 'flex';
+ break;
+ case "trainCamera":
+ case "trainConductorCamera":
+ // por alguna razon cuando la camara es `trainConductorCamera`
+ // o `trainCamera` la luz principal del tren se ve mas tenue
+ if(settings.nightMode == true) {
+ trainLight.intensity = 1000;
+ trainLight.distance = 1000;
+ }
+ break;
+ default:
+ break;
}
+ onResize();
+ settings.currCameraName = camerasName[settings.currCameraIndex];
+}
+
+function prevCamera() {
+ const camerasCount = cameras.length;
if(settings.currCameraIndex == 0) {
settings.currCameraIndex = (camerasCount - 1);
} else {
settings.currCameraIndex -= 1;
}
-
- if(cameras[settings.currCameraIndex].name == "firstPersonCamera") {
- firstPersonControls.unlock();
- blocker.style.display = 'block';
- instructions.style.display = 'flex';
- }
- onResize();
+ updateCamera();
}
function nextCamera() {
const camerasCount = cameras.length;
- if(cameras[settings.currCameraIndex].name == "firstPersonCamera") {
- firstPersonControls.unlock();
- blocker.style.display = 'none';
- instructions.style.display = 'flex';
- }
-
if(settings.currCameraIndex == (camerasCount - 1)) {
settings.currCameraIndex = 0;
} else {
settings.currCameraIndex += 1;
}
- if(cameras[settings.currCameraIndex].name == "firstPersonCamera") {
- firstPersonControls.unlock();
- blocker.style.display = 'block';
- instructions.style.display = 'flex';
- }
- onResize();
+ updateCamera();
}
const blocker = document.getElementById( 'blocker' );
@@ -195,6 +209,9 @@ function keyHandler(event) {
} else {
nextCamera();
}
+ if(gui != undefined) {
+ gui.__controllers[6].updateDisplay();
+ }
break;
case 'Space':
// if (firstPersonControls.isLocked === true) {
@@ -202,7 +219,6 @@ function keyHandler(event) {
// velocity.y += 350;
// break;
// }
- console.log("Toggling train animations");
settings.animationEnable = !settings.animationEnable;
if(gui != undefined) {
// update gui 'Animations' checkbox
@@ -260,6 +276,7 @@ function setupFirstPersonControls() {
firstPersonCamera.lookAt(-10, 5, 0);
firstPersonCamera.name = "firstPersonCamera"
cameras.push(firstPersonCamera);
+ camerasName.push("Primera Persona");
firstPersonControls = new PointerLockControls(firstPersonCamera, document.body);
@@ -294,7 +311,15 @@ function setupThreeJs() {
renderer = new THREE.WebGLRenderer();
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
- document.body.appendChild( renderer.domElement );
+ renderer.shadowMap.type = THREE.PCFSoftShadowMap; // default THREE.PCFShadowMap
+ renderer.shadowMap.enabled = settings.shadows;
+
+ document.body.appendChild(renderer.domElement);
+
+ stats = new Stats();
+ if(settings.showFps == true) {
+ document.body.appendChild(stats.dom);
+ }
const topView = new THREE.PerspectiveCamera(
35, window.innerWidth / window.innerHeight, 0.1, 1000);
@@ -303,6 +328,7 @@ function setupThreeJs() {
topView.lookAt(0, 0, 0);
topView.name = "topView"
cameras.push(topView);
+ camerasName.push("Vista Global");
orbitControls = new OrbitControls(topView, renderer.domElement);
@@ -311,8 +337,21 @@ function setupThreeJs() {
lights.hemisphere.object = new THREE.HemisphereLight(0xFFFFFF, 0x000000, 0.25);
lights.directional.object = new THREE.DirectionalLight(0xffffff, 1);
- lights.directional.object.position.set(-100, 100, 100);
-
+ lights.directional.object.position.set(-35, 35, 35);
+
+ // Set up shadow properties for the light
+ lights.directional.object.castShadow = true;
+ lights.directional.object.shadow.mapSize.width = 512;
+ lights.directional.object.shadow.mapSize.height = 512;
+
+ lights.directional.object.shadow.camera = new THREE.OrthographicCamera(
+ -65, 65, 45, -35, 1.0, 112);
+
+ const directionalLightShadowsHelper = new THREE.CameraHelper(lights.directional.object.shadow.camera);
+ directionalLightShadowsHelper.visible = settings.showHelpers;
+ scene.add(directionalLightShadowsHelper);
+ helpers.push(directionalLightShadowsHelper);
+
scene.add(lights.ambient.object);
scene.add(lights.hemisphere.object);
scene.add(lights.directional.object);
@@ -322,27 +361,32 @@ function setupThreeJs() {
lights.hemisphere.object.intensity = 0;
lights.directional.object.color.setHex(0xcdddfe); // 0x090254; 0xa8a1fd
scene.background = textures.skyNight.object;
- lights.directional.object.position.set(100, 100, 100); // math the skybox texture moon light
+ lights.directional.object.position.set(35, 35, 35); // match the skybox texture moon light position
} else {
lights.ambient.object.visible = true;
lights.hemisphere.object.intensity = 1;
lights.directional.object.intensity = 1;
lights.directional.object.color.setHex(0xFFFFFF);
scene.background = textures.skyDay.object;
- lights.directional.object.position.set(-100, 100, 100);
+ lights.directional.object.position.set(-35, 35, 35);
}
- const helper = new THREE.HemisphereLightHelper(lights.hemisphere.object, 5);
- if(settings.showHelpers) scene.add(helper) ;
+ const hemisphereLightHelper = new THREE.HemisphereLightHelper(lights.hemisphere.object, 5);
+ helpers.push(hemisphereLightHelper);
- const directinoalLightHelper = new THREE.DirectionalLightHelper( lights.directional.object, 5);
- if(settings.showHelpers) scene.add(directinoalLightHelper);
+ const directionalLightHelper = new THREE.DirectionalLightHelper(lights.directional.object, 5);
+ helpers.push(directionalLightHelper);
- const gridHelper = new THREE.GridHelper(200, 200);
- if(settings.showHelpers) scene.add(gridHelper);
+ const gridHelper = new THREE.GridHelper(100, 100);
+ helpers.push(gridHelper);
const axesHelper = new THREE.AxesHelper(5);
- if(settings.showHelpers) scene.add(axesHelper);
+ helpers.push(axesHelper);
+
+ for(let i = 0; i < helpers.length; ++i) {
+ helpers[i].visible = settings.showHelpers;
+ scene.add(helpers[i]);
+ }
window.addEventListener('resize', onResize);
onResize();
@@ -410,6 +454,12 @@ function buildBridge() {
bridge2.add(bridgeCamera);
bridgeCamera.name = "bridgeCamera";
cameras.push(bridgeCamera);
+ camerasName.push("Vista del Puente");
+
+ bridge1.castShadow = true;
+ bridge1.receiveShadow = true;
+ bridge2.castShadow = true;
+ bridge2.receiveShadow = true;
scene.add(bridge1);
scene.add(bridge2);
@@ -430,6 +480,7 @@ function buildLoco() {
train.add(trainConductorCamera);
trainConductorCamera.name = "trainConductorCamera";
cameras.push(trainConductorCamera);
+ camerasName.push("Cabina del Tren");
const trainCamera = new THREE.PerspectiveCamera(
55, window.innerWidth / window.innerHeight, 0.1, 10000);
@@ -439,6 +490,7 @@ function buildLoco() {
train.add(trainCamera);
trainCamera.name = `trainCamera`;
cameras.push(trainCamera);
+ camerasName.push("Costado del Tren");
const trainBackCamera = new THREE.PerspectiveCamera(
55, window.innerWidth / window.innerHeight, 0.1, 10000);
@@ -448,29 +500,58 @@ function buildLoco() {
train.add(trainBackCamera);
trainBackCamera.name = "trainBackCamera";
cameras.push(trainBackCamera);
+ camerasName.push("Vista hacia atras desde la Cabina del Tren");
// SpotLight(color: Int, intensity: Float, distance: Float, angle: Radians, penumbra: Float, decay: Float)
- trainLight = new THREE.SpotLight(0xffffff, 100.0, 2000.0, Math.PI/3, 0.5, 0.5);
+ trainLight = new THREE.SpotLight(0xffffff, 200.0, 100.0, Math.PI/6, 0.5, 1.0);
train.add(trainLight.target);
train.add(trainLight);
- trainLight.position.set(0, 2, 15);
- trainLight.target.position.set(0, -100, 100);
+ trainLight.position.set(0, 4, 5);
+ trainLight.target.position.set(0, -100, 1000);
trainLight.target.updateMatrixWorld();
- trainLight2 = new THREE.SpotLight(0xffffff, 10.0, 4.0, Math.PI/2, 0.5, 0.5);
+ trainLight2 = new THREE.SpotLight(0xffffff, 10.0, 3.0, Math.PI/6, 0.5, 0.5);
train.add(trainLight2.target);
train.add(trainLight2);
- trainLight2.position.set(0, 5, 20);
+ trainLight2.position.set(0, 3.25, 15);
trainLight2.target.position.set(0, 0, -100);
trainLight2.target.updateMatrixWorld();
- trainLight3 = new THREE.SpotLight(0xffffff, 10.0, 10.0, Math.PI/2, 0.5, 0.5);
+ trainLight3 = new THREE.SpotLight(0xffffff, 10.0, 16.0, Math.PI/3, 0.5, 0.5);
train.add(trainLight3.target);
train.add(trainLight3);
- trainLight3.position.set(0, 5, 10);
- trainLight3.target.position.set(0, 0, 100);
+ trainLight3.position.set(0, 5, 5);
+ trainLight3.target.position.set(0, -25, 100);
trainLight3.target.updateMatrixWorld();
+ //Set up shadow properties for the light
+ trainLight.castShadow = true;
+ trainLight.shadow.mapSize.width = 256;
+ trainLight.shadow.mapSize.height = 256;
+ trainLight.shadow.camera.near = 0.5;
+ trainLight.shadow.camera.far = 40;
+ trainLight.shadow.focus = 1;
+
+ trainLight3.castShadow = true;
+ trainLight3.shadow.mapSize.width = 128;
+ trainLight3.shadow.mapSize.height = 128;
+ trainLight3.shadow.camera.near = 0.5;
+ trainLight3.shadow.camera.far = 25;
+ trainLight3.shadow.focus = 1;
+
+ const trainLightHelper = new THREE.CameraHelper(trainLight.shadow.camera);
+ const trainLight3Helper = new THREE.CameraHelper(trainLight3.shadow.camera);
+
+ trainLight.visible = settings.nightMode;
+ trainLight2.visible = settings.nightMode;
+ trainLight3.visible = settings.nightMode;
+
+ trainLightHelper.visible = settings.showHelpers;
+ trainLight3Helper.visible = settings.showHelpers;
+
+ helpers.push(trainLightHelper);
+ helpers.push(trainLight3Helper);
+
train.scale.set(0.145, 0.145, 0.145);
train.visible = settings.showTrain;
scene.add(train);
@@ -485,23 +566,22 @@ function buildRailsFoundation() {
textures.durmientes.object.anisotropy = 16;
// load into `map` the example texture
- const map = new THREE.TextureLoader().load(
- 'https://threejs.org/examples/textures/uv_grid_opengl.jpg');
- map.wrapS = map.wrapT = THREE.RepeatWrapping;
- map.repeat.set(1, 80);
- map.anisotropy = 16;
+ // const map = new THREE.TextureLoader().load(
+ // 'https://threejs.org/examples/textures/uv_grid_opengl.jpg');
+ // map.wrapS = map.wrapT = THREE.RepeatWrapping;
+ // map.repeat.set(1, 80);
+ // map.anisotropy = 16;
// map.rotation = Math.PI/2;
const railsFoundationMaterial = new THREE.MeshPhongMaterial({
- side: THREE.DoubleSide,
- transparent: false,
- opacity: 1.0,
- shininess: 10,
+ side: THREE.FrontSide,
map: textures.durmientes.object
// map: map
});
const railsFoundation = new THREE.Mesh(railsFoundationGeometry, railsFoundationMaterial);
+ railsFoundation.receiveShadow = true;
+ railsFoundation.castShadow = true;
railsFoundation.position.set(-1, 1.25, -1);
railsFoundation.scale.set(1.00, 1.50, 1.00);
scene.add(railsFoundation);
@@ -513,14 +593,13 @@ function buildRailsFoundation() {
function buildRails() {
const railsGeometry = buildRailsGeometry();
const railsMaterial = new THREE.MeshPhongMaterial({
- side: THREE.DoubleSide,
- transparent: false,
- opacity: 1.0,
- shininess: 10,
+ side: THREE.BackSide,
color: 0xFFFFFF
});
const rails = new THREE.Mesh(railsGeometry, railsMaterial);
+ rails.castShadow = true;
+ rails.receiveShadow = true;
rails.position.set(-1, 1.25, -1);
rails.scale.set(1.00, 1.50, 1.00);
scene.add(rails);
@@ -530,9 +609,7 @@ function buildTerrainCustomMaterial() {
const customMaterial = new THREE.MeshPhongMaterial({
color: 0xffffff,
specular: 0x333333,
- shininess: 10,
- side: THREE.DoubleSide,
- reflectivity: 1
+ side: THREE.FrontSide,
});
// definos las variables uniformes adicionales que necesitamos
@@ -697,6 +774,9 @@ function buildTerrain() {
const customMaterial = buildTerrainCustomMaterial();
terrain = new THREE.Mesh(terrainGeometry, customMaterial);
+ terrain.castShadow = true;
+ terrain.receiveShadow = true;
+
scene.add(terrain);
terrain.position.set(0, amplitudeBottom, 0);
@@ -704,10 +784,13 @@ function buildTerrain() {
console.log('Generating water');
const waterGeometry = new THREE.PlaneGeometry(width/2, height-1.25);
- const waterMaterial = new THREE.MeshPhongMaterial( {color: 0x12ABFF, side: THREE.DoubleSide} );
+ const waterMaterial = new THREE.MeshPhongMaterial( {color: 0x12ABFF, side: THREE.BackSide} );
const water = new THREE.Mesh( waterGeometry, waterMaterial );
water.rotateX(Math.PI/2);
water.position.set(0, 0, -0.65);
+
+ water.castShadow = false;
+ water.receiveShadow = true;
scene.add(water);
}
@@ -721,14 +804,13 @@ function buildTunnel() {
textures.madera.object.anisotropy = 16;
const tunnelMaterial = new THREE.MeshPhongMaterial({
- side: THREE.DoubleSide,
- transparent: false,
- opacity: 1.0,
- shininess: 10,
+ side: THREE.FrontSide,
map: textures.madera.object
});
const tunnel = new THREE.Mesh(tunnelGeometry, tunnelMaterial) ;
+ tunnel.castShadow = true;
+ tunnel.receiveShadow = true;
tunnel.scale.set(0.5, 0.5, 0.5);
const trainPathPos = getRailsPathPosAt(0.32);
@@ -745,12 +827,18 @@ function buildTunnel() {
tunnelCamera.name = "tunnelCamera";
tunnel.add(tunnelCamera);
cameras.push(tunnelCamera);
+ camerasName.push("Camara del Tunel");
}
function buildTrees(count = 50) {
const [treeLogs, treeLeaves] = createInstancedTrees(count);
scene.add(treeLogs);
scene.add(treeLeaves);
+
+ treeLogs.castShadow = true;
+ treeLogs.receiveShadow = true;
+ treeLeaves.castShadow = true;
+ treeLeaves.receiveShadow = true;
}
function toggleNightMode() {
@@ -761,7 +849,7 @@ function toggleNightMode() {
lights.hemisphere.object.intensity = 0;
lights.directional.object.color.setHex(0xcdddfe); // 0x090254; 0xa8a1fd
scene.background = textures.skyNight.object;
- lights.directional.object.position.set(100, 100, 100); // math the skybox texture moon light
+ lights.directional.object.position.set(35, 35, 35); // match the skybox texture moon light
trainLight.visible = true;
trainLight2.visible = true;
trainLight3.visible = true;
@@ -771,7 +859,7 @@ function toggleNightMode() {
lights.directional.object.intensity = 1;
lights.directional.object.color.setHex(0xFFFFFF);
scene.background = textures.skyDay.object;
- lights.directional.object.position.set(-100, 100, 100);
+ lights.directional.object.position.set(-35, 35, 35);
trainLight.visible = false;
trainLight2.visible = false;
trainLight3.visible = false;
@@ -784,14 +872,48 @@ function createMenu() {
gui.add(settings, 'showTrain').name('Mostrar tren').onChange(
function () {
train.visible = !train.visible;
- });
+ }
+ );
gui.add(settings, 'nightMode', false).name('Modo noche').onChange(toggleNightMode);
+ gui.add(settings, 'showHelpers', true).name('Mostrar Guias').onChange(
+ function() {
+ for(let i = 0; i < helpers.length; ++i) {
+ helpers[i].visible = settings.showHelpers;
+ scene.add(helpers[i]);
+ }
+ }
+ );
+ gui.add(settings, 'showFps', true).name('Mostrar FPS').onChange(
+ function() {
+ if(settings.showFps == true) {
+ document.body.appendChild(stats.dom);
+ } else {
+ document.body.removeChild(stats.dom);
+ }
+ }
+ );
+ gui.add(settings, 'shadows', true).name('Sombras').onChange(
+ function() {
+ renderer.shadowMap.enabled = settings.shadows;
+ scene.traverse(function (child) {
+ if (child.material) {
+ child.material.needsUpdate = true
+ }
+ });
+ }
+ );
+ gui.add(settings, "currCameraName", camerasName).name('Camara').setValue(camerasName[settings.currCameraIndex]).onChange(
+ function() {
+ settings.currCameraIndex = camerasName.indexOf(settings.currCameraName);
+ updateCamera();
+ }
+ );
}
function buildScene() {
console.log('Building scene');
buildTunnel();
- buildTrees(350);
+ buildTrees(200);
buildTerrain();
buildRailsFoundation();
buildRails();
@@ -800,25 +922,8 @@ function buildScene() {
}
function mainLoop() {
- let currCamera = cameras[settings.currCameraIndex];
- switch(currCamera.name) {
- case "topView":
- orbitControls.enabled = true;
- blocker.style.display = 'none';
- instructions.style.display = 'none';
- break;
- case "firstPersonCamera":
- orbitControls.enabled = false;
- break;
- default:
- orbitControls.enabled = false;
- blocker.style.display = 'none';
- instructions.style.display = 'none';
- break;
- }
-
requestAnimationFrame(mainLoop);
- renderer.render(scene, currCamera);
+ stats.begin();
const dt = 0.001;
if(settings.animationEnable) {
@@ -891,16 +996,20 @@ function mainLoop() {
// canJump = true;
}
}
+
prevTime = time2;
+ renderer.render(scene, cameras[settings.currCameraIndex]);
+ stats.end();
}
function main() {
setupThreeJs();
setupFirstPersonControls();
time = 0.90;
+ prevTime = performance.now();
buildScene();
createMenu();
- nextCamera();
+ updateCamera();
mainLoop();
}
diff --git a/tp/src/standalone/rails.js b/tp/src/standalone/rails.js
@@ -172,6 +172,8 @@ export function buildRailsFoundation() {
map: textures.durmientes.object
});
const pMesh = new THREE.Mesh(pGeometry, pMaterial);
+ pMesh.receiveShadow = true;
+ pMesh.castShadow = true;
scene.add(pMesh);
}
@@ -245,6 +247,7 @@ function buildRails() {
const railsGeometry = mergeGeometries(railsGeometries);
const rails = new THREE.Mesh(railsGeometry, railsMaterial);
+ rails.castShadow = true;
scene.add(rails);
}
diff --git a/tp/src/terrain.js b/tp/src/terrain.js
@@ -1,5 +1,4 @@
import * as THREE from 'three';
-import { vertexShader, fragmentShader } from '/src/shaders.js';
const widthSegments = 100;
const heightSegments = 100;
diff --git a/tp/src/train.js b/tp/src/train.js
@@ -149,19 +149,22 @@ function buildChamber() {
}
function buildTrainWheel() {
- const wheel = new THREE.CylinderGeometry(wheelRad, wheelRad, wheelThickness);
- wheel.rotateZ(Math.PI/2);
+ const wheelGeometry = new THREE.CylinderGeometry(wheelRad, wheelRad, wheelThickness);
+ wheelGeometry.rotateZ(Math.PI/2);
const wheelBolt = new THREE.CylinderGeometry(wheelRad, wheelRad, wheelThickness);
wheelBolt.rotateZ(Math.PI/2);
const wheelsMaterial = new THREE.MeshPhongMaterial({
color: 0x393939,
- side: THREE.DoubleSide,
+ side: THREE.FrontSide,
shininess: 100.0
});
- return new THREE.Mesh(wheel, wheelsMaterial)
+ const wheel = new THREE.Mesh(wheelGeometry, wheelsMaterial);
+ wheel.castShadow = true;
+ wheel.receiveShadow = true;
+ return wheel;
}
function buildTrainAxe(material) {
@@ -170,7 +173,7 @@ function buildTrainAxe(material) {
const axeMaterial = new THREE.MeshPhongMaterial({
color: 0x7A7F80,
- side: THREE.DoubleSide,
+ side: THREE.FrontSide,
shininess: 100.0
});
@@ -189,26 +192,32 @@ export function buildTrain() {
const chassisGeometry = buildTrainChassis();
const chassisMaterial = new THREE.MeshPhongMaterial({
color: 0x7A7F80,
- side: THREE.DoubleSide,
+ side: THREE.FrontSide,
shininess: 100.0
});
const chassis = new THREE.Mesh(chassisGeometry, chassisMaterial);
+ chassis.castShadow = true;
+ chassis.receiveShadow = true;
train.add(chassis);
const chamberGeometry = buildChamber();
const chamberMaterial = new THREE.MeshPhongMaterial({
color: 0xFA1A09,
- side: THREE.DoubleSide,
+ side: THREE.FrontSide,
shininess: 100.0
});
const chamber = new THREE.Mesh(chamberGeometry, chamberMaterial);
+ chamber.castShadow = true;
+ chamber.receive = true;
chassis.add(chamber);
chamber.position.set(0, (chassisHeight + cabinWallThickness)/2, chassisOffset);
const cabinGeometry = buildCabin();
const cabin = new THREE.Mesh(cabinGeometry, chamberMaterial);
+ cabin.castShadow = true;
+ cabin.receive = true;
chassis.add(cabin);
cabin.position.set(0,
(chassisHeight + cabinWallThickness)/2,
@@ -217,11 +226,13 @@ export function buildTrain() {
const cabinRoofGeometry = buildCabinRoof();
const roofMaterial = new THREE.MeshPhongMaterial({
color: 0xFBEC50,
- side: THREE.DoubleSide,
+ side: THREE.FrontSide,
shininess: 100.0
});
const cabinRoof = new THREE.Mesh(cabinRoofGeometry, roofMaterial);
+ cabinRoof.castShadow = true;
+ cabinRoof.receive = true;
cabin.add(cabinRoof);
cabinRoof.position.set(0, cabinHeight+cabinRoofHeight+cabinWallThickness/2, 0);
@@ -249,11 +260,14 @@ export function buildTrain() {
const cylindersGeometry = BufferGeometryUtils.mergeGeometries([cylinderRight, cylinderLeft]);
const cylindersMaterial = new THREE.MeshPhongMaterial({
color: 0x393939,
- side: THREE.DoubleSide,
+ side: THREE.FrontSide,
shininess: 100.0
});
- chassis.add(new THREE.Mesh(cylindersGeometry, cylindersMaterial));
+ const cylinders = new THREE.Mesh(cylindersGeometry, cylindersMaterial)
+ cylinders.castShadow = true;
+ cylinders.receiveShadow = true;
+ chassis.add(cylinders);
chassis.position.set(0,-2,-2.75);
const w1 = buildTrainWheel();
@@ -269,7 +283,7 @@ export function buildTrain() {
a2.add(w3);
const w4 = buildTrainWheel();
- w4.position.set(-steamChamberRad+wheelThickness/2.1,0,);
+ w4.position.set(-steamChamberRad+wheelThickness/2.1,0,0);
a2.add(w4);
const w5 = buildTrainWheel();
@@ -300,7 +314,7 @@ export function buildTrain() {
const lightMaterial = new THREE.MeshPhongMaterial({
color: 0x393939,
- side: THREE.DoubleSide,
+ side: THREE.FrontSide,
shininess: 100.0,
emissive: 0xf6d32d
});
diff --git a/tp/src/trees.js b/tp/src/trees.js
@@ -80,7 +80,7 @@ export function createInstancedTrees(count) {
treeLogGeometry.translate(0, logHeight/2.0, 0);
const instancedTreeLogGeometry = new THREE.InstancedBufferGeometry();
instancedTreeLogGeometry.copy(treeLogGeometry);
- const treeLogMaterial = new THREE.MeshPhongMaterial({color: 0x7c3f00});
+ const treeLogMaterial = new THREE.MeshPhongMaterial({color: 0x7c3f00, side: THREE.FrontSide});
const instancedTreeLogs = new THREE.InstancedMesh(
instancedTreeLogGeometry,
treeLogMaterial,