Hi, everyone. It is a dynamic-occlusion-culling system for Unity. ASSETSTORE : https://assetstore.unity.com/packag...sion-culling-dynamic-occlusion-culling-138442 Very easy to set up, no programming required. Easy interface to edit convex hull [1.2] Stereoscopic rendering support (VR) [1.3] Baking LOD Mesh (Integrated UnityMeshSimplifier ) Geometric approach (NO GPU, NO Rasterization) * Available for any platform, including iOS and Android Managing large-scale occludees by spatial partitioning algorithm Runtime combine mesh for batching optimization Compare with PVS (Unity Occlusion Culling) Smaller memory usage (ignore, almost zero) No pre-computing time, no pre-computing data Dynamic Occluder (any translation, rotation, scaling) Dynamic Environment (show and hide) Cons. Setting occluders manually like unity-colliders for collision detection
Hi there, I'm looking for a decent occlusion culling tool. It looks promising, though I have to honest I'm not a fan of having to set all the occludees up like that. However if it gives a proper performance boost it's probably worth the hassle. But, I notice you barely mention the performance gains anywhere. I know this is very situation dependent, but could you at least show a video with a bit of a complex scene where you compare the scene with and without your tool?
We made a comparison video with an old test device (NVidia shield tablet 2015) for you. (We played the scene included in the asset.)
@GCat webgl yes, unity terrains no...you can hide just whole terrain game object, but not its submeshes
@KSI777 I am trying to use custom object as convex occluder using script but as you can see in video I am getting weird looking yellow lines from camera...it seems that just feed "SetConvexVolume" function with Vector3 array of vertices from mesh filter component is not enough. What is the correct workflow? Thanks for help. video: https://www54.zippyshare.com/v/lBm4NgxP/file.html ...I am using mesh based terrain objects Code (CSharp): using System.Collections; using System.Collections.Generic; using UnityEngine; public class SetOccluderConvex : MonoBehaviour { RT.Occluder m_Occluder; void Awake() { m_Occluder = new RT.Occluder(); m_Occluder.SetConvexVolume(GetComponent<MeshFilter>().mesh.vertices, transform.localToWorldMatrix); m_Occluder.SetTransform(transform); } void OnEnable() { if (m_Occluder != null) m_Occluder.Enable(); } private void OnDisable() { if (m_Occluder != null) m_Occluder.Disable(); } }
@GCat WebGL has no problem because it works with the CPU. But there is no support for terrain rendering. It is impossible to apply the terrain as a occludee. I think it might be able to use it with terrain partially. I have captured a sample video for you. (Of course I think that is quite limited.)
@Bzuco We checked and found some issues in SetConvexVolume. (The limit for the number of planes is 64, and there were some errors in the calculation of the convex.) We have fixed it and upload it to the asset store now, and it will be updated soon. (1.4 version) If the update is delayed, request by email, and I will send changes to you. The vertex count of convex affects performance. So we added a function to limit the vertex to the convex calculation function. And it would be helpful for the performance to pre-calculate it. We added it to your code as below. Code (CSharp): using System.Collections; using System.Collections.Generic; using UnityEngine; #if UNITY_EDITOR using UnityEditor; #endif public class SetConvexOccluder : MonoBehaviour { RT.Occluder m_Occluder; [HideInInspector] public Vector3[] m_BakedConvex; [HideInInspector] public int[] m_BakedHullTriangle; [HideInInspector] public int[] m_BakedEdge; void Awake() { m_Occluder = new RT.Occluder(); if (m_BakedConvex != null && m_BakedConvex.Length >= 4) m_Occluder.SetVolume(m_BakedConvex, m_BakedHullTriangle, m_BakedEdge, transform.localToWorldMatrix); else m_Occluder.SetConvexVolume(GetComponent<MeshFilter>().mesh.vertices, transform.localToWorldMatrix); m_Occluder.SetTransform(transform); } void OnEnable() { if (m_Occluder != null) m_Occluder.Enable(); } private void OnDisable() { if (m_Occluder != null) m_Occluder.Disable(); } #if UNITY_EDITOR [CustomEditor(typeof(SetConvexOccluder))] public class SetConvexOccluderEditor : Editor { Vector3[] m_ConvexVertex; int[] m_ConvexPolygons; int m_TargetCount; public void OnEnable() { SetConvexOccluder _target = (SetConvexOccluder)target; m_TargetCount = _target.m_BakedConvex != null && _target.m_BakedConvex.Length > 0 ? _target.m_BakedConvex.Length : 32; if (_target.m_BakedConvex != null && _target.m_BakedConvex.Length >= 4) RT.Occluder.ConvexHull3d(_target.m_BakedConvex, out m_ConvexVertex, out m_ConvexPolygons, 0); } public override void OnInspectorGUI() { base.OnInspectorGUI(); GUILayout.Space(8); EditorGUILayout.BeginHorizontal(); m_TargetCount = EditorGUILayout.IntSlider("", m_TargetCount, 8, 64); if (GUILayout.Button("Bake")) { SetConvexOccluder _target = (SetConvexOccluder)target; Undo.RecordObject(target, "Bake"); Vector3[] vertices = _target.GetComponent<MeshFilter>().sharedMesh.vertices; int[] hull; int[] edge; RT.Occluder.ConvexHull3d(vertices, out m_ConvexVertex, out m_ConvexPolygons, m_TargetCount); RT.Occluder.GetVolumeEdgeAndHull(m_ConvexPolygons, out hull, out edge); SceneView.RepaintAll(); _target.m_BakedConvex = m_ConvexVertex; _target.m_BakedHullTriangle = hull; _target.m_BakedEdge = edge; } if (GUILayout.Button("Reset")) { SetConvexOccluder _target = (SetConvexOccluder)target; Undo.RecordObject(target, "Reset"); _target.m_BakedConvex = null; _target.m_BakedHullTriangle = null; _target.m_BakedEdge = null; m_ConvexVertex = null; SceneView.RepaintAll(); } EditorGUILayout.EndHorizontal(); } private void OnSceneGUI() { if (m_ConvexVertex != null && m_ConvexVertex.Length > 0 && m_ConvexPolygons != null) { SetConvexOccluder _target = (SetConvexOccluder)target; Vector3[] vertex = new Vector3[m_ConvexVertex.Length]; List<Vector3> back_lines = new List<Vector3>(); List<Vector3> front_lines = new List<Vector3>(); for (int i = 0; i < vertex.Length; i++) { vertex[i] = _target.transform.TransformPoint(m_ConvexVertex[i]); } for (int i = 0; i < m_ConvexPolygons.Length;) { Vector3 nrm = Vector3.Cross(vertex[m_ConvexPolygons[i + 2]] - vertex[m_ConvexPolygons[i]], vertex[m_ConvexPolygons[i + 1]] - vertex[m_ConvexPolygons[i]]); Plane p = new Plane(Vector3.Normalize(nrm), vertex[m_ConvexPolygons[i]]); SceneView sceneview = SceneView.currentDrawingSceneView; bool front = p.GetDistanceToPoint(sceneview.camera.transform.position) > 0; List<Vector3> list = front ? front_lines : back_lines; int v0, v1; for (v0 = v1 = m_ConvexPolygons[i++]; i < m_ConvexPolygons.Length; i++) { int v2 = m_ConvexPolygons[i]; if (v2 == -1) { list.Add(vertex[v1]); list.Add(vertex[v0]); i++; break; } else { list.Add(vertex[v1]); list.Add(vertex[v2]); v1 = v2; } } Handles.color = Color.gray; Handles.DrawLines(back_lines.ToArray()); Handles.color = Color.white; Handles.DrawLines(front_lines.ToArray()); } } } } #endif }
OK, thanks, I will check the code and wait for the store update, or request you by email if it will be takes too long
Hello. I am looking for a working Dynamic Occlusion Culling system. Can you answer two questions? 1.Does this asset work on the Console platform? 2.This asset is described as not using GPU, but does it support multi-threaded CPU processing? Is CPU main thread usage minimal? Thank you.
@ohbado 1. There is no platform limit. 2. It is currently not operating in parallel like a general unity script. We plan to review the relevant issues. The calculated load depends on the number of objects. There is a variable that controls the calculation.
Does this support concave shapes? Also does it support runtime manipulation, addition, and deletion of the occluder shapes?
Concave is not supported, only Convex is supported. (However, it supports that the occluder is overlapped by multiple occluders. Hole on surface like a door are restrictively supported.) It is not possible flexibly change the shape, it is just possible to add and remove occluders runtime.
Hi I bought your asset, Im quite satisfied with it, though I have a future feature request, i thought already inculed: frustum culling. Right now only the occluded objects get culled, that are inside the camera frustum, all of the objects that are behind the player are still active. With that feature implemented this asset is easily 5 stars.
Do you mean something like this? (I tried to modify the code as below.) code I'll try to be able to selectively apply it to the next update. Currently we are preparing for optimization using compute shaders.
Well, yes. This is what i meant, wonderful job. I think that you should update your example videos too, because this is much more impressive this way. Thank you for your update. I rated the asset 5*
Unity alread does frustum culling (although you won't see it in Scene view). Are there any performance benefits of doing a manual frustum culling on top of the built-in frustum culling?
In my case yes, beacause i use object pooling on environment objects. So I can release the frustum culled objects back to the pool.
I got this package, but when looking at all of the example scenes I don't see any culling happening, nor do I see any of the visuals in the scene view that are seen in the readme and the asset's store page. Does anybody have any insights as to why that'd be the case?
Hi, I got a pretty weird case here so please hear me out: I am part of a modding community for a VR game and I make custom maps for that game. Due to the way we load the modded scenes we sadly do not get acess to any of unitys default occlusion culling. However the main problem is the CPU load as the game is very extensively physics based. Will your culling script reduce the load on the CPU?
@KSI777 It is translated at DeepL. Hello, I have a question. The wall in the foreground is made up of 4 separate objects, each with an RTSimpleOccluder set on it. The back wall has two and both are set to RTOccludee. One of the walls is culled because it is hidden by the Occluder, but the other wall is not culled, probably because it crosses two Occluders. Is this the way it works? Thank you.
Hello I tried to send an email to the support email written in the Readme.pdf but it seems this email is not reachable. Just a little question : Is there a way to get the actual Status of an Occludee from Script ? Let say for example I have a box behind an Occluder wall. When the box is Occluded : Debug.Log("RT_OccludeeStatus : " + occludee.isOccluded); // Could display RT_OccludeeStatus : True; When the box is Visible it display : Debug.Log("RT_OccludeeStatus : " + occludee.isOccluded); // Could display RT_OccludeeStatus : False; I just want to extend a FrustumCullingVisualization script so when the object is occluded by RT_Occlusion it is not displayed by the FrustrumCulling, Thanks
Hi @KSI777 I'm interested in buying it but is it still supported? Because zero updates since March 2021 makes it feel like it's been abandoned... Thanks for your answer
Same question here. What's the development status of this tool? Also: I can't manually build these green boxes for all objects (too many different ones in the game). I could however provide one or more matching concave meshes. Is it possible to use these meshes as RT convex occluders instead ob building them by hand?
Hello, I am considering buying your asset. My scene is generated at runtime, instantiating all game objects as tiles. Does this solution support this usecase?