• Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
5
Question by GlitchEnzo2 · Dec 02, 2010 at 10:46 PM · gpudisplacementvertexshaderisvisiblefrustrumculling

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.

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

10 Replies

· Add your reply
  • Sort: 
avatar image
6

Answer by allenwp · Dec 20, 2013 at 02:25 PM

Lemon, your answer looks pretty close, but doesn't work out of the box for me. I just made a blog post answering this question:

http://allenwp.com/blog/2013/12/19/disabling-frustum-culling-on-a-game-object-in-unity/

 // boundsTarget is the center of the camera's frustum, in world coordinates:
 Vector3 camPosition = camera.transform.position;
 Vector3 normCamForward = Vector3.Normalize(camera.transform.forward);
 float boundsDistance = (camera.farClipPlane - camera.nearClipPlane) / 2 + camera.nearClipPlane;
 Vector3 boundsTarget = camPosition + (normCamForward * boundsDistance);
 
 // The game object's transform will be applied to the mesh's bounds for frustum culling checking.
 // We need to "undo" this transform by making the boundsTarget relative to the game object's transform:
 Vector3 realtiveBoundsTarget = this.transform.InverseTransformPoint(boundsTarget);
 
 // Set the bounds of the mesh to be a 1x1x1 cube (actually doesn't matter what the size is)
 Mesh mesh = GetComponent<MeshFilter>().mesh;
 mesh.bounds = new Bounds(realtiveBoundsTarget, Vector3.one);
Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image xuancoolcat2 · Oct 21, 2015 at 05:36 AM 2
Share

Thanks. Ins$$anonymous$$d, I used the solution of the comment in the link. Just enlarge the bounds of mesh. Simplest and works enough to me now.

 float boundwidth = 500.0f;
 model$$anonymous$$esh.bounds = new UnityEngine.Bounds(new Vector3(0,0,0), new Vector3(1,1,1) * boundwidth);



avatar image zero4444 xuancoolcat2 · Sep 04, 2019 at 11:10 PM 0
Share

This still works. Only 2 lines of code.

avatar image
0

Answer by Seizure · Apr 23, 2013 at 08:10 PM

myTerrain.basemapDistance = 5000; //Allows terrain textures to be shown at a greater distance. myTerrain.detailObjectDistance = 5000; //Allows grass and similiar to be shown at greater distance.

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
8

Answer by EeroH · Dec 25, 2012 at 05:16 PM

After fighting with a similar issue (displacement in the vertex shader), I found a possible solution to change the bounds: Replace your model's MeshRenderer with SkinnedMeshRenderer, which is actually ment to be used with animated meshes that have larger bounds than the mesh itself.

One way to get a SkinnedMeshRenderer component automatically generated for your mesh, is to create one (useless) bone/armature parented to your mesh in your 3d modelling software. Then in Unity, import the rig for the model as well (you don't need to import animations, at least not in Unity 4). When you have the model in the project hierarchy, you can even disable the animator component and the armature/bone gameobject (everything animation-related excess except for SkinnedMeshRenderer itself. Deleting those seems to cause problems, though). There may be an other way to create a proper SkinnedMeshRenderer, but I don't know yet if it's possible just by scripting.

Now, the trick is that SkinnedMeshRenderer has a localBounds member that can be changed. This is because an animated model may move/change inside its boundaries. Supposing that you know the maximum bounds (or maximum displacement as you mentioned) for your model, you can initialize the renderer with proper bounds once (in OnEnable(), for example):

 // Get the SkinnedMeshRenderer component
 skinnedMeshRenderer = gameObject.GetComponent<SkinnedMeshRenderer>();
 
 // Create and set your new bounds
 Bounds newBounds = new Bounds(myMaxBoundsCenter, myMaxBoundsSize);
 skinnedMeshRenderer.localBounds = newBounds;
 

As a result, the rendering will use these bounds for frustum culling, and you don't have to worry about the bounds after initializing them once. A nice thing about SkinnedMeshRenderer is also that it shows the actual AABB bounding box in the editor, so it's easy to see if the runtime-set boundaries are correct.

This solution took a while to come up with, but at least so far it has worked like a charm.

Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image mbbmbbmm · Oct 10, 2016 at 12:59 PM 0
Share

Very comfortable solution! It's also possible to just add a Skinned $$anonymous$$esh Renderer component to the object in Unity (don't forget to remove the original $$anonymous$$esh Filter and $$anonymous$$esh Renderer components) and then assign the mesh to the corresponding field. Only thing to keep in $$anonymous$$d is that meshes must be named in a recognizable way to be able to reassign them in the editor. And also Skinned $$anonymous$$esh Renderers won't be batched as far as I know.

avatar image
0

Answer by KingSharaman · Mar 10, 2012 at 12:53 AM

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.

Comment
Add comment · Show 4 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Dylan Gundlach · Aug 09, 2014 at 06:22 PM 0
Share

I don't know why you got so many down votes. I was having this render culling problem with a function in an editor script I created(see below), and adding "mesh.RecalculateBounds()" worked fine. Thanks mate.

private void shift$$anonymous$$esh(){ $$anonymous$$esh mesh = target.GetComponent<$$anonymous$$eshFilter>().shared$$anonymous$$esh; Vector3[] vertices = mesh.vertices; // for(int i = 0; i < vertices.Length; i++){ vertices[i] += shift; } mesh.vertices = vertices; mesh.RecalculateBounds(); }

avatar image PappyA · May 01, 2015 at 11:30 PM 1
Share

I think the reason is because the question pertains to manipulating vertex position in the vertex shader, which happens after the CPU is done with the object. As far as the CPU is concerned the vertices have never moved, thus mesh.RecalculateBounds() doesn't do anything.

avatar image Velo222 · Oct 11, 2015 at 11:40 PM 0
Share

Using the "RecalculateBounds()" command fixed my problem as well. Thank you. Whether or not this is in the scope of the original question, I don't think it should have negative votes, but.....technicalities I guess. It helped me.

avatar image $$anonymous$$ · Nov 09, 2015 at 05:59 PM 0
Share

This suggestion fixed my problem as well. I had an issues with the Vuforia SD$$anonymous$$ and turns out Vuforia does not call RecalculateBounds() after creating it's camera texture background. Been searching for a why to fix this for better part of the day and your suggestion fixed it. Thanks. Gave an up vote to show my gratitude.

avatar image
1

Answer by GlitchEnzo2 · Dec 04, 2010 at 10:10 PM

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.

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
  • ‹
  • 1
  • 2

Your answer

Hint: You can notify a user about this post by typing @username

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

Welcome to Unity Answers

If you’re new to Unity Answers, please check our User Guide to help you navigate through our website and refer to our FAQ for more information.

Before posting, make sure to check out our Knowledge Base for commonly asked Unity questions.

Check our Moderator Guidelines if you’re a new moderator and want to work together in an effort to improve Unity Answers and support our users.

Follow this Question

Answers Answers and Comments

18 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Modify water displacement 0 Answers

iPhone Performance Question relating to CPU-WAITS-GPU 1 Answer

Porting DXSDK GPU Bitonic Sort to Unity 3 Answers

for a 2d background, sprite or a quad with shader, would be best? 0 Answers

GPU Memory : Impact of Grayscale Textures 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges