Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

230
Vistas
How to get world coordinates from clicking screen in Three.js using displacement maps?

I'm trying to get world coordinates from clicking the screen, but using displacement maps. This makes it more complex as the floor is variable heights (hills). My approach so far is to calculate the point on the floor (assuming the floor was all flat at z=0), then ray trace from the camera to that point, and at each iteration see where the height of the ray becomes <= the real height of the floor at that point. Once its smaller or equal to, we know it hit the floor and have the (x,y,z). Points outside the map have z=0 too.

This is the code:

// https://stackoverflow.com/questions/13055214/mouse-canvas-x-y-to-three-js-world-x-y-z
public static Get3DPoints(camera:THREE.PerspectiveCamera, click_position:THREE.Vector2, targetZ:number) {
    var vec = new THREE.Vector3(); // create once and reuse
    var pos = new THREE.Vector3(); // create once and reuse
    vec.set(
        ( click_position.x / window.innerWidth ) * 2 - 1,
        - ( click_position.y / window.innerHeight ) * 2 + 1,
        0.5 );
    vec.unproject( camera );
    vec.sub( camera.position ).normalize();
    var distance = ( targetZ - camera.position.z ) / vec.z;
    pos.copy( camera.position ).add( vec.multiplyScalar( distance ) );
    return pos;
}

public static async Get3DCoordinatesFromClick(GAME_CONTEXT:Game_Context, camera:THREE.PerspectiveCamera, click_position:THREE.Vector2):Promise<THREE.Vector3> {
    return new Promise((resolve, reject) => {
        var start = camera.position.clone();
        var collision_point:THREE.Vector3;
        var point3d = this.Get3DPoints(camera, click_position, 0);
        //console.log(click_position, " fp --->", point3d);
        new TWEEN.Tween(start).to({
            x:point3d.x,
            y:point3d.y,
            z:point3d.z
        }, 60).onUpdate(vector => {
            if (vector.x < 0 || vector.y < 0 || vector.x > GAME_CONTEXT.width || vector.y > GAME_CONTEXT.height) {
                var z = 0;
            } else {
                var z = GAME_CONTEXT.heights_map.GetValue(vector.x/GAME_CONTEXT.width, vector.y/GAME_CONTEXT.width);
            }
            if (!collision_point && vector.z <= z) {
                collision_point = vector.clone();
            }
        }).onComplete(vector => {
            //console.log(click_position, "--->", collision_point || vector);
            resolve(collision_point || vector);
        }).start();
    });
}

This generally works and gives me fairly accurate measurements, perhaps off by 1-4 real world units. And maybe I could improve it by finding the point of the ray right when its z equals the floor height.

But the main problem is I'm getting inconsistent values each time I click. I'm clicking in the exact same spot on the screen but the (x,y,z) coordinate changes by a little each time. It's not giving me the same value.

I'm suspecting this has to do with Tweening and putting a fixed 60millisecond duration for the ray travel.

Anyone know how to fix this?

about 4 years ago · Juan Pablo Isaza
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda