gusbeane / vortrace

Fast and exact projections through Voronoi meshes.
1 stars 0 forks source link

Add volume rendering #6

Open gusbeane opened 2 years ago

gusbeane commented 2 years ago

Not sure how to even start with this

gusbeane commented 2 years ago

From Matthew's email

Do you have anything you can point me to for the volume renderings? I'm not sure at all how this would be done.

Firstly, I think adding volume rendering is secondary to getting everything else in place. But I do think it would be a very attractive feature, it's something lots of people in medical and engineering imaging would expect for example. I’d be happy to take a look at adding this at a later date when I have spare time, in principle its just a small extension to the standard integration.

For an example on how volume renderings are used with astro sims in general, take a look at yt’s module. It only works for grid codes and it has way more features than I think we’d want to put in (at least at first). I’ve used it in the past with Arepo by interpolating cell data onto a cartesian unigrid first, but its a very slow way to do things.

But the yt docs don’t actually explain how to calculate the volume rendering. After a quick google, the intro to this master’s thesis gives a good summary: https://www.duo.uio.no/bitstream/handle/10852/9416/Fluor.pdf Take a look at section 2.2.3, either the front to back or back to front algorithms are what we would need (but note that it assumes regular, uniform sized voxels, we would need to renormalise by path length). Note that we can ignore all the stuff about gradient estimation, shading, illumination, interpolation etc. its not relevant to us.

Essentially, we need to have the user specify a transfer function which maps a cell quantity (e.g. density, temperature etc.) to a colour and opacity vector (R,G,B,alpha). We can provide some basic ones (e.g. place a gaussian in alpha at T = 1e6 K in the red channel, place a gaussian in alpha at T = 1e5 K in the green channel, place a gaussian in alpha at T = 1e4 K in the blue channel) but users can provide their own. This should all be in Python. Then the C++ integrator gets handed the (R,G,B,alpha) vector for each cell (instead of the usual density etc.). As we integrate along the ray, instead of just adding ds*rho to the result, cells contribute to the RGB channels and reduce the contribution from upstream, according to their opacity. Then the code returns an (R,G,B) for each pixel.