Occlusion Culling and me..

So. Generally I do well, i often struggle with new assets purely cos the guy showing them says click this, do that, and ive not even managed to click the first thing… and no matter how much screen space i have i need like 8 hands and 2 computers running one to run the video, and to halt, rewind, pause, etc… the others to do the unity/code editor potions… But…

Ive used occlusion culling before, Ive not had major issues but frankly I am questioning if 1+1=2 today.

See, see my complex scene setup

yes, 1 plane, 1 sphere, a light and a camera. Shocking isnt it

My occlusion settings


(and yes i baked)

TBH i feel like im at the stabbing in the dark stupid stage now so
the plane, light and camera, which dont move are all fully static
the plane has a navmesh and the navmesh is how the sphere moves
the sphere, which does move, is set as occluder and ocludee, why? cos well i thought ocludee but when it didnt work… maybe…

so

code wise? next to none

public class test : MonoBehaviour
{

    public bool CanSeeMe { get; private set; }
   
    private BehaviorTree behaviorTree;
    // Start is called once before the first execution of Update after the MonoBehaviour is created
    void Start()
    {
        behaviorTree = GetComponent<BehaviorTree>();
    }

    private void OnBecameVisible()
    {
        CanSeeMe = true;
        Debug.Log("Seen");
    }
    private void OnBecameInvisible()
    {
        CanSeeMe = false;
        Debug.Log("Not seen ");
    }
}

and while its not the behaviour tree code,

the stacked conditional is actually irrelevant - why, cos if the stupid variable was changing, it would work :stuck_out_tongue:
So
the CanSeeMe, (as the renderer.isvisible wasnt… and i couldnt track it as easily so made my own)

the insanely simple principle being.
wander, if wandered off screen as so not visible, return to 0,0,0 and try again.

Only problem is, the OnBecameInvisible never fires until the game ends… Now, I am aware that this can be effected by the scene camera (annoyingly) so, its pointed at the sky during play. So that should not be an issue

dynamic occlusion is on the sphere renderer and occlusion culling enabled on the camera.

So why then is my stupid dumb sphere not realising its not visible any more… the “visibility lines” very much confirm when its off screen it should be off screen… (but you cant look at those without using the scene camera … ARGH)

Ive really had enough of fighting the up hill battles

Oh i get that, but when the thing is like waaaaaaaay off screen, no, this doesnt explain it at all… its never counting as off screen

There’s a shadow-casting directional light in your scene.

If either the object casting the shadow or the object receiving the shadow (in this case, your plane) are visible, both will be rendered and hence, OnBecameInvisible will never be called for either.

Are you sure this is not the reason? because it damn sure looks like it… :roll_eyes:

when you change it so the ball goes off at -4, and at -24 your 1m ball and its possible respective shadow still says its visible… id say no.

Ok, but none of that matters… is the ground plane still visible?

Doesn’t matter whether the ball and its shadow are inside the camera’s frustum or far outside. If any object that would receive the ball’s shadow is rendered (even if its just a tiny little corner of it) then the ball will be considered visible. So if your ground is receiving the ball’s shadow - even if offscreen - and the ground is visible - even if just a pixel - then the ball is also considered visible. This is a basic consequence of how shadowmaps work.

Given that your ground plane seems huge and spans the entire screen, I’d say theres a pretty good chance this is the problem.

You can tell for sure using a simple test: disable your directional light. Does it now work as you were expecting it to? If so, shadows are indeed the culprit.

That sound crazy.
Hmm. I shall poke. Ive not had this issue previously but to be honest i used in short walls floor tiles ceiling tiles etc.

Hmm

Nothing crazy about it, it’s just how shadows work.

Try simply disabling the directional light. It takes less than 5 seconds to test whether this is the issue.

i disabled the light, and it didnt make a difference, disabling the shadows didnt really make a difference either… I then split the plane up into a butt load of little plane squares, it helped a bit, but still not quite the expected behaviour.

Just to make sure… there are other objects occluding the sphere, right?

I mean, if you only have the sphere and the ground and no other objects besides them that the sphere could hide behind of, how is occlusion culling supposed to do anything at all?

I’m starting to feel like you’re confusing occlusion culling with frustum culling. Frustum culling means objects completely outside the camera’s frustum (that is, things the camera is not directly looking at) are not drawn. This is always done by default, you don’t need to do anything special for it to work.

Occlusion culling means objects that are completely behind other objects aren’t drawn either. This requires a baking process to store visibility information.

Neither of these can be used to determine whether an object is visible to the player since they’re conservative: even if the object cannot be seen on screen, it may be rendered if needed for other effects (shadows, probes, reflections, etc). That’s why raycasts are generally used for visibility checks instead.

yes, by the sounds of it im using the wrong name… so how/why is frustrum culling not happening, how can i make it more reliable

as i understood it, the becamevisible/becameinvisible were an expected guaranteed event

Frustum culling is always applied. However, it only culls objects whose bounding box is completely outside of the camera, and that are not involved in any effect that would be visible on screen (shadows, realtime reflection/ambient probes, etc). The reason is simple: if you have an object that is not on screen but that would project a visible shadow, or would be reflected off another surface, or would bleed color on screen due to GI, etc… it still must be rendered, even if outside the camera’s frustum.

So if you’re using this to determine whether the player “sees” the object or not, I have bad news: you can’t.

You are much better off just using TestPlanesAABB to check yourself if the object is within the camera’s frustum planes, and raycasts to determine whether it is occluded by other objects.