Creating a stunning 2D image from a 3D scene through the power of raytracing with webgl and three.js

My goal is to project a 3D scene onto a 2D plane using ray tracing. Although my ultimate aim is volume rendering, I am currently struggling with the basics. I have set up a three.js scene with the viewing plane attached to the camera in front of it.

The Setup:

In the shader, a ray is shot from the camera through each point (250x250) on the plane. Behind the plane lies a cube volume of 41x41x41 dimensions. If a ray intersects the cube, the corresponding point on the viewing plane turns red; otherwise, it remains black. However, this method only works when looking at the cube from the front. An example can be viewed here:

If you try rotating the camera to view the cube from different angles, you will notice that instead of a proper cube projection, we get a square with some odd pixels on the side.

Raytracing Code:

Vertex Shader:

//Code for inside() function and getDensity() function

void main() {
    PointIntensity = getDensity(position);
    vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
    gl_Position = projectionMatrix * mvPosition;
}

Fragment Shader:

varying float PointIntensity;

void main() {
    //Red points for rays traversing the cube, black for empty space
    gl_FragColor= vec4(PointIntensity, 0.0, 0.0, 1.0);
}

Full Code: http://pastebin.com/4YmWL0u1

Running Code:

I would appreciate any tips on where I might have gone wrong with this approach.

EDIT:

I have made changes as suggested by Mark Lundin but still only see a red square when moving the camera (without the weird pixels). The update involved using the inverse of the projection matrix passed as a uniform to unproject the UV coordinates on the viewplane.

New code here: http://pastebin.com/Dxh5C9XX

Updated example running here:

You can press x, y, z to view the current camera coordinates and confirm the camera movement.

Answer №1

The reason you are only seeing a square instead of a 3D volume is due to the limitations in your current raytracing method. Your algorithm does not take into consideration the camera's orientation or projection, resulting in a flat representation of the scene. To rectify this issue, it is essential to incorporate the camera's orientation and projection matrix into your calculations.

vec3 unproject( vec2 coord ){
    vec4 screen = vec4( coord, 0, 1.0 );
    vec4 homogenous = uInvMVProjMatrix * 2.0 * ( screen - vec4( 0.5 )  );
    return homogenous.xyz / homogenous.w;
}

In the provided code snippet, the function unproject takes a 2D coordinate and uses the inverse model view projection matrix (uInvMVProjMatrix) to project the plane's coordinates into 3D space. The resulting vec3 can then be utilized for intersection testing purposes.

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 function res.sendFile() does not display files on the browser

For the past few days, I've been facing a challenge. Does anyone have any suggestions? When I click on a login button, I authenticate the user, generate a token, store it in cookies, and then use it in the headers of a request to display the homepage. ...

JavaScript Update Function for Pointers in Parse.com - Modify a Row with a Pointer

I am currently working with Parse and JavaScript. While I know the ObjectId from the Status_id-class, I am facing a challenge in updating the column in the Question_status-class due to it being of Pointer-type. Can anyone guide me on how to update a Poin ...

Can I specify which modal or component will appear when I click on a component?

Working on a small Angular 5 project, I have a simple component that represents a food product shown below: [![enter image description here][1]][1] This component is nested within my main component. When this component is clicked, a quantity component/m ...

Error message in the browser console: Uncaught TypeError - The function allSections.addEventListener is not recognized

Whenever I inspect my browser console, I keep encountering this error: Uncaught TypeError: allSections.addEventListener is not a function at PageTransitions (app.js:16:17) at app.js:33:1 I find it strange because my VS Code editor does not display any err ...

The model's function received the error message "Not a valid function."

My project involves NodeJS, Express, and Sequelize(mysql2)... I am encountering an issue where I keep receiving the error message "is not a function". I have created a model and defined a function in the model as shown below: module.exports = (sequelize, D ...

Secondary camera in THREE.js rotates in sync with head rotation in virtual reality

Combining THREE.js and Aframe (in Exokit) has led me to develop a unique "selfie camera" component. However, I've encountered an unusual issue where the camera rotation is affected by head rotation when entering VR mode. Although I am aware of the cha ...

Is there a way for me to programmatically modify a .env file using an npm script?

Currently, I'm managing a project with a .env file that contains confidential information. One of the key elements in this file is 'STATUS'. Just to clarify, this pertains to a Discord bot, The value assigned to the 'STATUS' var ...

How to make a JQuery list item unselectable when appending it

I encountered a strange issue while using jQuery to append items to a list. <ul id="idNicheItems" class="clScrollItems ui-widget-content ui-corner-all"> <li id="NicheItem_1"> Item 1</li> <li id="NicheItem_2"> Item 2</li& ...

Incorporating a new row in JQuery Datatable using an mdata array

I am currently using a datatable that retrieves its data through mData. var processURL="path" $.ajax( { type : "GET", url : processURL, cache : false, dataType : "json", success ...

Numerous Levels of Dropdown Menus

I am looking to implement a feature on a web page where users can select multiple vehicles using JQuery. The idea is that selecting the brand in the first dropdown will populate the second dropdown with the models available for that specific brand. The ...

How come my links aren't initiating jQuery click events?

Today, I decided to experiment with jQuery and encountered an issue. On my webpage, there are multiple links displayed in the format shown below: <a class="a_link" id="a_id<#>" href="#">Click me</a> The value <#> is a number gener ...

Discovering the amount of time a section of a webpage remains in view on a browser

I am looking for a way to track user engagement on my website that contains pages with extensive scrolling and numerous images. Each user who logs in sees a unique selection of images. My goal is to monitor how long users linger on each part of the page t ...

Transformation of CSS classes in React with Webpack

Have you ever noticed that when you inspect the Airbnb website, the classnames appear to be morphed into single alphanumeric names? What is the name of this technique and is it applied at the code level or build level? https://i.sstatic.net/qSiaj.jpg ...

"Error in react-three-fiber: Only the last mesh retains its model, all others are

Currently, I am working on a React application where I am using react-three-fiber to visualize data in a 3D environment. My goal is to create various models by passing data representing their characteristics as props into components. However, I am encounte ...

What is the best way to update object values only when changes occur, and leave the object unchanged if no changes

There is an object named ApiData1 containing key-value pairs, including color values within properties. The colors are updated based on the numberOfProjects value from ApiData2, with specific ranges dictating the color updates. This setup is functioning co ...

Trouble arises when adding a .js script to the webpage

I'm feeling quite puzzled by this small piece of code, as it appears to be the simplest thing you'll come across today. Despite that, I can't help but seek guidance because I've been staring at it for what feels like an eternity and can ...

Accessing a span element using an eval function

I have a function that accesses an input element and updates its value using the following line of code: eval('document.forms[0].telephone').value = $telephone[$i]; Now, I need to transfer this value to a span, but I'm having trouble refer ...

How can I include line breaks using HTML `<br>` tags in a textarea field that is filled with data from a MySQL

Within a modal, I am showcasing a log inside a read-only <textarea> field that contains data fetched from my MySQL database. Below this, there is a writable <textarea> field where users can input updates to the log, which are then added to the ...

Issue opening react modal dialogue box

I'm encountering an issue while trying to implement the headless ui modal. I'm attempting to trigger the modal.js script from my home.js file. In my home.js file, I have the following code snippet: function Home() { const [isOpen, setIsOpen] = ...

Exploring the functionality of dynamic component imports in jest testing

Under a specific condition, I dynamically imported a component and stored it in an object property. Then, I displayed it in the template using vue <component :is="">. Everything is functioning correctly at the component level. However, I am ...