Search Unity

Better Visibility Testing using Raycasting and Projection to Screen Space

Discussion in 'Editor & General Support' started by jefft, Mar 14, 2012.

  1. jefft

    jefft

    Joined:
    Feb 20, 2012
    Posts:
    23
    I've been toying with ways to perform visibility testing. A simple view frustrum test doesn't count occluders, and raycasting can be very hit and miss (literally, depends whether you cast the ray at the right spot). I don't have Pro, so any technique using Umbra is probably out.

    My current theory is a recursive approach as follows (if testing visibility of object A):
    1. Project the bounding box of A onto a coarse grid in screen space.
    2. Convert the centre co-ordinates from screen space to a vector from the camera and raycast in this direction.
    3. If we hit A, break out. It is visible.
    4. Project the bounding box of occluder O onto the coarse grid in screen space.
    5. If all grid cells of A are fully covered by occluders, break out. It is not visible.
    6. Pick another area of the grid that has low coverage (how? area x coverage?)
    7. Go back to step 2.

    Obviously we need to end the recursion at some depth. Also subdividing the grid may be required.

    I think this approach would be quite efficient if either there are no occluders or a few large occluders cover A. Transparent objects with colliders might be a problem, possibly another layer could be used for that.

    Any thoughts on workability or efficiency of this approach?
     
  2. Arowx

    Arowx

    Joined:
    Nov 12, 2009
    Posts:
    8,194
    Use a halving method, e.g. sub divide your ray grid and repeat for each new sub grid depending on accuracy needed/range.
     
  3. jefft

    jefft

    Joined:
    Feb 20, 2012
    Posts:
    23
    I have thought of that, thanks. Do you think the projection approach may increase the speed/accuracy over a simple grid of raycasts?
     
  4. Arowx

    Arowx

    Joined:
    Nov 12, 2009
    Posts:
    8,194
    It really would depend on your games environment and camera view/type.

    I would think a voxel/grid system with pre-baked visibility based on camera frustum with the ability to tweak objects manually would work in most environments, but then your re-making Umbra.
     
  5. jefft

    jefft

    Joined:
    Feb 20, 2012
    Posts:
    23
    I think I'll try this the old fashioned way - timing tests for raycasts vs primitive scripting operations such as filling an array. Then I will have some idea whether proceeding can cause any gains.

    I have thought about a (much simpler) Umbra-like approach. The problem is that (a) a lot of wheel re-inventing would have to happen, as Unity doesn't seem to expose it's object model in a way conducive to building occlusion maps and (b) I don't know how I would re-bake it after editing the level unless I wrote an external tool that could somehow interact with Unity.
     
  6. Arowx

    Arowx

    Joined:
    Nov 12, 2009
    Posts:
    8,194
    You can code specifically to work within the Unity Editor.
     
  7. jefft

    jefft

    Joined:
    Feb 20, 2012
    Posts:
    23
    Thanks for the link, I'd forgotten that can be done!

    One of the issues that I referred to if taking an Umbra-like approach is that I'm not aware of a way to find what exactly a MeshCollider occludes without Pro. I think it could be done with Render to Texture, but I believe that's a Pro-only feature. Without that, it would seem that bounding boxes and raycasts are the only tool for dealing with this kind of occluder. Spheres, boxes and capsules could at least be projected to 2D based upon transform information.