Recently, over in povray.beta-test-binaries, I made a comment with
respect to the new method 3 AA mode (+am3) in v3.8 being better for
render to render results due being able to seed the random number
generator with that mode.
Kenneth asked for clarification and both of us tried multiple same scene
renders looking for differences due AA jitter being on. We saw none.
This led me to dig into the code earlier this week.
I long, and wrongly, thought AA methods 1 and 2 employed a random jitter
render to render. There is documentation which - to me - reads in a way
aligned with this belief:
has the following note:
"Note: The jittering noise is random and non-repeatable..."
For years I ran AA with -j to turn jitter off when I wanted
repeatability. In fact, I often run without AA so it doesn't hide
problems - and so AA jitter not in play.
Going back to at least v3.6 the jitter of AA modes 1 & 2 is exactly the
same render to render. Today it is only the new AA mode 3 which is truly
random render to render -unless the seed (+ss) is set by the user.
Prior to v3.7 and threading, there was a global variable continuously
incremented and added to each x then y as every pixel was traced. These
values were used as inputs to multiple hash indexing into a 256 entry
table of single float offsets. This was a decent method to visit all two
value pair possibilities in the table of 256 +-0.5 values.
With threading (v3.7+) there is no longer a global variable. Some change
was made to vary x and y inputs to the hashing, but I think these help
not all that much. I could ramble a while with details, but basically
this method less good at generating all the pair combinations -
especially when you look at small sub-windows of a larger render. In
fact, in sub windows of 50x50 pixels no jitter was as good or better in
AA at generating unique offsets.
I'll toss out too that at 300x300 windows, the jitter -- x,y
pairs/offsets generated are already less than 8% unique at super
sampling >4 / pixel.
I'd also long made a bad assumption that the jitter value was scaling
down only as the sub-pixels scaled down in the recursive methods 1 & 2.
What actually happens is the input jitter amount is scaled immediately
depending on the recursion depth (R) specified. The internal jitter
scaling values are the J columns below.
For example, when running +am2 +r3 +j1.0, the internal jitter scale is
0.111 * what comes out of the 256 entry jitter value table with max
values of +-0.5. So, we are getting a max jitter of only +-0.055 in that
case and all inside the pixel boundary.
The internal jitter scale is set for the smallest possible sub-pixel
(the largest recursion depth) whether or not that depth is necessary
given the threshold.
R am1 J am1 Jc am2 am2 Jc
1 1.00000 1.00000 0.33333 3.00000
2 0.50000 2.00000 0.20000 5.00000
3 0.33333 3.00000 0.11111 9.00000
4 0.25000 4.00000 0.05882 17.00000
5 0.20000 5.00000 0.03030 33.00000
6 0.16667 6.00000 0.01538 65.00000
7 0.14286 7.00000 0.00775 129.00000
8 0.12500 8.00000 0.00389 257.00000
9 0.11111 9.00000 0.00195 513.00000
The Jc column above is what the +j<value> would need to be to get a
constant jitter with respect to the pixel size with each recursion
depth. Today the jitter value is clamped to a 0.0 to 1.0 range, so
knowing larger values might be of use - is of no use.
What I've coded up now in povr is AA jitter defaulted off. This saves a
little time when using AA and in practice the jitter on in v3.7+ isn't
better anywhere that I've tested. It's different, so sometimes, yeah,
different will look better.
I've also removed the upper clamp on the jitter amount - it can now be
huge. Renders for 500+ values give a noisy effect, but an image that's
still pretty much what you'd expect due bouncing often outside each
Lastly, I've replaced the hash/jitter table with c++ random number
generators. Now with +j, I get random jittering and the x,y offsets in
that 300x300 test are 100% unique - but also now different render to
render like method 3.
Aside 1: The same 2d jitter code was used in the focal code so I created
a version just for focal blur leaving the behavior the same for now.
Though +j (or some other method) turning on focal blur jitter which is
more random probably worth doing.
Aside 2: In the focal blur code there are random number generators
perturbing the x,y inputs. This means the jitter with it more like what
the pre v3.7 AA jitter used to be - with respect to walking all the pair
possibilities in a way less clustered.
These asides lead me to mentioning other jitter methods in POV-Ray. I'm
only focused on the AA method 1 and 2 one herein.
Likely not 100% a complete list and perhaps my understanding of behavior
sometimes wrong too, but for v3.8 (povr):
(With jitter value >0)
AA method 1&2 jitter not random at all render to render(r-r).
AA method 3 random jitter (r-r) unless seeded.
Media jitter random (r-r).
Area lights jitter random (r-r).
Photons jitter random (r-r).
Rainbow jitter random (r-r).
Isosurface jitter random (r-r) (povr only).
Focal blur, as previously mentioned, internally uses random (r-r) jitter
into the 256 value jitter table which today is not user controllable,
but (r-r) differences likely hard to detect. A jitter enhancement here
allowing more user control might be useful, but it's not an option I use
Oh! I looked at one last thing - the +ag feature for AA. I have used it
in an old image with strong, narrow highlights. Otherwise, it doesn't
seem to do a lot - for my usually simple scenes in any case. In my tests
with simple scenes and hacking controls to get near the same number of
AA samples, I'd put the cost in the 4% range of the entire render cost.
It's not all that cheap. I wonder if tweaking the threshold - which
we've always been able to do - would not offer results as good at no
additional expense. Anyone have more experience with +ag settings other
than the default 2.5?
Post a reply to this message