Things That Don't Work

© Mike Williams 2002,2003,2004,2005

Up | Previous: Seashells | Next: Alphabetical Index

#declare Thing =
  difference {box {-1,1}
      sphere {0,1.2}

#declare P=function{pattern{object {Thing}}}

#include ""
  max_gradient 100
  contained_by {box{-1.1,1.1}} open
It might seem like there would be all sorts of interesting effects that could be achieved by using the "object" pattern.

function {pattern {object {My_Object}}}
is a function that returns the value 1 for all points that are inside My_Object and the value 0 for all points that are outside My_Object. So we might think that we could make an isosurface from that function and then modify it in interesting ways, for example by adding a noise function.

Unfortunately, any path through the isosurface encounters a point where the value jumps instantly from 0 to 1, so the actual max_gradient of every point on the surface is infinite. Instead of getting a few nasty little holes in our nice isosurface, we get a few tiny patches of surface and the rest is hole, unless very extreme values of max_gradient are used (and then it takes ages).

Also, the idea of adding noise to the surface doesn't work quite like what you'd intuitively expect. Adding a noise function to the object pattern function gives one region of space where the function evaluates to noise+1.0 and in the rest of space it evaluates to noise+0.0. One thing we could do is to apply a turbulence warp to the object pattern, but that's not so easy to control and still suffers from infinite max_gradient.

If you think about max_gradient for a while you might get the idea that something with a low max_gradient will always render faster than something with a higher max_gradient. If this were the case, then we could speed things up by artificially reducing the gradient of the function.

For example, if we consider

isosurface {
  function { 0.3 - F(x,y,z) }
        max_gradient 10
we might notice that we can obtain exactly the same surface by using

isosurface {
  function { (0.3 - F(x,y,z))*0.1 }
        max_gradient 1
or even

isosurface {
  function { (0.3 - F(x,y,z))*0.01 }
        max_gradient 0.1
These do in fact produce the same image when rendered. However, although the max_gradient is very different, the rendering times are exactly the same.
  You can't use vectors in an isosurface function.

You can't even extract float values from a vector by using things like

You can't index an array inside an isosurface function.

You can use individual fixed elements of an array, like A[3] but you can't use the function variables to index the array like A[floor(x)].

However, you can do this.

You can't pass function variables to a macro.

You can call a macro from inside an isosurface function, but it gets evaluated once, at parse time.

Don't get confused by the fact that you can use "x", "y" and "z" in your macro. "x", "y" and "z" have two different meanings in POV-Ray, and inside a macro they are always interpreted as having the other meaning: shortcuts for the unit vectors.

You can, however, use macros with Ingo's "" file, like this

Download a zip file containing the POV source files for all the images that appear on this page. (POV-ray 3.5 format only)

Up | Previous: Seashells | Next: Alphabetical Index