Volume Refraction Shader (for a more physically-based way to do heat ripples and gravity wells)
Currently, the only way to create the distortions you would get from the heat of a fire or the gravity of a black hole is to fake it with a 2D distortion or with a flat refractive plane in front of the camera. The problem with this is that it is highly dependent on camera angle and makes it impossible for objects to interact with the distortion or pass through it. Also, it will not produce the caustics we would normally expect to see on objects around a heat source.
It would be really cool if there were a shader that could bend light based on a volume density, with rays skewing toward areas of high density and away from areas of low density or vice versa (this would, of course, require the existence of either negative density values or a "neutral" value greater than zero, since gases can be either more dense or less dense than air).
I can think of a few ways of doing this:
- The shader could use the density map to build contour surfaces of equal density, creating what is basically a series of refractive surfaces with varying IOR
- It could integrate curves through the material to map input points/angles on one surface to output points/angles on the other surfaces (this would require remapping to include interior surfaces if another object passed inside the volume)
- It could turn the variation ("slope") in density into a vector field, adding slight vector changes to the ray's path as it passes through, or
- It could periodically sample the ray's immediate surroundings, create a local vector in the direction of highest density, and add it to the ray's direction.
I'm sure there are other ways as well. That said, I know little enough about all of this that I have no idea if any of it would be feasible from a memory/computation standpoint. What are people's thoughts?
14 Comments
What cycles could do with is a render time isosurface generator which can key off volumetric texture data. Molecular modellers have been doing this for years to render molecular orbital isosurfaces from volumetric electron density data.
Once you have such an isosurface, you can (in theory) apply any shader to them since you now have volumetric surface normals. That would open up glossy as well as refractive volumetric materials.
Maybe somebody from the dev team can take a poke around in one of the opensource molecular modelling programs and see what is going on in terms of isosurface generation ;o)
ugovaretto.github.io/molekel/wiki/pmwiki.php/Main/DownloadBinary.html
sourceforge.net/p/avogadro/mailman/message/27991608/
It is physically correct but veeery expensive idea, that will require thousands of bounces or whole new way of ray-path. So not for a cycles, I think. Until it will have BiDir at least. Now it is much cheaper and faster to use fake planes
I wonder if you could use a cube with a glass shader and a noise texture subtly shifting the IOR off 0?
* @ammusionist * Can IOR be controlled in 3 dimensions, or is it a shader-wide property. In which case making it 3D would be a good approach for this possibly?
* @ammusionist * My understanding is that it can only be controlled in 2 dimensions (it's a surface property, not a volume property). That's what I would hope this new shader would fix.
* @ammusionist * Usually a plane, but that's a common trick yes: youtube.com/watch
This proposal could really use a mock-up. What would the 3D scene look like for such a set up? What about the node network for the material?
* @Jason van Gumster * Will do tonight.
* @Jason van Gumster * I didn't end up having time to work on it, and I can't say I understand the basic Material node well enough to know if this would work, but I was picturing a simple node with two inputs: "density" (like on the existing volume shaders, with the expectation that a 3D map of some kind would plug in there) and "IOR multiplier" (a single value that determines how strongly and in which direction the density is expressed in terms of how the light is bent). My expectation would then be that the output would plug into the Volume input on the Material node, but like I said, I don't know enough about how materials work to say whether or not that's feasible.
* @ludwa.borra * Refraction operates off of IoR and a normal, which isn't present in volumes. I would expect volumetric refraction to be based on a volume density map, which would define both the normal and the strength of refraction.
* @Jon Ross * Exactly what I was thinking! The strength would be based on the "slope" of the volume density map, with the normal pointing in the direction of greatest change. The multiplier would just be to define what those slope values mean in terms of the strength of the perceived refraction.
* @Jon Ross * There is a volume scatter node, which I would expect to be able to deflect light paths. I would imagine if you could use this with a Noise texture to very slightly deflect light as it passes through a volume it would do the trick (Anisotropy set to 1 for forward scatter). You could multiply the noise by a spherical blend to concentrate the noise over a "fire" object then multiply the result by say, 0.01 before feeding it to the Volume Scatter's Density.
I'm not near my home PC right now but does someone want to try this?
If it doesn't work, we could really use a volume IOR node!
* @ammusionist * But since the Volume Scatter node is designed to deflect evenly in all directions, wouldn't a high positive anisotropy basically just let light pass through without being deflected at all? I don't think there's a way to specify a direction of deflection.
* @ludwa.borra * Fair point, Perhaps using the noise to alter the aniosotropy, so it varies slightly below 1 and then a fairly low density would do the trick?