What is the process for converting NDC coordinates to camera space within a vertex shader?

I am currently maintaining a vertex shader contained within a custom material class (originally inherited from ShaderMaterial but now from MeshStandardMaterial) which converts 3D coordinates to Normalized Device Coordinates (NDC) as usual:

vec4 ndcPos = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
ndcPos /= ndcPos.w;
//...other transformations to ndcPos

Next, a series of transformations are applied to ndcPos. These transformations are carried out in NDC space. To return the resulting coordinate back to camera (eye) space, it appears that the steps need to be reversed, as shown below:

vec4 mvPos = ndcPos * ndcPos.w;
mvPos *= inverse of projectionMatrix;

Expected outcome: mvPos should only have the modelView transformation applied.

Queries:

  1. Is this approach correct?
  2. How can the inverse of projectionMatrix be computed? It would be convenient and efficient to pass camera.projectionMatrixInverse as a uniform to the vertex shader, but I have not been able to figure out a way to do so in three.js: neither through ancestor material classes, nor through onBeforeCompile which can access the camera.

Answer №1

To calculate the view space position in reverse, you can use the following operation:

vec4 p = inverse(projectionMatrix) * ndc;
vec4 mvPos = p / p.w;

Similarly, to determine the object position in reverse, you can use the following operation:

vec4 p = inverse(projectionMatrix * modelViewMatrix) * ndc;
vec4 pos = p / p.w;

(Please note that in the code above, pos represents the position attribute and mvPos represents position * modelViewMatrix.)

It is important to remember that when transforming a Cartesian coordinate with a perspective projection matrix, or its inverse, you will obtain a Homogeneous coordinate. To convert this back into a Cartesian coordinate, a Perspective Divide must be done (which sets the component w to 1 after the Divide).

Furthermore, please keep in mind that the inverse function is only available in GLSL ES 3.00 (WebGL 2.0) and not in GLSL ES 1.00 (WebGL 1.0). If needed, the inverse matrix can be calculated in Javascript and passed as a uniform variable to the shader.

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

The retrieval of data from AWS Dynamodb in Node.js is not done synchronously

I recently started working with Node.js and DynamoDB. I created a Node.js SDK to retrieve a single row from a DynamoDB table. The data is being fetched correctly, but there is a delay which is causing an error. Below is a snippet of my code: var AWS = re ...

Using Meteor package to efficiently import JSON arrays into mongoDB

I am currently working on developing a meteor package that will allow users to import JSON files into collections in a mongoDB. However, I'm uncertain about the feasibility of this task. The idea is for the user to upload a JSON file and specify the ...

"Enhance your Angular experience with SweetAlert integration using directives and translation

Currently, I am utilizing the Angular implementation of the SweetAlert plugin from GitHub. I am attempting to pass an Angular directive with translation to the title. The variable being passed as the title is: {{ 'register.confirmation_modal.SUPERI ...

Tips for identifying and logging out a dormant user from the server side using Angular 2 Meteor

I'm currently diving into Angular 2 Meteor and working on a project that requires logging out the user when they close their browser window. I also need them to be redirected to the login page when they reopen the app. After searching online, I could ...

Utilizing Flask to gather information from a leaflet map

I am currently working on creating a webpage using Flask. The webpage features a leaflet map where users can click to create a marker that opens a popup window with a link. The link's purpose is to open a new page displaying the longitude and latitude ...

Using THREE.js to shoot a ball with a curve on the X or Z axis

As a beginner in THREE.js and lacking knowledge in physics, my goal is to create a top-view football manager game with realistic ball movement. I have successfully made the ball move and rotate in the right direction, adjusting its path when it reaches bou ...

How can I animate SVG paths to fade in and out sequentially?

My current code is causing the path to fade in/out all at once instead of one after the other var periodClass = jQuery(this).parent().attr("class"); jQuery("svg path").each(function(i) { var elem = jQuery(this); if (elem.hasClass(periodClass)) ...

Converting JSON to PNG format using FabricJS

An image has been created and saved as fabricjs-json. Here is the link to the image: https://i.sstatic.net/7Wrhd.png Below is the json representation of the image: { "version": "5.2.1", "objects": [ { ...

Navigate to a specific hidden div that is initially invisible

Currently, I am working on a web chat application using next.js. The app includes an emoji picker button, which, when clicked, displays a menu of emojis. However, the issue I am facing is that the user has to scroll down in order to see the emoji menu. I a ...

Exploring Highcharts Pie Chart with AJAX for Real-time Data Updates

Looking for some guidance with implementing AJAX in my code to make my chart dynamic based on data from the database. Although the code is error-free, the chart is not refreshing automatically. Any help, comments, or suggestions would be greatly appreciate ...

Uploading files in AngularJS using Rails Paperclip

I have been working on implementing a file upload feature with AngularJS/Rails using the Paperclip gem. I was able to resolve the file input issue with a directive, but now I am facing an issue where the image data is not being sent along with other post d ...

Targeting an HTML form to the top frame

Currently, I have a homepage set up with two frames. (Yes, I am aware it's a frame and not an iFrame, but unfortunately, I cannot make any changes to it at this point, so I am in need of a solution for my question.) <frameset rows="130pt,*" frameb ...

What is the best way to achieve a Clamp-To-Border effect on a Texture loaded onto an Image in the THREE.js?

My scene includes a plane with an image loaded onto the texture. I've found that there is no Clamp-To-Border option for textures, only Clamp-To-Edge, Repeat Wrapping, and Mirrored Wrapping. Below is an image displaying the default ClampToEdge effect. ...

Leveraging Ajax to fetch JQuery

Currently, I am utilizing Ajax to trigger a PHP file for processing upon form submission. The JQuery form validation mechanism evaluates the variables' values to determine whether to proceed with submitting the form or to return false while displaying ...

Tips for accessing basic information from these websites without encountering CORS issues

Having issues retrieving data from the following two sites: and Eurolottery. The CORS issue is causing the problem, and I was able to retrieve data using a Chrome CORS extension and the provided code below: var HttpClient = function() { this.get = fu ...

Is the $http call for OPTIONS instead of POST?

Hey there, I'm encountering a strange issue while trying to call my backend using the POST method. Remote Address:192.168.58.183:80 Request URL:http://192.168.58.183/ESService/ESService.svc/CreateNewAccount Request Method:OPTIONS Status Code:405 Meth ...

Using React Material UI icon within an auto complete feature

https://i.stack.imgur.com/W3CmF.png I am struggling to incorporate the target icon into the autoComplete component. After reviewing the documentation, I have been unable to find a solution. In TextInput, a similar outcome can be achieved by implementing ...

steps for incorporating AngularJS code into a bootstrap modal within an asp.net core mvc application

I am encountering an issue with using AngularJS code inside a Bootstrap modal. I am loading the modal using jQuery code, and after loading it, I want to utilize Angular JS code to fetch and insert data. The Angular code works perfectly fine in a separate v ...

Avoid refreshing AJAX on browser back navigation

Describing my current situation: I have a scenario with 2 pages: - On page 1, it sends a request using $.ajax to receive JSON data for display. Then there is a button that when clicked, takes me to page 2. - After clicking the button and transitionin ...

Add the div id to the script

Currently, I have a script set up where by clicking on a specific div (for example id=packtoa), it will add a class 'show' to listview items that have a matching class with the clicked div's id. While this system works well, I find myself n ...