Cycles: Add out of view dicing falloff and dicing camera
ClosedPublic

Authored by Mai Lavelle (maiself) on Oct 20 2017, 2:36 PM.

Details

Summary

Adds two separate settings: a selection for a camera to use to calculate subdivision from, which is important for animations to avoid crawling artifacts (and also useful for debugging), and a dicing rate falloff for objects out of view to reduce memory usage. I've included both as the dicing camera is a pretty simple addition, but more important is the UI might need reworking and having both together will make that easier.

@Ronny G (nutel) has done some testing of this already, he was able to render this scene in under ~5gb down from ~26gb by using the dicing falloff.

https://wiki.blender.org/index.php/File:Cycles_Displacement.jpg

The method of applying the falloff is a little weird, I tried several approaches and this worked best, but maybe someone can think of someway to make it better?

Diff Detail

Repository
rB Blender

here are the 2 images

falloff 0 > 64gb (swapped a little)

falloff 8 ~ 10gb of memory

This is great, I'll dig into the math later.

intern/cycles/blender/addon/properties.py
404–405

The range 0..25 is a bit odd, is there is an interpretation of this factor that users can understand, or can we normalize it to a 0..1 range somehow?

intern/cycles/blender/blender_camera.cpp
845–861

Can we deduplicate this code?

As I understand it the dicing falloff factor now depends on scene scale, and f_dist is a distance in scene units. If we normalize the p vector, then f_dist will be normalized to the range 0..1. Any point on the unit sphere will be at most 1 away from the camera position, going to 0 nearer to the frustum.

The factor can then be interpreted as a multiplier on the dicing rate, increasing from 1 inside the frustum to 1 + dicing_falloff_factor furthest away from the frustum. We could rename it to "Offscreen Dicing Scale" with range 1..inf, similar to how we have a dicing scale for individual objects. Does that make sense?

Two other notes (that shouldn't hold up this patch):

  • How valid is it really to use the perspective camera projection for points outside the frustum? It provides a smooth transition at the frustum edges, but the further you go away it doesn't seem so meaningful. A panorama camera projection may be better.
  • We may want to replace f_dist with some pow(f_dist, exponent) formula, in case linear falloff is not ideal. No idea if it actually would help, would need to be tested.
intern/cycles/render/camera.cpp
631

This can be initialized to 0.0, just to be safe. We should never end up below zero anyway.

Thinking about this further, I'm not entirely sure normalizing f_dist is ideal. If the camera is flying very close to some displaced objects, then you'd probably want geometry very close behind the camera to be tessellated almost as much as in front of the camera, to avoid popping? In that case "very close" depends on scene scale.

On the other hand, maybe it's not actually that different from a mountain far away casting sun shadows that pop. If we use normalization, then objects behind the camera appearing in a reflection would be tessellated with the same amount of faces, regardless if they are small and nearby, or large and far away. That makes some sense as well I think.

How valid is it really to use the perspective camera projection for points outside the frustum? It provides a smooth transition at the frustum edges, but the further you go away it doesn't seem so meaningful. A panorama camera projection may be better.

Its more about how FOV affects the size of micropolygons rather than any particular projection. Nothing would really change with a panoramic projection (you'd still need to calculate the angle a pixel represents). The original math in the perspective if block could probably be simplified to make this more clear tho.

We may want to replace f_dist with some pow(f_dist, exponent) formula, in case linear falloff is not ideal. No idea if it actually would help, would need to be tested.

I tried this, the results were not good. I found anything besides linear falloff produced either bad results, or was too unintuitive to control.

If we normalize the p vector...

Not really sure what you mean by this, doing so breaks all the math. Were you thinking of doing something entirely differnt?
__

I'm not really sure how to make any of this more intuitive unfortunately. The memory savings are quite good, but it shouldn't be confusing to users. Maybe some images of what the effect is on dicing is would help? Ill try putting something together later.

intern/cycles/blender/addon/properties.py
404–405

This is the best explanation I could come up with:

"Treat geometry out of view as if it were this many times farther that is actually is for the proposes of dicing (higher values have the effect of reducing quality of reflections and shadows for off screen objects, but can also save considerably on memory)"

The max of 25 is mostly arbitrary, but seemed to be the highest I could push it before tessellation patterns became chaotic due to abrupt change in dicing rates over the scene.

Its more about how FOV affects the size of micropolygons rather than any particular projection. Nothing would really change with a panoramic projection (you'd still need to calculate the angle a pixel represents). The original math in the perspective if block could probably be simplified to make this more clear tho.

With a smaller FOV, the entire scene will be subdivided more finely. For the part within the frustum it makes sense, since that part will appear bigger on screen. For parts far away from the frustum it doesn't seem helpful to me, and you'd get very different memory usage depending on the camera FOV. This can be manually compensated with the falloff, and animated FOV is not that common. But ideally I think parts of the scene (far) outside of the frustum should not be affected by FOV, instead some kind of spherical projection could be used.

Smaller FOVBigger FOV

I tried this, the results were not good. I found anything besides linear falloff produced either bad results, or was too unintuitive to control.

Fair enough.

Not really sure what you mean by this, doing so breaks all the math. Were you thinking of doing something entirely differnt?

Ok, I think I was mistaken and missed some terms cancelling out. It seems to render the same scene at the different scales with the same result, so that's great.

intern/cycles/blender/addon/properties.py
404–405

That's fine, that's a good explanation.

But then I think we should give it a 1..25 range, and use (dicing_falloff_factor - 1) in the code. Since 0.5 times farther would actually be closer, and that's not how it works now (and shouldn't of course).

Brecht Van Lommel (brecht) edited the summary of this revision. (Show Details)
  • Rename to Offscreen Dicing Scale, and set default to 4.0.
  • Remove ANIMATABLE from dicing camera, pointer properties do not support animation currently.
This revision is now accepted and ready to land.Fri, Jan 12, 1:33 AM
This revision was automatically updated to reflect the committed changes.