x


Disable Frustum Culling?

Is there a way to disable frustum culling on specific objects? Or perhaps disable it entirely?

I'm displacing the vertices in my mesh in a vertex shader. They are displaced to the extent that the original mesh (on the CPU side) is out of the view frustum, whereas the displaced vertices (on the GPU side) ARE in the view frustum. This causes the mesh to suddenly stop rendering and disappear, which is obviously not the desired behavior.

I tried solving this by overriding the OnBecameInvisible() method and forcing the renderer to be enabled, but that did nothing. (I had thought that the frustum culling disabled the renderer, but that is not the case.)

I wish the isVisible field on the renderer was able to be set. I feel that would solve this issue. Any other ideas?

Update: I thought about forcing the bounds on the renderer to be the same size as the maximum displacement, but the bounds property is read-only too.

I then tried having a second camera in the scene that is static and moved back enough to always have the displaced mesh in view, but that didn't work either. Apparently each camera does it's own frustum culling, which makes sense.

more ▼

asked Dec 02 at 10:46 PM

GlitchEnzo\'s gravatar image

Patrick McCarthy
230 3 4 14

(comments are locked)
10|3000 characters needed characters left
 moderation talk

3 answers:

I've come up with a partial solution. It's not perfect, but it's a lot better than it used to be.

In my camera script, at the end of the LateUpdate() method, I added this:

camera.fieldOfView = 60;
Shader.SetGlobalMatrix("viewMatrix", camera.worldToCameraMatrix);
Shader.SetGlobalMatrix("projMatrix", camera.projectionMatrix);
camera.fieldOfView = 179;

As you can see, it sets the field of view to the standard 60 degrees, sets the shader View and Projection matrices, and then forces the field of view to 179 degrees (the maximum). So, from the shader's point of view, the camera is normal, but in Unity's point of view, the frustum is widened out to the extreme. This means that when Unity does the culling and determines which objects to render, a lot more objects pass the test.

Of course, this means that you have to change your shaders to use your own matrix variables instead of the Unity built-in variables, but that's not too bad:

o.pos = mul(_Object2World, v.vertex);
o.pos = mul(viewMatrix, o.pos);
o.pos = mul(projMatrix, o.pos);

As I said, it's not perfect and some of the displaced meshes still are clipped, but it's only about 1% of the time now as opposed to about 90% of the time before.

more ▼

answered Dec 04 at 10:10 PM

GlitchEnzo\'s gravatar image

Patrick McCarthy
230 3 4 14

(comments are locked)
10|3000 characters needed characters left
 moderation talk

I have also had issues with the frustum culling taking place too early / incorrectly. When using the exact same code, the frustum would cull early if the Initialization of the GameObject took place in my Update() call rather than Start(). Very strange. I changed the bounds size to be extremely large and less culling occurred, but it was still bad. When I moved the bounds center to the center of the frustum, it worked every time. To move the frustum I placed the following code at the end of my Update() - after the mesh modification:

Transform camTransform = Camera.main.transform;
float distToCenter = (Camera.main.farClipPlane - Camera.main.nearClipPlane) / 2.0f;
Vector3 center = camTransform.position + camTransform.forward * distToCenter;
float extremeBound = 500.0f;
MeshFilter meshFilter = frontRenderer.GetComponent<MeshFilter>();
meshFilter.sharedMesh.bounds = new Bounds (center, new Vector3.one * extremeBound);

Obviously if you need the bounds for anything else you'll run into problems and will want to make a backup before you force the change.

more ▼

answered Apr 14 at 04:32 AM

Lemon\'s gravatar image

Lemon
114 5 5 13

(comments are locked)
10|3000 characters needed characters left
 moderation talk

Use RecalculateBounds() after you assign the mesh to a MeshFilter component. So for example in C#:

GetComponent().mesh = aMeshObject; aMeshObject.RecalculateBounds();

This way it will recalculate renderer bounds.

more ▼

answered Mar 10 at 12:53 AM

KingSharaman\'s gravatar image

KingSharaman
1 2

(comments are locked)
10|3000 characters needed characters left
 moderation talk
Your answer
toggle preview:

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this question

By Email:

Once you sign in you will be able to subscribe for any updates here

By RSS:

Answers

Answers and Comments

Topics:

x15
x10
x6
x5
x4

Asked: Dec 02 at 10:46 PM

Seen: 1584 times

Last Updated: Sep 13 at 12:01 AM

powered by Qato - Enterprise Q&A