Otherwise known as a phase function, this determines in which directions
the light is scattered in the volume. Until now it's been isotropic
scattering, meaning that the light gets scattered equally in all
directions. This adds some new types for anisotropic scattering, to
scatter light more forwards or backwards towards the viewing direction,
which can be more similar to how light is scattered by particles in nature.
Here's a diagram of how light is scattered isotropically and anisotropically:
http://mke3.net/blender/devel/rendering/volumetrics/phase_diagram.png
The new additions are:
- Rayleigh
describes scattering by very small particles in the atmosphere.
- Mie Hazy / Mie Murky
more generalised, describes scattering from large particle sizes.
- Henyey-Greenstein
a very flexible formula, that can be used to simulate a wide range of
scattering. It uses an additional 'Asymmetry' slider, ranging from -1.0
(backward scattering) to 1.0 (forward scattering) to control the
direction of scattering.
- Schlick
an approximation of Henyey-Greenstein, working similarly but faster.
And a description of how they look visually (just an omnidirectional lamp
inside a volume box)
http://mke3.net/blender/devel/rendering/volumetrics/phasefunctions.jpg
* Sun/sky integration
Volumes now correctly render in front of the new physical sky. Atmosphere
still doesn't work correctly with volumes, due to something that i hope
can be fixed in the atmosphere rendering, but the sky looks quite good.
http://mke3.net/blender/devel/rendering/volumetrics/sky_clouds.png
This also works very nicely with the anisotropic scattering, giving
clouds their signature bright halos when the sun is behind them:
http://mke3.net/blender/devel/rendering/volumetrics/phase_cloud.mov
in comparison here's a render with isotropic scattering:
http://mke3.net/blender/devel/rendering/volumetrics/phase_cloud_isotropic.png
* Added back the max volume depth tracing limit, as a hard coded value -
fixes crashes with weird geometry, like the overlapping faces around
suzanne's eyes. As a general note, it's always best to use volume
materials on airtight geometry, without intersecting or overlapping faces.
the emission component by the density at the current point, which
made the volume too bright in less dense areas. This made it look
too rough, as opposed to smooth as it should be. This makes the
particle rendering look *much* better, thanks a bunch to ZanQdo for
complaining and kicking my butt to make me realise the error.
Here's an example of how smooth it looks now:
http://mke3.net/blender/devel/rendering/volumetrics/smoke_test03.movhttp://mke3.net/blender/devel/rendering/volumetrics/smoke_test03.blend
Settings in existing files will have to be tweaked a bit, since
what they were set up for before, was incorrect.
* Added two new interpolation types to Point Density: Constant and
Root. These work similarly to in proportional edit for example,
just gives a bit more choice over how hard-edged the particles
should look.
Replaced the previous KD-tree (for caching points) with a
BVH-tree (thanks to Andre 'jaguarandi' Pinto for help here!).
The bvh is quite a bit faster and doesn't suffer some of the
artifacts that were apparent with the kd-tree.
I've also added a choice of falloff types: Standard, Smooth, and
Sharp. Standard gives a harder edge, easier to see individual
particles, and when used with a larger radius, Smooth and Sharp
falloffs make a much cloudier appearance possible. See the image
below (note the settings and render times too)
http://mke3.net/blender/devel/rendering/volumetrics/pointdensity_bvh.jpg
limit ray intersections like as for ray transparency). It
remains to be seen if it's even that useful, and was
preventing refracting materials behind volumes from
working easily.
SunSky didn't include skycolor in raytrace.
Note: there seems to be an error in sunsky when looking straight down,
so this option requires raytracing stuff not in outer space. :)
* subsurf code had a lot of unused variables, removed these where they are obviously not needed. commented if they could be useful later.
* some variables declorations hide existing variables (many of these left), but fixed some that could cause confusion.
* removed unused vars
* obscure python memory leak with colorband.
* make_sample_tables had a loop running wasnt used.
* if 0'd functions in arithb.c that are not used yet.
* made many functions static
- removed ugly clamping function (it was dividing XYZ based on max of
one of the values)
- added option to use Exposure, this only works for brightness (Y).
results look very pleasant, foggy and hazy results are possible.
with exposre==0, no exposure happens for HDR extreme range skies,
this is how yafray rendered it.
- added menu for choosing color spaces (CIE = modern lcds)
Please review! (and yes i know it's still not in World :)
The Point Density texture now has some additional options for how
the point locations are cached. Previously it was all relative to
worldspace, but there are now some other options that make things
a lot more convenient for mapping the texture to Local (or Orco).
Thanks to theeth for helping with the space conversions!
The new Object space options allow this sort of thing to be possible
- a particle system, instanced on a transformed renderable object:
http://mke3.net/blender/devel/rendering/volumetrics/pd_objectspace.mov
It's also a lot easier to use multiple instances, just duplicate
the renderable objects and move them around.
The new particle cache options are:
* Emit Object space
This caches the particles relative to the emitter object's
coordinate space (i.e. relative to the emitter's object center).
This makes it possible to map the Texture to Local or Orco
easily, so you can easily move, rotate or scale the rendering
object that has the Point Density texture. It's relative to the
emitter's location, rotation and scale, so if the object you're
rendering the texture on is aligned differently to the emitter,
the results will be rotated etc.
* Emit Object Location
This offsets the particles to the emitter object's location in 3D
space. It's similar to Emit Object Space, however the emitter
object's rotation and scale are ignored. This is probably the
easiest to use, since you don't need to worry about the rotation
and scale of the emitter object (just the rendered object), so
it's the default.
* Global Space
This is the same as previously, the particles are cached in global space, so to use this effectively you'll need to map the texture to Global, and have the rendered object in the right global location.
Removed all the old particle rendering code and options I had in there
before, in order to make way for...
A new procedural texture: 'Point Density'
Point Density is a 3d texture that find the density of a group of 'points'
in space and returns that in the texture as an intensity value. Right now,
its at an early stage and it's only enabled for particles, but it would be
cool to extend it later for things like object vertices, or point cache
files from disk - i.e. to import point cloud data into Blender for
rendering volumetrically.
Currently there are just options for an Object and its particle system
number, this is the particle system that will get cached before rendering,
and then used for the texture's density estimation.
It works totally consistent with as any other procedural texture, so
previously where I've mapped a clouds texture to volume density to make
some of those test renders, now I just map a point density texture to
volume density.
Here's a version of the same particle smoke test file from before, updated
to use the point density texture instead:
http://mke3.net/blender/devel/rendering/volumetrics/smoke_test02.blend
There are a few cool things about implementing this as a texture:
- The one texture (and cache) can be instanced across many different
materials:
http://mke3.net/blender/devel/rendering/volumetrics/pointdensity_instanced.png
This means you can calculate and bake one particle system, but render it
multiple times across the scene, with different material settings, at no
extra memory cost.
Right now, the particles are cached in world space, so you have to map it
globally, and if you want it offset, you have to do it in the material (as
in the file above). I plan to add an option to bake in local space, so you
can just map the texture to local and it just works.
- It also works for solid surfaces too, it just gets the density at that
particular point on the surface, eg:
http://mke3.net/blender/devel/rendering/volumetrics/pointdensity_solid.mov
- You can map it to whatever you want, not only density but the various
emissions and colours as well. I'd like to investigate using the other
outputs in the texture too (like the RGB or normal outputs), perhaps with
options to colour by particle age, generating normals for making particle
'dents' in a surface, whatever!
sure if this is 'correct' but so far in testing it's been working
pretty well.
This also exposes a new 'Nearest' value, to determine how many
nearby particles are taken into account when determining density.
A greater number is more accurate, but slower.
Initial commit for supporting rendering particles directly as
volume density. It works by looking up how many particles are
within a specified radius of the currently shaded point and using
that to calculate density (which is used just as any other
measure of density would be).
http://mke3.net/blender/devel/rendering/volumetrics/smoke_test01.mov
http://mke3.net/blender/devel/rendering/volumetrics/smoke_test01.blend
Right now it's an early implementation, just to see that it can
work - it may end up changing quite a bit. Currently, it's just a
single switch on the volume material - it looks up all particles
in the scene for density at the current shaded point in world
space (so the volume region must enclose the particles in order
to render them.
This will probably change - one idea I have is to make the
particle density estimation a procedural texture with options for:
* the object and particle system to use
* the origin of the co-ordinate system, i.e. object center, world
space, etc.
This would allow you in a sense, to instance particle systems for
render - you only need to bake one particle system, but you can
render it anywhere.
Anyway, plenty of work to do here, firstly on getting a nice
density evaluation with falloff etc...
solids, in front of other volumes, etc. Now there's a 'layer depth'
value that works similarly to refraction depth - a limit for how many
times the view ray will penetrate different volumetric surfaces.
I have it close to being able to return alpha, but it's still not 100%
correct and needs a bit more work. Going to sit on this for a while.
* Now it's possible to render with the camera inside a volume. I'm not sure how this goes with overlapping volumes yet, will look at it. But it allows nice things like this :)
http://mke3.net/blender/devel/rendering/volumetrics/clouds_sky.mov
* Sped up shading significantly by not doing any shading if the density
of the current sample is less than 0.01 (there's nothing to shade there anyway!) Speeds up around 200% on that clouds scene.
* Fixed a bug in global texture coordinates for volume textures
Now other objects (and sky) correctly render if they're partially
inside or behind a volume. Previously all other objects were ignored,
and volumes just rendered on black. The colour of surfaces inside or
behind the volume gets correctly attenuated by the density of the
volume in between - i.e. thicker volumes will block the light coming
from behind. However, other solid objects don't receive volume shadows
yet, this is to be worked on later.
http://mke3.net/blender/devel/rendering/volumetrics/vol_inside_behind.png
Currently this uses raytracing to find intersections within the volume,
and rays are also traced from the volume, heading behind into the
scene, to see what's behind it (similar effect to ray transp with IOR
1). Because of this, objects inside or behind the volume will not be
antialiased. Perhaps I can come up with a solution for this, but until
then, for antialiasing, you can turn on Full OSA (warning, this will
incur a slowdown). Of course you can always avoid this by rendering
volumes on a separate renderlayer, and compositing in post, too.
Another idea I've started thinking about is to calculate an alpha
value, then use ztransp to overlay on top of other objects. This won't
accurately attenuate and absorb light coming from objects behind the
volume, but for some situations it may be fine, and faster too.
Rather than a single absorption value to control how much light is absorbed as it
travels through a volume, there's now an additional absorption colour. This is
used to absorb different R/G/B components of light at different amounts. For
example, if a white light shines on a volume which absorbs green and blue
components, the volume will appear red.
To make it easier to use, the colour set in the UI is actually the inverse of the
absorption colour, so the colour you set is the colour that the volume will
appear as.
Here's an example of how it works:
http://mke3.net/blender/devel/rendering/volumetrics/vol_col_absorption.jpg
And this can be textured too:
http://mke3.net/blender/devel/rendering/volumetrics/vol_absorb_textured.png
Keep in mind, this doesn't use accurate spectral light wavelength mixing (just
R/G/B channels) so in cases where the absorption colour is fully red green or
blue, you'll get non-physical results.
Todo: refactor the volume texturing internal interface...
- Fixed a shading bug, due to issues in the raytrace engine where it would ignore
intersections from the starting face (as it should). Disabled this for single
scattering intersections, thanks to Brecht for a hint there. It still shows a
little bit of noise, I think due to raytrace inaccuracy, which will have to be
fixed up later.
before: http://mke3.net/blender/devel/rendering/volumetrics/vol_shaded_old.png
after: http://mke3.net/blender/devel/rendering/volumetrics/vol_shaded_correct.png
Now single scatttering shading works very nicely and is capable of things like this:
http://mke3.net/blender/devel/rendering/volumetrics/vol_shaded_clouds.mov
- Added colour emission. Now as well as the overall 'Emit:' slider to control
overall emission strength, there's also a colour swatch for the volume to emit
that colour. This can also be textured, using 'Emit Col' in the map to panel.
This animation was made using a clouds texture, with colour band, mapped to both
emit colour and emit (strength):
http://mke3.net/blender/devel/rendering/volumetrics/vol_col_emit.mov
- Added 'Local' mapping to 'map input' - it's similar to Orco
- Fixed texture 'map input', wasn't using the offsets or scale values.
Zbuffer error in render: when you render faces clipped by 'clip end' the
z values could wrap around, resulting in errors. Code not nicely clamps,
plus should be faster even!
This is an initial commit to get it in SVN and make it easier to work on.
Don't expect it to work perfectly, it's still in development and there's
plenty of work still needing to be done. And so no I'm not very interested
in hearing bug reports or feature requests at this stage :)
There's some info on this, and a todo list at:
http://mke3.net/weblog/volume-rendering/
Right now I'm trying to focus on getting shading working correctly (there's
currently a problem in which 'surfaces' of the volume facing towards or away
from light sources are getting shaded differently to how they should be),
then I'll work on integration issues, like taking materials behind the volume
into account, blending with alpha, etc. You can do simple testing though,
mapping textures to density or emission on a cube with volume material.
- Added blending mode and factor option, so it's more clear and
controllable what happens with it. Also nice for crazy effects
of course!
- Preview render now shows preview for it too
On the todos:
- have this in World buttons (as well) for quicker sky setups
- review math of color clamping and scaling, this is definitely
not good... but a fix will make old files look very different.
- Changed order for applying atmosphere, it does it now before alpha-adding
sky, giving correct transparency
- Added correction for de-premulling and premulling scatter color
Commit patch #7788, allow to set the render step, so it's
possible make render every N frames only.
The step is change in Scene buttons (F10), below start and
end frame buttons.
Also add a command line options (-j), so it's possible to
overwrite the file step (useful for renderfarm).
[ Brecht, this work with OpenGL renders and simulated
the skipped frames, please double check ]
Finally, after a long time new render candy for the non-game peoples! :)
Good doc is here: (url splits in two)
http://www.harkyman.com/2008/08/06/controllable-shadow-intensity-
and-color/
Note the colorpicker for shadow is in "Shadow and Spot" panel. A bit
hidden, could get more attention. For later. :)
not give a smooth fallof. there's no correct fix possible due
to a lack of information, but this manually adds a smoother
falloff, overestimating the contribution of foregroud pixels
instead of becoming transparent.
halo material attach to the object instead of the mesh.
Also for bug #13489: avoid a crash rendering with invalid
active vcol layer, most likely caused by a bug that was
already fixed.