A Unity ID allows you to buy and/or subscribe to Unity products and services, shop in the Asset Store and participate
in the Unity community.
Discussion in 'Assets and Asset Store' started by frenchfaso, Jan 18, 2013.
Good morning Gentlemen,
InstantOC 2.2.2 is out, with some polish for the Unity 5 branch.
Thanks for your hard work ^^
How does this work with multiplayer? If I have a server instantiating objects and have control over them with scripts (and navigation), will they still be visible and interactable for clients who are the other end of the world (next to them)?
I presume InstantOC just disables the renderer of the gameobject if it's not in view?
I would run InstantOC on the client, not on the server. The client is basically in charge of rendering things, which is where occlusion and LOD would come into play.
thank you for your interest in InstantOC!
As @hopeful already explained, InstantOC runs on the client, hiding/un-hiding content dynamically, based on occlusion/visibility. Being fully dynamic, it can handle content streamed from a server and/or generated at runtime by the client (as opposed to the built-in occlusion culling in Unity, which works only for static content).
How does this system compare to the already present LOD system for Unity? Framerate, tri count and draw calls wise?
I can have 5 levels of LOD for my game objects currently, in the videos you only display 2 and say you can do 3, has that been expanded on?
thank you for your interest in InstantOC and sorry for the delay!
InstantOC is primarily a dynamic occlusion culling system, which also includes a ray-based LOD system.
The integrated LOD system currently supports 3 LOD levels; being ray-based, it is smarter than distance-based LOD systems (like the Unity LOD system) in certain situations:
if you have a LOD group behind a wall, and you are only few meters away, but on the other side of the wall, distance-based LOD systems would render the high-res LOD level although the object is not visible (it's behind the wall!). InstantOC LOD system would render the low-res LOD level until the object is hidden behind the wall, and switch directly to the right LOD level, after the object becomes visible to the player.
However, you get the maximum performance gain, when you use both, InstantOC occlusion culling capabilities AND the integrated LOD system.
If 3 LOD levels are not enough, you can combine InstantOC occlusion culling with some other LOD system, for instance the excellent QuickLOD, or the Unity built-in LOD system.
Let me know if this helps!
Great thanks, that is exactly what I needed to know, I have purchased
Does it have an interface for callbacks on things becoming visible/invisible?
e.g. I need to know when a clickable object is being rendered so that I can change the player's mouse cursor to indicate it. Unity has nothing to allow this (built-in visiblity checks are known not to be correctly implemented, and generally say "everything's visible always" just in case).
If it does, what's the interface for that? Ideally, I'm looking for something like:
MonoBehaviour : OnIOCBecameVisible / OnIOCBecameInvisible
(I've implemented this before in other engines, but the only sane + effective way to do it was always to build an Occlusion Culling framework first, and then use that to do all the work. So ... I'm hoping I can buy IOC and be done. Otherwise, I have to re-write OC myslef just to get the feature I need )
thank you for your interest in InstantOC!
Currently you can check if an object is rendered/visible or not through InstantOC, but no event/callback is fired; it's a good idea for an update, I'll do some tests and report back!
Let me know if you need help with the setup.
I am having trouble setting up occlusion, here's a video displaying my current setup, currently your not supposed to have the gameobject rendered if it's not viewable but i can't seem to get that to work.
Or if you have a list of "what's currently visible" (list of GameObjects, I guess?) which is very cheap to query (i.e. it's a list, not a method that re-calculates each time you call it), then I can just as easily integrate that.
In some ways ... "what's visible right now?" would be easier to use than callbacks.
I'm happy to give feedback on method signatures for the API etc - I've got a real-world project I want to apply this to right now, so I can say "that works" / "that's too hard to use" / "can you add X parameter" etc.
Ok I ended up figuring it out, any object that will be in front of an object managed by IOC needs to be in the layer IOC or whatever you named it or else the occlusion won't occur.
Glad you figured it out, sorry for the delay!
Yes, that's right, in Unity 4.x it worked differently, occluders didn't need to be on an "IOC" layer, but as of Unity 5 they do. I suppose it's due to the new Physics system.
you can check if a certain object is hidden or not like this:
make the "hidden" bool variable public in IOClod script
get a reference to the IOClod script of the object you are checking:
var iocLod = GetComponent<IOClod>();
check it like this:
I'll do some tests to see if maintaining a list of visible objects is feasible or not (performance-vise).
Hello @frenchfaso and @a436t4ataf
In case you're interested, here are my experiences with call-backs in unity.
The call-back feature is something that I've implemented in QuickLod and can easily be implemented in InstantOC.
Events are a good call-back method, as they are much optimized and use nearly no performance when no listener is present.
Also you can pass on some data that other developers can use, such as the old and the new lod level.
I assume you already know events, but if not, here's a useful link.
If you use events, you should also offer an OnDisable/OnDestroy event, so that the listener can unregister in case of an object removal/disabling.
Else you have some ghost references which can prevent GC from freeing memory.
Using a list of objects which are currently visible can have some drawbacks.
I wouldn't recommend a list, but rather a HashTable or HashSet duo to the constant time complexity.
HashSets and -tables perform not so well when iterating over them, as they are unsorted.
Duo to the drawbacks, I would recommend using events instead.
Sure. I say "List" because that's an interface not a class, but C# happens to have a madly named class with same name . I only need something I can iterate over - HashSet is fine (should be fast to iterate?).
The differences are fairly small, but out of interest, in my experience the main advantages of List/Set/etc for this:
1. To be honest, if you give me callbacks, I'm going to implement a List anyway (even though my first tests I'll be using the callbacks, they're great for prototyping). It's almost impossible not to - how do you debug your code, for instance? . You need that list. Even if the performance isn't great, you need it.
2. I don't have to worry about forgetting to unregister etc (as you noted). Not just me, but ... anyone else who extends / re-uses my code (that's the bigger worry)
3. Some algorithms are much easier to implement using lists. e.g. Some of Unity's operations you need to re-invoke EVERY FRAME, and so a callback is a pain (you end up storing a var that you then check every frame. Might as well have had a list at that point).
4. If multiple bits of code are taking the callbacks and maintaining a list ... and the OC system already has an internal list it's generating each frame ... that's duplicated code / CPU usage. It would be much more efficient for OC system to export a read-only data structure that is "the most recent data on what's visible", and when asked for new version, to keep sending a pointer to the cached copy, rather than re-generate.
Sorry, I'd assumed you already track this data internally, as part of your OC checks. I thought it would be a case of exposing the data structure you already have.
If it's somethign custom you don't want to expose, I'd implement:
1. public List GetLatestVisibleList()
2. ...which internally has a List instance "List _LatestCachedCopy"
3. ...and each time it's called, it checks if your data structure has changed since last call (easy but poor implementation: save the Time.time, and assume that every new frame it needs to "assume it has changed"). Better implementation: check the data structure itself.
4. ...if data has cahnged, regenerate the _LatestCachedCopy
5. ...then return _LatestCachedCopy
I don't know what your goal is with the collection.
Depending on what you want to do, it would need a different collection type.
If you are experienced with the available collection types, you may want to ignore my post, as I'm only comparing some speed differences for the list and the hashset. Also I've got this information by reading blogs and doing some tests, so it can be wrong! You can find more information here.
I'm using the big O notation here. In general, O(1) means it always uses the same time, not dependent on the amount of items. O(n) on the other hand means that it takes longer, the more items are in the collection.
If you want to iterate over a collection, the list is a better choice, as its data is already in an enumerable state. A hashset is not directly enumerable as the data has no defined order, it's not indexed.
Adding objects to the end of a list is an O(1) operation, the same for adding an object to a hashset. Removing items on the other hand is O(n) (n -> number of items stored) for a list and O(1) for the hashset.
Inserting objects into the list is O(n), as it needs to move back all later items, this usually takes long. The hashset has no insert command, as the data is not indexed.
Finding an item in a List is O(n), for the hashset O(1).
So it depends.
When you want to check if an item is in the collection, then you would need a hashset.
But when you want to check all items of the collection, then a List would be better.
Also it depends on how InstantOC implements this collection.
When it clears and refills the collection in every frame, then a list is better.
But when it removes certain items and adds others, then a hashset is better.
While the hashset usually is slower in an empty collection than the list, I wouldn't weight it here, as the collection is probably never empty, but more likely filled with objects.
This said, I would recommend you to use the call back feature and create your own collection.
As far as I understand the codebase of InstantOC, there's no internal list of objects, as it just handles the objects which were hit by a ray. This is also one of the reasons why it's so fast.
To get the best performance, I suggest making a performance test with a list and with a hashset to find the faster variant.
O-notation isn't relevant here. The datasets are far too small for O - your numbers are incorrect.
With a very big game, you MIGHT see that difference (unlikely, but possible), but with OC you should never see it - the whole point of OC is that it's keeping the number of items very small .
I'm pretty sure a list will always be better for InstantOC. Cost of adding is immeasurably small here.
But the haset has to do extra work: Hashing algorithms are much much more expensive than your add-to-collection cost. Any dataset using a hash is likely to be 10x or more slower than the list because of this. Worst, it might well do allocation, in which case it's potentially thousands of times slower.
For most of the OC algorithms I know of, and can imagine using in Unity, it has to process them as a list. Whether it stores that list as it goes makes little difference: you've already taken the pain of loading each item into local memory, so you might as well save-out the references as you go.
How are you getting the "objects hit by the ray"? The Unity methods return list/array, no? (effectively the same thing, in C#. List is implemented behind the scenes as multiple arrays, last time I checked)
Please read the first answer in this link (same as I've referenced in my previous post).
There the test results indicate that the hashset performs better than the list when there are 20 objects or more.
You probably have more than 20 objects active at the same time.
InstantOC fires a set of rays from the camera (IOCcam).
Every object that is on the correct layer and get's hit by a ray gets, as it's visible.
When an object doesn't get an information for some time, it hides it self.
There are no usable collections involved which could be exposed.
As I stated before, the optimal collection type depends on what you want to achieve.
If you only want to add items to a collection and iterate over them, then you are correct, a list is faster.
But when you want to remove specific items, a hashset already performs better.
And here the way InstantOC handles the objects has a huge impact.
As it works with rays instead of collections, it cannot rebuild the collection in every frame.
Instead it would have to remove the old items and add the new items -> Hashset.
No, it absolutely does not indicate that. You are fundamentally misunderstanding how these are implemented, how they run on a computer, and how you measure performance costs of code. I don't mind, but I strongly recommend you read up about micro-benchmarking, and also investigate the actual time in microseconds of these operations - it is so small you will never, ever, EVER see the difference in a Unity game.
Aside from the fact their own source invalidates the test, look how many iterations they had to do to find a difference: "int times =10000000;"
(NB: their code is ridiculous; never use that as a benchmark! And their hashset is storing native strings, which means you cannot draw any conclusions relevant to InstanctOC)
You are misapplying some theory, missing out step one, which is something like: "this theory only applies when the numbers are of sufficient scale". The real world numbers here are too small for your conclusions, by a factor of something like 1,000,000
Apologies for derailing the thread; I felt it was important to correct the massively misleading statements on performance, but it doesn't matter. Thanks @frenchfaso for the responses. I'll try InstantOC with the tweaks mentioned and it looks like it'll be fine.
I have multiple camera in my scene and would like each camera to use ioc as its enabled. Simply putting IOCcam on each camera doesnt seem to work. Any recommendations ?
Hello JBR games,
is it a split-screen scenario?
It should be enough to set the tag of one of the cameras to "Main Camera".
So i have 3 cameras ,but only one is in use at anyone time. Setting tag to main camera doesnt seem to help for the other cameras. I am using for my first camera... fpsCamera.SetActive(false); for the main camera. While switching to one of the other cameras. Should i enable the camera itself instead ?
Hello JBR games,
this should be ok, are you getting any errors in the console?
No errors that I know of. But all the objects disappear in front of the second camera.
Maybe I will take your demo and add a couple extra fps cameras and test that and see if I can reproduce the same problem otherwise it might be something in my project.
Just tried that, I added a second camera to the demo scene, tagged it as "MainCamera", added the IOCcam script, disabled the first camera, it works!
It might be something specific to your project/setup, would you mind sharing with me a sample scene that exposes the problem, so that I can look into it and point you in the right direction?
Good to know it's probably something on my side then I'll look into it . I'll send you a scene if I need to but it's a pretty large project with a lot of dependencies. Total be at least a couple gigs in size.
Thanks for the info I'll keep you posted.
All right, keep me updated!
As an alternative we could do a Skype/Teamviewer session.
a little off-topic, I just released my first Unity game!
It's called Splashy Flipper, here is the official presentation thread, with infos, and a link to the official web-page, where you can try the free WebGL version!
Hey, I'm thinking of picking this up right now. Is this only beneficial for runtime generated scenes, or does it also have general performance advantages compared to the Unity built-in OC?
Basically, in a static scene (static as in no runtime instantiations of meshes), does IOC perform better than Unity OC?
I doubt it, but that's a good question. Now that everyone has OC with Unity 5 it makes sense to do a performance comparison.
While I haven't tried it yet, you ought to be able to get both methods working together. It would probably be good for this to be mentioned in the docs, if it isn't yet.
My understanding is that where IOC has always been helpful is for occlusion in dynamic situations, for particle effects, objects behind doors that open and close, and so on.
@sprawww @hopeful InstantOC is, at runtime, probably a little bit slower than the integrated occlusion culling in Unity, as mentioned in the official FAQ.
So as you already mentioned, it is most useful (actually even required) in scenes with dynamic/procedural content, where it is simply not possible to use the integrated occlusion culling.
But there is another aspect to take into account, InstantOC can be very useful also if you have only static content, it can dramatically boost up your work-flow, not requiring baking after each modification, as traditional occlusion culling techniques require. It's fully dynamic, so you just do your editing and hit "Play": occlusion culling enabled!
Also, as @hopeful mentioned, it integrates lights and particle effects occlusion culling, both of which are really handy optimizations especially on mobile platforms.
I am currently making use of Unity's Occlusion Culling, but I've hit a major blocker.
My setup currently consists of a single "Main" scene and my actual level scenes are stored in Asset Bundles. When I want to load a new level, I use "Application.LoadLevelAdditiveAsync" on the Asset Bundle and load the level scene directly in the main scene.
The problem I'm now facing is that apparently Unity does not support Occlusion Culling for scenes that are loaded with LoadLevelAdditive and LoadLevelAdditiveAsync.
Does your plugin support Occlusion Culling for levels that are loaded additively in another scene from an Asset Bundle?
IIRC, InstantOC works by firing raycasts that hit colliders when they are in front of the camera, and this reveals the items you want to show. You set up the colliders the way you want (this includes trigger colliders). It doesn't have to be a per-object collider, as you can have one collider act to reveal many objects, nor does the collider have to be surrounding an object ... it could be placed like a trigger, so that when the collider moves into the camera view, objects at a particular location are revealed.
Also, you only use this OC system where you want it. So if you want some things to be visible all the time (like maybe certain tall buildings in an urban scene), then you can leave them out of the IOC system.
As you can see, you can have pretty good control over what gets revealed when.
(EDIT: Above was edited a bit for clarity.)
@dreasgrech thank you for your interest in InstantOC, as @hopeful kindly explained, InstantOC is pretty flexible, and as a matter of fact, it is perfect in such situations where you load content dynamically at runtime, and/or create content procedurally at runtime.
here is a blog post with the first video-review of Splashy Flipper and a Twitch of me beating the World-record!
I'm planning to write a series of blog-posts about the making-of Splashy Flipper, with lots of code samples and detailed infos about catches I encountered and the solutions I came up with. Together they should form a fairly detailed tutorial about making a Flappy Bird like game with Unity.
@JohnRossitter from SmarterPhone Labs published a great article on Unity optimization techniques:
Check it out!
Currently experimenting with collider-free dynamic occlusion culling.
It's slow(er), but I haven't done much optimization work yet.
In Unity 5, Physics has become so fast, that it's not a problem any more, relying on colliders to do dynamic OC.
Are you seeing nevertheless some use cases for (slower) collider-free dynamic OC?
Yes, I would love to use collider free OC for our game.
I suppose you have procedural or streamed content, so Unity's Umbra OC is not an option?
Yes, most of the games content is procedural.
I have a quick question: I've been looking for an implementation of partial mesh/objects occlusion cullling. It means, the technique that not only avoids rendering objects that are entirely occluded, but that also offer the option to render only the parts of the objects/meshes that are visible.
Common OC is dual choice: you either don't render an object (if it is full occluded) or you render the full object (if some part of it is visible). However, imagine you have one very big object/mesh with hundreds of thousands of triangles. Since it is so big, imagine that rarely it fits the camera entirely. Most of the time only a small part of it is within the frustrum. So, the ideal would be to render just the part of the object/mesh that is visible - not all of it.
I've read about such algorithms in the past and was wondering if your asset is able of such or if you know of some solution to that.
In any case, I've been playing around with your asset and it is a really incredible piece of work. Congrats. And by the way, I would also love to have the possibility of OC without colliders, for my procedurally generated environment.
@fermas Hello, I'm glad you like InstantOC! Thanks
InstantOC works at the mesh renderer level, so it hides/unhides whole meshes. Unity cameras have built-in View Frustum Culling, which should work at the triangle level (not completely sure though..), so parts of a mesh that are not in the View Frustum, should not be rendered.
As of the collider-free occlusion culling, I've added a couple of optimizations to the experimental version, (like using the new CullingGroup API) but for non-trivial meshes it is still too slow. Ray based dynamic occlusion culling is almost like a real-time ray-tracer, you have to fire a lot less rays, but even so it`s a lot of work. So it will be very hard to do custom, collider-free, ray-casting that is as fast as the new Unity 5 Physics.raycast, partially because the latter is native, and partially because it assumes a lot of things to maximize performance (for instance colliders are static).
Would it be possible in your case, to generate the geometry in separate meshes, in order to take advantage of InstantOC?
Do you have any tutorials on how to setup occludee objects? I have many small assets and would like them to only be occludee's.
Thanks! Nice Asset BTW!