Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 14 Next capture
2021 2022 2023
2 captures
12 Jun 22 - 14 Jun 22
sparklines
Close Help
  • 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
0
Question by _watcher_ · Jul 02, 2017 at 06:02 PM · editorcullingfrustrumvisualizefrustrumculling

Visualize frustrum culling in Editor

Hi,

Working on a simple 2D game, i'm thinking of using Unity's existing culling for enabling/disabling some additional features on my objects, when they are off-screen (using Renderer's OnBecameVisible and OnBecameInvisible).

However it is hard to visualize, as whatever leaves the camera's frustrum during playmode is automatically culled, but i can not see the effect (since its off screen - out of camera's frustrum). This is in the "Game" window.

Now lets hop into the "Scene" window during playmode. We have 2 cameras here, the "main" scene camera (or the "active" camera), that we added into an empty scene. This is the camera that shows what we see in Game window. And then there is the camera that we are "looking through" into the scene. Lets call this "Editor camera".

My question is: Is there a way to visualize frustrum culling in Editor? Example: Editor camera looks at scene main camera that culls objects (it can see it's cone of vision, lets call this "view rect" [we're in 2D]). Editor camera can see the view rect of the active scene camera (Unity supports this already), and can see how objects which leave the frustrum of the active camera - how their Renderers - are disabled - how they "disappear" - so that at that point the Editor camera can't see them! (i dont see Unity being able to do this atm? What am i missing?)

Anything like this? Any techniques? Im sure this is possible, or there is some kind of BEST PRACTICE to test frustrum culling in Unity already, as i've seen some pictures that demonstrate this..

UPDATE: after some more reasearch, i've discovered, that what i want is similiar to visualization of "occlusion culling" that Unity does for 3D/MeshRenderers (involves baking the information, more here: https://docs.unity3d.com/Manual/OcclusionCulling.html). However we can not use the occlusion culling visualization for SpriteRenderers (so not for Sprites). I've also found 4 more unanswered questions in spirit of "how to visualize occlusion culling for SpriteRenderer". So it seems that - atm in editor - for simple 2D sprites - we can not "visualize" frustrum culling, neither disable it to implement our own (+visualization).

However i've also found that by increasing camera's FOV (assume .size in case of 2D/orthographic) in Camera.onPreCull and setting it back to default in Camera.PreRender, i might be able to "fake" what i need (play mode only). Ill leave this question open, until i test the solutions provided, including the one i just outlined, and close it once i've found one that suits best the use-case above.

UPDATE2: SOLUTION1: Apart from solution posted below by @Bunny82 (SOLUTION2) (which is awesome), i've decided to post my quick hack, using the FOV switch mentioned above. This allows to visualize frustrum culling for a specific camera inside editor's "Game" window (using the [ExecuteInEditMode] directive).

Here is a screen:

alt text

And here is the code:

 #if UNITY_EDITOR
 using UnityEngine;
 using UnityEditor;
 
 [ExecuteInEditMode]
 public class VisualizeCulling : MonoBehaviour
 {
     /// <summary>
     /// camera to use for frustrum culling visualization
     /// </summary>
     public Camera targetCamera;
 
     /// <summary>
     /// Original target camera size (if target camera is ortographic/2D), or FOV (if target camera is perspective/2D)
     /// NOTE: target camera size will be enlarged from originalCameraSize to cullingCameraSize during culling visualization
     /// </summary>
     private float originalCameraSize;
 
     /// <summary>
     /// Camera size to use during frustrum culling visualization
     /// This should be higher value than the target camera's size/FOV
     /// NOTE: target camera size will be enlarged from originalCameraSize to cullingCameraSize during culling visualization
     /// </summary>
     public float cullingCameraSize;
 
     /// <summary>
     /// During frustrum culling visualization,
     /// the original target camera size is visualized using semi-transparent debug rectangle
     /// - only for 2D cameras
     /// </summary>
     public Color originalCameraSizeDebugColor = new Color(1, 0, 0, 0.5F);
     
     /// <summary>
     /// Disable this script by default;
     /// Let user set the inspector values first and enable manually after;
     /// </summary>
     public void Awake()
     {
         enabled = false;
     }
 
     /// <summary>
     /// Enable script to re-initialize with inspector-set values
     /// </summary>
     public void OnEnable()
     {
         if (CheckCamera()) {
             CheckCullingSize();
 
             // register delegates for culling visualization
             Camera.onPreCull += PreCullAdjustCamSize; // shrink
             Camera.onPreRender += PreRenderAdjustCamSize; // back to default
         }
         
             EditorApplication.playmodeStateChanged += StateChange;
     }
 
     public void OnDisable()
     {
         // set camera size back to default size
         if (targetCamera != null) {
             if (targetCamera.orthographic) {
                 targetCamera.orthographicSize = originalCameraSize;
             }
             else {
                 targetCamera.fieldOfView = originalCameraSize;
             }
         }
         
         // unregister delegates
         Camera.onPreCull -= PreCullAdjustCamSize;
         Camera.onPreRender -= PreRenderAdjustCamSize;
     }
     
     private void StateChange()
     {
         // app will change playMode
         if (EditorApplication.isPlayingOrWillChangePlaymode) {
             if(!EditorApplication.isPlaying) {
                 // will play;
                 // disable during play
                 enabled = false;
             }
         }
     }
     
     /// <summary>
     /// Before Camera culling, set camera size to default/original size
     /// </summary>
     /// <param name="cam"></param>
     public void PreCullAdjustCamSize(Camera cam)
     {
         if (cam == targetCamera)
         {
             if (cam.orthographic) {
                 cam.orthographicSize = originalCameraSize;
             }
             else {
                 cam.fieldOfView = originalCameraSize;
             }
         }
     }
     
     /// <summary>
     /// Before Camera rendering, set camera size to culling size (bigger than original)
     /// </summary>
     public void PreRenderAdjustCamSize(Camera cam)
     {
         if (cam == targetCamera)
         {
             if (cam.orthographic) {
                 cam.orthographicSize = cullingCameraSize;
             }
             else {
                 cam.fieldOfView = cullingCameraSize;
             }
         }
     }
 
     /// <summary>
     /// Use defaults, if user doesnt specify inspector values
     /// </summary>
     private bool CheckCamera()
     {
         // if targetCamera was not defined via inspector
         if (targetCamera == null) {
             // Then use main camera
             if (Camera.main != null) {
                 targetCamera = Camera.main;
             }
             // If no camera is tagged as MainCamera
             else {
                 Debug.LogError("VisualizeCulling: OnEnable->CheckCamera: ERROR: Please set target camera via inspector to enable culling visualization!");
                 return false;
             }
         }
 
         // if main camera is orthographic/2D
         if (targetCamera.orthographic) {
             originalCameraSize = targetCamera.orthographicSize;
         }
         // else its perspective
         else {
             originalCameraSize = targetCamera.fieldOfView;
         }
 
         return true;
     }
 
     /// <summary>
     /// If user doesnt supply camera size for culling, or sets wrong culling size,
     /// use mult of original camera size as default culling size
     /// </summary>
     private void CheckCullingSize()
     {
         if (cullingCameraSize <= originalCameraSize) {
             cullingCameraSize = originalCameraSize * 1.5f;
         }
     }
     
     /// <summary>
     /// Draw debug viewport rect of targetCamera's original size, while culling is enabled
     /// - Actual Camera size is enlarged during culling
     /// - Only for 2D cameras
     /// </summary>
     void OnDrawGizmos()
     {
         if (targetCamera != null && targetCamera.orthographic) {
             Gizmos.color = originalCameraSizeDebugColor;
             Gizmos.DrawCube(transform.position, new Vector2(originalCameraSize * 2 * targetCamera.aspect, originalCameraSize * 2));
         }
     }
 }
 #endif

Usage: Simply attach the class to any GameObject in your scene. Then set the culling camera size - this value should be greater than your target camera FOV (if your camera is 3D camera) or ortographic size (if your camera is 2D camera). To illustrate what this value means, just imagine another camera looking at your target camera, with same attributes, only "greater". The bigger that number, the more you will be able to see "outside" of your target camera. One more variable to set via inspector - targetCamera - just drag and drop your target camera here, for which you want to visualize culling. The script will try to auto-correct the settings, in case you mess something up, so no worries there. Once you are done setting the variables, enable the script (it should be disabled by default).

Cheers!

scr01.jpg (206.7 kB)
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

1 Reply

· Add your reply
  • Sort: 
avatar image
0
Best Answer

Answer by Bunny83 · Jul 02, 2017 at 07:06 PM

You may want to use this custom frustum intersection test i've just implemented. The built-in frustum culling in Unity always uses all active cameras which includes the SceneView camera. So there is no way to visually "see" something being culled as it's only culled when it isn't seen by any camera.

With my solution you can manually perform a frustum test between a camera / object pair.

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 _watcher_ · Jul 02, 2017 at 07:29 PM 0
Share

Thank you @Bunny83, i will check your solution, and update the main post accordingly.

avatar image _watcher_ · Jul 03, 2017 at 01:32 PM 0
Share

Allright, i've added my own hack/solution to the original post, however i do like your solution as well, most of all i appreciate your help, and will mark it as the correct answer. Cheers!

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.

Follow this Question

Answers Answers and Comments

84 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 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 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 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 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

Create Camera Frustrum planes for specific layer 0 Answers

Frustrum culling and Gpu instancing. 0 Answers

Detect if bounds are "partially" inside camera frustum 2 Answers

Way to graphically visualize a Vector2 or Vector3 in inspector? 2 Answers

Low fps with many objects even when not looking at them 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