Yeah! Finally! I did it!:
The code:
THREE Shadows body { margin: 0; } import * as THREE from 'three';
// scene
const scene = new THREE.Scene();
// camera
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.set(0,6,10);
// renderer
const renderer = new THREE.WebGLRenderer();
// enabling shadows
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.BasicShadowMap;
document.body.appendChild(renderer.domElement);
renderer.setSize(window.innerWidth, window.innerHeight);
// plane geometry
const geometryP = new THREE.PlaneGeometry(-50, -50, 50, 50);
geometryP.rotateX(-Math.PI / 2);
const materialP = new THREE.MeshStandardMaterial({color:0xffffff})
// Definir las alturas del terreno
const terrainVertices = geometryP.attributes.position.array;
for (let i = 0; i < terrainVertices.length; i += 3) {
const x = terrainVertices[i];
const z = terrainVertices[i + 2];
const y = Math.sin(x * 2) + Math.cos(z * 2); // Ejemplo de generación de alturas
terrainVertices[i + 1] = y;
}
geometryP.computeVertexNormals();
const plane = new THREE.Mesh(geometryP, materialP);
plane.castShadow = true;
plane.receiveShadow = true;
scene.add(plane);
// sphere geometry
const geometryS = new THREE.SphereGeometry(2, 32, 32);
const materialS = new THREE.MeshStandardMaterial({
color:0xffffff
});
const sphere = new THREE.Mesh(geometryS, materialS);
sphere.position.set(0,3,0);
sphere.receiveShadow = true;
sphere.castShadow = true;
scene.add(sphere);
// light
let light = new THREE.DirectionalLight(0xFFFFFF, 1.0);
light.position.set(20, 100, 10);
light.target.position.set(0, 0, 0);
light.castShadow = true;
scene.add(light);
//Crea los controles del mouse:
let xa=0;
let ya=0;
onmousedown=()=>{
if(document.pointerLockElement===document.body||
document.mozPointerLockElement===document.body){
}else{
document.body.requestPointerLock()
}
}
onmousemove=(event)=>{
if(document.pointerLockElement===document.body||
document.mozPointerLockElement===document.body){
xa-=0.01*event.movementX
if(-1.5<ya&&0<event.movementY){
ya-=0.005*event.movementY
}
if(ya<1.5&&event.movementY<0){
ya-=0.005*event.movementY
}
}
}
//Crear los controles de teclado:
let k=[];
onkeydown=onkeyup=(e)=>{
k[e.keyCode]=e.type=="keydown"
}
// Crear una función de animación
const animate = () => {
renderer.setSize(innerWidth,innerHeight)
camera.aspect=innerWidth/innerHeight
camera.updateProjectionMatrix()
requestAnimationFrame(animate)
renderer.render(scene,camera)
if(-1.5>ya){ya=-1.5}
if(1.5<ya){ya=1.5}
camera.lookAt(
camera.position.x+Math.sin(xa)*Math.cos(ya),
camera.position.y+Math.sin(ya),
camera.position.z+Math.cos(xa)*Math.cos(ya)
)
if(k[65]){
camera.position.x+=0.05*Math.cos(xa)
camera.position.z-=0.05*Math.sin(xa)
}
if(k[87]){
camera.position.x+=0.05*Math.sin(xa)
camera.position.z+=0.05*Math.cos(xa)
}
if(k[68]){
camera.position.x-=0.05*Math.cos(xa)
camera.position.z+=0.05*Math.sin(xa)
}
if(k[83]){
camera.position.x-=0.05*Math.sin(xa)
camera.position.z-=0.05*Math.cos(xa)
}
camera.position.y=Math.sin(camera.position.x * 2) + Math.cos(camera.position.z * 2)+3;
};
// Iniciar la animación
animate();
</script>
</body>