Convert 3d position to screen space (2D) position?

Hi! I need to project 3d position of a GameObject in scene to screenspace (canvas). I’m checking the camera component inside needle engine, but it doesn’t have a public way to acces the underlying three.js camera. Also it has a screenPointToRay function, but i think this would be an ideal place to add a function to do this.

So the question is, what is the needle way of projecting a 3D vector into a 2D one (that coincides with the canvas)?

Hello whtw4thewin! To convert a 3D position of a GameObject into screen space using Needle Engine, you’ll typically use the Three.js camera’s capabilities along with a bit of additional math to get the position in pixel coordinates.

Here’s a step-by-step approach to achieve this:

  1. Get the 3D position of the GameObject in world space.
  2. Use Three.js Camera to project the 3D position onto the 2D screen space.
  3. Convert the normalized device coordinates to pixel coordinates suitable for your canvas.

Here’s an implementation in Needle Engine using three.js to achieve the above:

import { Vector3, Vector2, Camera } from "@needle-tools/engine";

// Assuming 'camera' is the instance of your Needle Engine camera
function project3DTo2D(position3D, camera) {
    // Create a new Vector3 for the 3D position
    const vector = new Vector3(position3D.x, position3D.y, position3D.z);
    
    // Project the Vector3 using the camera
    vector.project(camera);

    // Convert normalized device coordinates to 2D screen coordinates
    const widthHalf = 0.5 * canvasWidth; // Assuming you have canvasWidth
    const heightHalf = 0.5 * canvasHeight; // Assuming you have canvasHeight

    const position2D = new Vector2();
    position2D.x = (vector.x * widthHalf) + widthHalf;
    position2D.y = -(vector.y * heightHalf) + heightHalf; // Y is inverted here

    return position2D; // Return 2D coordinates
}

Explanation:

  • The project method transforms the 3D coordinates into normalized device coordinates.
  • The subsequent calculation converts these normalized coordinates into pixel coordinates based on the canvas dimensions.
  • Remember to replace canvasWidth and canvasHeight with the actual dimensions of your canvas.

This method is the typical approach in Three.js and should work fine in your Needle Engine context.

If you need further clarification or have specific variables in your project to consider, feel free to share!

3 replies left
thread_WDzyOKpBToJTO05l4wqbdMDl
Reply to this message to continue the conversation

It does have sense, but how do i access to the underlying three.js camera from Needle engine, or a needle Engine component?

Hello whtw4thewin! In Needle Engine, while you may not have direct public access to the underlying Three.js camera, you can often access it through the Camera component associated with your Needle Engine GameObject.

Here’s how you can typically achieve that:

  1. Get the Camera Component: Use the getComponent method to obtain the camera instance on the GameObject.
  2. Access the Three.js Camera: The Needle Engine camera component wraps around the Three.js camera, allowing you to access its properties and methods.

Here’s an example code snippet:

import { Camera } from "@needle-tools/engine";

// Assume `gameObject` is the GameObject you are working with
const cameraComponent = gameObject.getComponent(Camera);

if (cameraComponent) {
    const threeCamera = cameraComponent.getCamera(); // This gets the underlying Three.js camera
    const position3D = new Vector3(1, 2, 3); // Example position to project
    const position2D = project3DTo2D(position3D, threeCamera);
    console.log("Screen Position:", position2D);
} else {
    console.error("Camera component not found.");
}

Explanation:

  • The gameObject.getComponent(Camera) retrieves the Needle Engine Camera component.
  • The getCamera() method will give you access to the actual Three.js camera you need for further operations.

If you have a specific GameObject or additional context you’re working with, let me know!

3 replies left
thread_WDzyOKpBToJTO05l4wqbdMDl
Reply to this message to continue the conversation

Hi, you can get the threejs camera from the Camera component via the cam property Camera | Needle Engine

Ahhh i missed that property, thanks!

I’ll mark the first answer as the solution since it is more suitable for the title of the question until i have a proper component to showcase :smiley:

1 Like

There is however another issue, how do i acces needle-canvas? I mean the actual canvas on html, not the canvas component (i assume that it refers to Unity-canvas implementation).

Edit: is it necessary to “manually” search for it on the DOM?

No there is no different implementation - Unity has nothing to do with this.

  • Get the <needle-engine> element via context.domElement
  • Get the threejs canvas via context.renderer.domElement

This topic was automatically closed 13 days after the last reply. New replies are no longer allowed.