Eyesplits

Application Note #33

November, 2002


1 Introduction

Sometimes, when rendering a scene with PRMan prior to release 11, it would print the following error message:

R56001 Primitive "%s" won't split at camera plane.

This means that a geometric primitive has a bounding box so large, that the renderer was not able to reduce the primitive to a reasonable size for dicing with a reasonable amount of splitting. The reason why this error is more common when placing the camera close to a ground plane is related to the perspective projection and the related bounding box of the primitive. Bounding boxes of objects that are motion blurring through the camera plane or that have large displacements bounds are even more likely to cause eyesplit problems. In versions of PRMan prior to release 11, the renderer would discard this primitive and then continue to render other primitives in the scene. In release 11, PRMan will now render the geometry but sometimes it can have potential shading artifacts. The motion-blurred image below illustrates the different eyesplits behavior between release 11 and previous releases.

Eyesplit problems prior to PRMan 11

Same RIB file rendered with PRMan 11
This application note will illustrate various situations which can cause eyesplit problems and will offer suggestions that can be used to alleviate eyesplit issues. In section 2 we discuss the basic eyesplit problem, where geometry straddles the eyeplane. In section 3, we show how to improve performance on objects with displacement bounds. In section 4, we discuss motion blur and we conclude in section 5 with a discussion of some advanced eyesplit options.


2 Eyesplit-itis: splitting too much

The key to avoiding eyesplit problems is understanding what conditions can cause them in the first place. The most common case is the one in which non-blurred, non-displaced geometry has a bounding box that straddles the eyeplane and the near clipping plane. An illustration of this is below.

Conditions that cause eyesplits
Because the perspective projection is ill defined at depth values equal to or less than zero, the code must modify the geometry so that the near plane of the bounding box is further than the eyeplane. To achieve this, the primitive will be split to create two pieces of geometry. In the case above, GPRIM-A will be near clipped and GPRIM-B will be projected into screen space.

There can be cases where splitting the geometry until the bounding box is in front of the eyeplane produces an unreasonable amount of geometry. Ten eyesplits will produce 2^10 pieces of geometry (and each of these pieces may need further splitting to reduce the geometry to a size reasonable for dicing). For this reason the default eyesplit limit in PRMan is set to 10, meaning the geometry will not eyesplit more than 10 times. If the geometry splits more than the eyesplit limit number of times, no more eyesplitting will occur and PRMan will try to dice the geometry.

2.1 Teapot Case Study

Below is an example rib file that produces bad eyesplit behavior.
   version 3.04
   Declare "resource" "string"
   Option "searchpath" "resource" [".:@"]
   FrameBegin 1
   Format 640 480 1
   Display "teapot" "framebuffer" "rgba"
   ## ---This is a really poor choice for the near clipping plane---
   Clipping .00001 10000
   Projection "perspective" "fov" [54.4322]
   ScreenWindow -1 1 -0.75 0.75
   WorldBegin
        ShadingRate 1
        ShadingInterpolation "smooth"
        AttributeBegin
                ## The teapot is really close to the eyeplane
                Translate 0 0 -8.99999
                Surface "randomgridsurf"
                ReadArchive "teapot-geom"
        AttributeEnd
   WorldEnd
   FrameEnd
Because the near clipping plane is very close to the eye, it is more difficult to split the geometry in such a way that the bounding box of the two split pieces end up either completely behind or in front of the eyeplane. The image below shows the large number of grids that result from this RIB file. If expensive shaders were attached to this object, a significant amount of time and memory would be expended trying to render this frame.

Example of a poor near clipping plane choice
If the composition of this frame requires such a close up, then we can reduce the amount of geometry generated by this scene by reducing the eyesplits limit. By adding the following line to the RIB file, we are telling PRMan to eyesplit the geometry less frequently:
   Option "limits" "eyesplits" [5]
Since we won't split the geometry 10 times, but only 5 times, we will generate fewer grids that need to be processed. The image below shows the result of using a limit of 5.

Example of poor clipping plane with eyesplit limit of 5
In the image above the grids are still somewhat long and radial because the near clipping plane is so close to the eye. In cases like these, the best way to alleviate eyesplits problems is to move the near clipping plane as far forward as possible. Using the example above, if we set the near clipping plane to a larger value, the resulting image would be black (because the teapot would be clipped). However, if we also move the teapot behind the near clipping plane, the resulting grids are much more reasonable in size and shape and no eyesplits issues arise. The RIB and image below illustrate this point.
   version 3.04
   Declare "resource" "string"
   Option "searchpath" "resource" [".:@"]
   FrameBegin 1
   Format 640 480 1
   Display "teapot" "framebuffer" "rgba"
   ## ---This is a really poor choice for the near clipping plane---
   Clipping 1 10000
   Projection "perspective" "fov" [54.4322]
   ScreenWindow -1 1 -0.75 0.75
   WorldBegin
        ShadingRate 1
        ShadingInterpolation "smooth"
        AttributeBegin
                ## The teapot is really close to the eyeplane
                Translate 0 0 -7.9
                Surface "randomgridsurf"
                ReadArchive "teapot.geom"
        AttributeEnd
   WorldEnd
   FrameEnd

Example of good near clipping plane

3 Eyesplits and displacements

Eyesplits problems can be compounded by large displacement bounds. If an object has a displacement bound that is twice as large as the bound of the undisplaced object, then no amount of splitting would generate a bounding box that would lie in front of the eyeplane. This problem can be avoided by keeping the displacement bounds of object very tight. The renderer will give warnings in the statistics about objects that do not use most of their displacement bounds, and the warnings can be used to reduce the bounds on objects that give problems. In release 11 of PRMan, the renderer can now render ground planes that have a fair amount of displacement, up through the eyeplane. The eyesplits limit can be used to help create images that look reasonable, and do not consume too much memory. The example RIB file and image below shows an example of this.
 version 3.04
 Declare "resource" "string"
 Option "searchpath" "resource" [".:@"]
 FrameBegin 1
 ## 10 is too high
 Option "limits" "eyesplits" [7]
 Attribute "displacementbound" "sphere" [.8] "coordinatesystem" "current"
 Format 640 480 1
 Display "displacement" "framebuffer" "rgba"
 Clipping .1 1000
 Projection "perspective" "fov" [54.4322]
 ScreenWindow -1 1 -0.75 0.75
 ConcatTransform [0.997801 0.00515556 -0.0660731 0 2.90359e-10 0.99697 0.0777918 
                  0 -0.0662739 0.0776207 -0.994778 0 0.394103 -0.690351 4.2613 1]
 WorldBegin
        ReverseOrientation
        ShadingRate 1
        ShadingInterpolation "smooth"
        Surface "randomgridsurf"
        AttributeBegin
                Attribute "identifier" "name" ["|nurbsPlane1|nurbsPlaneShape1"]
                ConcatTransform [1000 0 0 0 0 1 0 0 0 0 1000 0 0 .8 0 1]
                Opacity [1 1 1]
                Displacement "dispeye" "float kb" [.6] "float freq" [8]
                NuPatch 4 4 [0 0 0 0 1 1 1 1] 0 1 4 4 [0 0 0 0 1 1 1 1] 0 1 
                 "Pw" [-0.5 -3.06152e-17 0.5 1 -0.5 -1.02051e-17 0.166667 1 -0.5 1.02051e-17 
                       -0.166667 1 -0.5 3.06152e-17 -0.5 1 -0.166667 -3.06152e-17 0.5 1 -0.166667 
                       -1.02051e-17 0.166667 1 -0.166667 1.02051e-17 -0.166667 1 -0.166667 3.06152e-17 
                       -0.5 1 0.166667 -3.06152e-17 0.5 1 0.166667 -1.02051e-17 0.166667 1 0.166667
                       1.02051e-17 -0.166667 1 0.166667 3.06152e-17 -0.5 1 0.5 -3.06152e-17 0.5 1 
                       0.5 -1.02051e-17 0.166667 1 0.5 1.02051e-17 -0.166667 1 0.5 3.06152e-17 -0.5 1]
        AttributeEnd
 WorldEnd
 FrameEnd

Example of using eyesplits to render displacements
One should be careful not to set the eyesplit limit too low when working with displacements, because poor splitting can result in loss of quality in the image. The image below illustrates the problems that can occur if the eyesplits limit is set too low.

Example above with eyesplits limit of 3

4 Eyesplits and motion blur

Objects that motion blur through the eyeplane present one of the most difficult eyesplits situations. The bounds of an object that moves through the eye will never be reduced no matter how much splitting of the geometry occurs. The best way to avoid this problem is to simply avoid objects that fly through the eyeplane. However, if a scene absolutely calls for an object that flies through the eyeplane, lowering the eyesplits limit should produce an acceptable image.

The RIB and image below illustrate the new eyesplit behavior. In this scene, a sphere is translating through the eyeplane at a fairly high rate of speed. The image on the right shows the result with the default eyesplit limit of 10 (don't try this at home without a fair amount of memory) and with a limit of 4. The image with a limit of 4 renders 40 times faster than the limit of 10 and consumes 1/500th the amount of memory.

 version 3.04
 Declare "resource" "string"
 Option "searchpath" "resource" [".:@"]
 FrameBegin 1
 ## 10 is too high
 Option "limits" "eyesplits" [4]
 Format 640 480 1
 PixelSamples 17 17
 Shutter 0 1
 Display "motionblur" "framebuffer" "rgba"
 Clipping 1 10000
 Projection "perspective" "fov" [54.4322]
 ScreenWindow -1 1 -0.75 0.75
 WorldBegin
        ShadingRate 1
        ShadingInterpolation "smooth"
        AttributeBegin
                MotionBegin [0 1]
                  Translate 0 0 5
                  Translate 1 -1 -.1
                MotionEnd
                Surface "randomgridsurf"
                Sphere 1 -1 1 360
        AttributeEnd
 WorldEnd
 FrameEnd

Motion blur eyesplit problems with eyesplit limit of 10

Motion blur with eyesplit limit of 4
One caveat with motion blur, if the object moves too quickly through the eyeplane, often it will be clipped (because a long micropolygon might land mostly behind the eyeplane). If the object seems to disappear from the scene too quickly, the motion of the clipped object should be cheated to prevent the object from flying a long distance behind the eyeplane.


5 Advanced eyesplits options

There are two advanced eyesplit options that are normally best left untouched, but sometimes can help extreme situations. The first option is called gprimsplits. This option can be used to disable the new eyesplits behavior in release 11:
   Option "limits" "gprimsplits" [-1]
If this option is set to a positive value it controls how often a primitive will split after it has reached the eyesplits limit. Once an object reaches an eyesplit limit, the split criteria is no longer based on whether the bounding box is behind the eye, but on how large the bounding box is when projected into screen space. (Objects that have reach the eyesplits limit have a different criteria for projecting the object into screen space). Increasing this value beyond the default of 2 can yield better shading results for displacements that go through the eyeplane.

The other option is useful in the situation where an object seems to be splitting a lot, but not because of eyesplits, but instead because of "normal" splits. This case is rare, but it can happen. In this case, the follow option may help:

   Option "limits" "nearhither" [.01]
This option sets the distance from the eye that is actually used to determine if geometry is behind the eye. It is a ratio of the distance between the eye and the near clipping plane. A value of 0 would mean the eyeplane is used to determine when something eyesplits, and value of 1 means the near clipping plane would determine when something eyesplits. Normally a value near the eye is best. However if geometry is experiencing a large number of "normal" splits, setting this threshold higher can cause the geometry to "eyesplit". The advantage of having the geometry eyesplit is that the number of splits could then be controlled with the eyesplits limit attributes and options.