obtaining the 2D coordinates of a point in 3D space using three.js

I'm currently exploring how to obtain the 2D screen coordinates for a 3D point.

Using three.js, I am creating snowflakes that gently descend on the screen. Initially, I created the animation using a 2D canvas and included mouse interaction to allow users to move the snowflakes around with their mouse. Everything was working fine until I switched to webgl, where the snowflakes were represented as 3D points. Calculating the distance of the mouse to each particle caused particles further from the center of the screen to behave unexpectedly due to the perspective.

Answer №1

To convert your worldPos vec3 to screen space, you first need to apply the viewProjection matrix and then perform the perspective divide. This will bring the coordinates to NDC space, where (-1,-1,x) represents the bottom left of the screen and (+1,+1,x) represents the upper right of the screen. Adjust these coordinates based on the screen width and height to obtain the final position in screen space.

Below is the code implementation for this process:

worldToScreen: function(viewProjectionMatrix, screenWidth, screenHeight){
    var m = viewProjectionMatrix;
    var w = m[3] * this[0] + m[7] * this[1] + m[11] * this[2] + m[15]; // Required for perspective divide
    this.transformByMat4(viewProjectionMatrix);
    if (w !== 0){ // Perform perspective divide and NDC -> screen conversion
        var invW = 1.0/w;
        this[0] = (this[0]*invW + 1) / 2 * screenWidth;
        this[1] = (1-this[1]*invW) / 2 * screenHeight; // Screen space Y goes from top to bottom
        this[2] *= invW;
    } 
    return this;
}

Essentially, this is the process that the GPU follows to render objects. You can also check the THREE Vector3 methods for an implementation or simply use the provided code snippet.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

When a cursor hovers over an image, a dark line appears

I wanted to create a hover effect where the image would enlarge when hovered over. I achieved this using a JavaScript function that applies the transform property with a scale of 1.2 to the picture. However, during the animation, a black line appears at th ...

Using SVG files in NextJS

I'm encountering an issue while trying to import an SVG file in a NextJS project. The error message I keep getting is: ./assets/aboutimg.svg 1:0 Module parse failed: Unexpected token (1:0) You may need an appropriate loader to handle this file type, ...

Guide to coloring a steep plane depending on its elevation by utilizing a vertex shader?

I created an airplane in THREEjs using Mesh, PlaneGeometry, and ShaderMaterial. It's a basic form that I made steeper by applying a simple formula. Now, my goal is to color the terrain based on its height using vertex shaders. Essentially, I want diff ...

Where am I going wrong in my attempts to use a callback function?

I am currently attempting to implement a callback function for this particular JavaScript function. function Filtering_GetSite(siteElement) { $.ajax({ type: "POST", url: "samle.asmx/f1", data: "", contentType: "application/json; charset= ...

I am experiencing difficulty with the color of my progress bar in Firefox

After successfully creating an interactive progress bar that works perfectly in Google Chrome and surprisingly also in Safari without vendor prefixes, I encountered a roadblock when testing it on Firefox. The progress bar color reverts back to the default ...

What are some effective strategies for reducing excessive re-rendering of React components?

Here is how I am displaying a list of components on the screen: const MessagesContainer = ({ messages, categories, addHandler }) => { const options = categories.map(category => ( { value: category.name, label: category.name } )); ...

I am attempting to implement an Express static middleware as demonstrated in this book, but I am having trouble understanding the intended purpose of the example

I'm currently studying a chapter in this book that talks about Express, specifically concerning the use of express.static to serve files. However, I'm encountering an issue where the code catches an error when no file is found. I've created ...

Trouble displaying Bar Graph in chart.js using PHP

I am facing a challenge with creating a bar graph using chart.js that loads data from a PHP array via ajax. The data is successfully loaded through ajax, as confirmed in the console, but I am unable to display it on the graph. Here's what I see in the ...

Instructions for adding and deleting input text boxes on an ASP.NET master page

*I am currently facing an issue with adding and removing input textboxes for a CV form using ASP.NET in a master page. Whenever I click on the icon, it doesn't seem to work as intended. The idea is to have a textbox and an icon "+" to add more textbox ...

Save essential data in local/session storage to have access to it even after the page is reloaded

Dear Team, we recently developed a single-page application that stores data in the root scope for access on other pages. While everything functions well in the regular flow, we encountered an issue with browser refresh. If a user refreshes the applicatio ...

Display user account balances in real-time on the web browser by retrieving data from a secure private Ethereum

I am seeking to create a website that can display real-time updates of a user's wealth from a private Ethereum blockchain. Ongoing Issue (buggy) Currently, I have attempted to connect to a private Ethereum blockchain that is mining using a WebSocket ...

Retrieve data that resets to undefined upon reloading from an array

Encountering an unusual error while working with TypeScript for the first time. Initially, when I use console.log(data), it displays an array with objects. However, upon reloading the webpage without making any changes, the console log shows undefined. con ...

Icon bar struggling to contain voluminous material card content

I've incorporated Material UI cards into my project and have an icon bar at the bottom of each card. However, the media within the card is overflowing onto the icon bar, causing a layout issue as illustrated in this screenshot: https://i.sstatic.net/ ...

What are the typical methods for implementing middleware in Node.js using the Express and Connect frameworks?

Exploring the proper way to utilize middlewares in a growing Node.js web project using Express and Connect. While there are middlewares that handle requests globally, there are often specific tasks such as processing incoming data that are only relevant t ...

Utilizing Angular routing in HTML5 mode within a Node.js environment

While I've come across other solutions to this problem, they all seem to have drawbacks. One option leads to a redirect, which could be disastrous for my front-end application that relies on Mixpanel. A double-load of Mixpanel results in a Maximum Ca ...

Is there a way to determine the dataType when an Array is converted into an ArrayBuffer?

I am dealing with an array: const dataArray = new Uint16Array(256); Later on, this array is transferred to another computer using nodeJs with the binaryType set to "arraybuffer". How can I determine on the receiving client whether to cast the array as U ...

Break up the JavaScript code into modules to avoid duplicating blocks of code detected by

There is a block of code that SONAR has identified as duplicate. I am looking for guidance on how to address this issue. import fields from '../../utils/utils'; dispatch( fields.change([ { id: 'userData', value: ...

Error message: "The term 'Outlet' is not recognized in react-router version 6.4"

What is the proper way to define the Outlet component in react-router version 6.4? Below is a code snippet: function Layout() { return ( <div> <Navbar /> <Outlet /> <Footer /> </div> ); } ...

Issue with alignment in the multiselect filter of a React data grid

In React Data Grid, there is a issue where selecting multiple filter options messes up the column headers. Is there a solution to display selected filter options above a line in a dropdown rather than adding them to the column header? The column header siz ...

Incorporating HTML content into a Vue component

I'm running into issues trying to display the content of an HTML file within a Vue component. Essentially, I have a Django backend that generates an HTML file using Bokeh and backtesting.py library. On the frontend side, I'm utilizing Nuxt/Vue, w ...