Search Unity

Question Is it possible to do proper Occlusion Culling at an angle?

Discussion in 'General Graphics' started by gxslim, Mar 30, 2023.

  1. gxslim

    gxslim

    Joined:
    Feb 10, 2013
    Posts:
    2
    I've been messing around with occlusion for hours now and I can't get it to behave the way I want.

    Essentially the issue is the visibility lines pass slightly through an occluder if the camera is facing it at most angles other than head-on.

    For example, in the image below, I've even added a solid cube (set to static) to try to fix this. As you can see, the visibility lines seem to go an arbitrary amount through the solid wall (as well as the actual walls im trying to use)

    (https://imgur.com/a/tEv7z4z)

    The goal is to get that crystal to occlude successfully, as I have game logic that will depend on discovering it for the first time, and I want the player to see what it is that's being discovered!

    I've tried using very small values when baking the occlusion map (this SS was from an attempt using 0.5 for the smallest occluder.)

    Would really appreciate help here.
     
  2. warthos3399

    warthos3399

    Joined:
    May 11, 2019
    Posts:
    1,758
    With Unity, Occlusion Culling has shot itself in the foot. Many posts about it over the years. I love Unity, but OC is a non-reliable system. At an angle?, Save yourself the headache, dont use OC...
     
  3. burningmime

    burningmime

    Joined:
    Jan 25, 2014
    Posts:
    845
    Trying to drive game logic via occlusion culling sounds like a minefield. Not sure if its behaviour is consistent accross al platforms or even dererministic, and it's not specced. Occlusion culling is for performance.

    If you really want to implement it based on what the player sees... so the easiest way would be raycasts. See if a ray from the camera intersects the bounding box of the crystal. If so (and crystal is close enough), cast a grid of rays (maybe 4x4 or something) at points from the camera's FOV, and see what they intersect. If any of them hit the cystal, the player has seen it. That's not completely robust, but it's maybe good enough.

    If you want to be more thorough or not all the occluders have colliders, then...

    1. Downsample depth buffer to a MUCH lower resolution. Example I wrote a few months ago which does that.
    2. Draw the object (or just its bounding box) to a new render target with the downsampled depth buffer (offset slightly so it doesn't intersect itself). Use a replacement shader that just draws a solid red color or something; keep it super simple. Use conservative raster on platforms that support it.
    3. Run a compute shader over this small render target to see if any of the pixels are red.
    4. Use AsyncGPUReadback and on the next frame, you'll find out if the player has seen it.

    ... BTW,
     
    Last edited: Mar 31, 2023
    ontrigger likes this.
  4. gxslim

    gxslim

    Joined:
    Feb 10, 2013
    Posts:
    2
    Thanks for the replies. After seeing a bunch of the other forum threads I was beginning to think OC was hopeless.

    I wanted to avoid the raycasting solution cause I wasn't sure immediately how to do it without trying to raycast every possible ray in the frustum which seems like it would make my pc explode. I think I'll try the grid of rays method.