Volume ray tracing using three.js without textures - javascript

I'm trying to visualize hydrogen wave functions, and would like to do this using volume ray tracing/casting. All guides online for creating volume rendering is based on having 2D textures from some medical imaging. In my case, I don't have any data as images, but instead the 3D data is already in memory (I'm using them to generate particles right now).
Do I really need to convert all my 3D data to 2D textures, only to load them in again, and fake a 3D texture? If not, how can it be done without textures?

Yes, from your link I understand that you have a function that takes a 3D coordinate and returns a propability between 0 and 1. You can use this directly during the evaluation of each ray.
For each ray,
for each distance ∆ along the ray
calculate the coordinates at distance ∆ from the camera
calculate the propability at those coordinates using your function
add the probability to the ray's accumulated color
Using this method, you skip the particle positions that you have rendered in the linked example, and use the function directly.

Related

How to implement rolling a ball on a sphere in terms of matrices?

Target:
It is necessary to create two spheres, one of which can be rolled over the surface of the other with the mouse, and implement a camera that can be moved around these balls using the keyboard.
Implementation:
I started a matrix that stores the current state of the rotation of the rolling ball. When the user drags, I get a series of mouse move events, and each time I move, I calculate how many degrees around the current X and Y, as the user sees them, the rotation has changed. Then I calculate a matrix that represents these two rotations and multiply the original sphere rotation matrix by it in reverse order - the reverse order is necessary because the rotation occurs from the point of view of the camera, and not from the point of view of model space.
Problem:
But with such an implementation, the second sphere will not change the point of contact with the first sphere (it will, as it were, slide along it), how can one analytically implement the rotation of the point of contact of the balls in terms of matrices?
Here is the code if anyone is interested: https://github.com/AndrewStrizh/spheres-with-webGL
What you need is to be able to control rotation of your sphere around two (or more) different rotation pivots.
A proper way to deal with complex transformations is to implement hierarchical transformations:
http://web.cse.ohio-state.edu/~wang.3602/courses/cse3541-2019-fall/05-Hierarchical.pdf
In this case, you can control the rotation of the sphereB around the sphereA by making the sphereB a child of an third invisible object - call it Locator - located at the center of the sphereA. With proper implementation of hierarchical transformations, rotating the Locator will also rotate the sphereB around this Locator (so, around the sphereA). In the same time, you can also apply a rotation of the sphereB around its own center, making it spinning.
In practice, implementing true hierarchical transformations require to implement a scene graph, with proper nodes traversal, etc. But the main idea is that every object have what is called a local transform matrix, and world transform matrix. The local transform matrix hold only the own transformation of that particular object (locally to its own origin), while the world transform matrix is the final matrix, sum result of all the hierarchical transformations (from parents) applied to this object.
The world transform matrix is the one used as "model" matrix, to be multiplied with the view and projection matrices. World and local transform matrices of nodes are computed like this (pseudocode):
node.worldMatrix = node.localMatrix * node.parent.worldMatrix;
Knowing that, since you only need three objects and two hierarchical transformations, you don't have to implement a whole scene graph, you only need to simulate this principle by multiplying proper matrices to reproduce the desired behavior.

How do I make the Three.js camera look at the face of an object?

I'm have a sphere made of hexagons and pentagons and I am trying to make the camera look at a particular hexagon directly - so the centre of a user's view is the hex and it is flat.
The hexagons are made using the hexasphere.js plugin (https://github.com/arscan/hexasphere.js/tree/master). I am able to extract information from a mesh object which makes up a hex. But I don't know how to take the object info and tell the camera where to go.
I have tried using the normal matrix element of the mesh and finding the euler angles - but I don't know what to then do with them.
Ok, I've found a solution. The hexasphere plugin provides the centre point of a face with hexasphereObj.tiles[i].centrePoint which is a point object and this has a method project(radius, percent) which gets the coordinates of a point at a projection from the centre of the hexasphere and through the centre of the face.
I was then able to move the camera to this projected point and have it lookAt the centre of the hexasphere.

Best practice: Rendering volume (voxel) based data in WebGL

I´m searching for a (or more) best practice(s) for the following problem. I´ll try to describe it as abstract as possible, so the solution can be applied to scenarios i have not yet thought of.
Data available: Voxels (Volumetric Pixels), forming a cube, with coordinates x,y,z and a color attached.
Goal: Use OpenGL to display this data, as you move through it from different sides.
Question: Whats the best practice to render those voxels, depending on the viewpoint? How (which type of Object) can store the data?
Consider the following:
The cube of data can be considered as z layers of x y data. It should
be possible to view, in-between-layers, then the displayed color
should be interpolated from the closest matching voxels.
For my application, i have data sets of (x,y,z)=(512,512,128) and
more, containing medical data (scans of hearts, brains, ...).
What i´ve tried so far:
Evaluated different frameworks (PIXI.js, three.js) and worked through a few WebGL tutorials.
If something is not yet clear enough, please ask.
There are 2 major ways to represent / render 3D datasets. Rasterization and Ray-tracing.
One fair rasterization approach is a surface reconstruction technique by the use of algorithms such as Marching Cubes, Dual Contouring or Dual Marching Cubes.
Three.js have a Marching Cubes implementation in the examples section. You basically create polygons from your voxels for classical rasterization. It may be faster than it seems. Depending the level of detail you want to reach, the process can be fast enough to be done more than 60 times per second, for thousands of vertices.
Although, unless you want to simply represent cubes (I doubt) instead of a surface, you will also need more info associated to each of your voxels rather than only voxel positions and colors.
The other way is raycasting. Unless you find a really efficient raycasting algorithm, you will have serious performance hit with a naive implementation.
You can try to cast rays from your camera position through your data structure, find / stop marching through when you reach a surface and project your intersection point back to screen space with the desired color.
You may draw the resulting pixel in a texture buffer to map it on a full-screen quad with a simple shader.
In both cases, you need more information than just colors and cubes. For example, you need at least density values at each corners of your voxels for Marching cubes or intersection normals along voxels edges (hermite data) for Dual Contouring.
The same for ray-casting, you need at least some density information to figure out where the surface lies or not.
One of the keys is also in how you organize the data in your structure specially for out-of-core accesses.

Use 3d model as icon without scaling in Google Earth Plugin

There're two types of objects we can place on the google earth.
The first one is 3d models - they have real size and they scale with dependency on the camera position.
The second one is icons and labels - they overlay the map and do not scale while the camera moves.
So is there a possibility to use 3d models like icons? That means I want to switch my png-icons with beauty 3d-models that do not scale and that have icon's behavior.
I know that there's access to the camera and object positions, and we can rescale 3d object with dependency on the distance every time when the camera or an object moves, but I believe there's simpler way without all these calculations and observables.
I would say no, there is no simple way to achieve this.
As you say, an icon doesn't have any geometry other than a location, but a 3D model is specifically defined by its location and its length, width, height, etc. Yes you could calculate the scaling and attempt to redraw the model based on the current view, but that wouldn't be trivial and I really doubt that the results would be very pleasing.

Get the image of an element that gets drawn in the three.js while rendering

Well the way I think three.js handles the render is that it turns each element into an image and then draws it on a context.
where can I get more information on that.
and if I am right, is there a way to get that image, and manipulate it?
any information will be appreciated.
Three.js internally has a description of what the scene looks like in 3D space, including all the vertices and materials among other things. The rendering process takes that 3D representation and projects it into a 2D space. Three.js has several renderers, including WebGLRenderer (the most common), CanvasRenderer, and CSS3DRenderer. They all use different methods to draw that 2D projection:
WebGLRenderer uses JavaScript APIs that map to OpenGL graphics commands. As much as possible, the client's GPU takes parts of the 3D representation and more or less performs the 2D projection itself. As each geometry is rendered, it is painted onto a buffer. The complete buffer is a frame, which is the complete 2D projection of the 3D space that shows up in your <canvas>.
CanvasRenderer uses JavaScript APIs for 2D drawing. It does the 2D projection internally (which is slower) but otherwise works similarly to the WebGLRenderer at a high level.
CSS3DRenderer uses DOM elements and CSS3D transforms to represent the 3D scene. This roughly means that the browser takes normal 2D DOM elements and transforms them into 3D space to match the Three.js 3D internal representation, then projects them back onto the page in 2D.
(All this is highly simplified.)
It's important to understand that the frame rendered WebGL and Canvas representations is the resulting picture that you see on your screen, but it's not an <img>. Typically, your browser will render 60 frames per second. You can extract a frame by dumping the <canvas> into an image. Typically you'll want to stop the animation loop in order to do this as otherwise you might not be capturing the frame you want. Capturing frames this way is slow and given that your browser is rendering so many frames per second there are not easy ways to capture every frame.
Additionally, Chrome has built-in canvas inspection tools which allow you to take a closer look at each frame the browser paints.
You can't easily intercept the buffer as Three.js is rendering the frame, but you can draw directly onto the canvas as you normally would. renderer.context is the graphics context that Three.js draws onto, where renderer is the Renderer instance you create when setting up a Three.js scene. (A graphics context is basically a helper to assemble the buffer that makes up the frame.)

Categories

Resources