POV-Ray : Newsgroups : povray.general : 24 bit heightfields : Re: 24 bit heightfields Server Time
30 Jul 2024 20:19:30 EDT (-0400)
  Re: 24 bit heightfields  
From: clipka
Date: 12 Dec 2008 15:45:00
Message: <web.4942cc28869f689f7c822d860@news.povray.org>
"SharkD" <nomail@nomail> wrote:
> >     height = red + (green/256.0) + (blue/65536.0)
> >
> > with red, green, blue and height all ranging from 0.0 to 1.0.
>
> I don't quite understand your math. If red, green and blue all range from 0 to
> 1, then the maximum possible height is 3. The maximum height of heightfields is
> 1.

Red, green and blue are "misused" to encode one single higher-precision value.

The range of 0.0 to 1.0 which I presumed is just for convenience, because that's
PoV-ray's "native" range for colors, and is a very convenient range for heights
because it can easily be scaled to any other range you may need.

In the image, the red, green & blue channels each have a precision of 8 bit, so
the smallest step a single channel can encode is 1/256 of its total range.


Now if we used only a single channel (say red) to encode the height, we could
map it like this (note that this is just a convention, not a law):

    height = red

This would give us the same precision for the height as the red channel can
provide, i.e. smallest steps being 1/256 of the total range.

If we want to increase this, we can use the other channels to help us, e.g.:

    height = red + green + blue

In this way, our smallest step is 1/256 of a *single* channel's range, but as
the height will now - as you correctly observed - be in range 0.0 to 3.0, this
is actually 1/768 of the *height's* total range. So we have tripled the
height's precision.

This is, however, not the highest precision one can get out of 3*8 = 24 bits. In
fact, it should be possible to encode steps as small as 1/(2^24) of the total
range.

In fact, we can achieve that by using the green and blue component to encode
*smaller* steps than the red component (a kind of high-precision correction
terms), e.g.:

    height = red + 0.1 * green + 0.01 * blue

So although red, green and blue have a range of 0.0 to 1.0 each, the terms now
have a range of 0.0 to 1.0, 0.0 to 0.1 and 0.00 to 0.01 respectively, with
their smallest steps being 1/256 of the *term's* range, i.e. 1/256 for the "red
term", 0.1/256 for the "green term" and 0.01/256 for the "blue term".

So the height's range would now be in the range of 0.0 to 1.11 (quite similar to
the original range), but the smallest step would be 0.01/256, i.e. we have
hundredfold the precision of a single channel.

It turns out that the ideal factors for the single terms are powers of 1/256
(the smallest step representable by a single component), giving the term I
mentioned:

    height = red + green/256 + blue/65536

Well, actually I must confess that this is not *really* the ideal formula,
unless the range for red, green and blue isn't precisely 0.0 to 1.0, but 0/256
to 255/256 and the resulting range of the height would not be 0.0 to 1.0
either, but 0/(2^24) to (2^24-1)/(2^24); for the range 0.0 to 1.0 as actually
used by PoV-ray (if I'm not mistaken), the formula should be:

    height = ( (red*255) + (green*255)/256 + (blue*255)/65536 )/255


Post a reply to this message

Copyright 2003-2023 Persistence of Vision Raytracer Pty. Ltd.