Hi guys! Paul and Cyrille join me to wish you all a Happy New Year! 🙂
This update is going to be essentially a technical one (it’s been a while I haven’t done any of those). I received many questions regarding the new vegetation system in Ghost of a Tale, which was introduced in the latest build. So I will now attempt to answer them.
Caveat Emptor: this technique is used on PC and Xbox One/PS4 (I haven’t applied it to any other platform yet).
(Also: yes, the game is running on Unity 🙂 )
The reason why I developed this system is because I don’t like it when I see vegetation behaving like the vertex are warping and stretching unnaturally around a sphere or capsule shape (even in AAA games). If I were a shader wizard maybe I would have come up with a super smart shader that would give me what I need, alas I’m not. So I had to find another way… 🙂
The main idea is what happens around Tilo should be high quality while the rest should stay as cheap as possible (nothing new here).
In this example the fern objects are made of two models:
- A static one (a simple mesh with usual LODs)
- A dynamic one (same model as LOD0 but the stems are skinned to a couple of joints). Technically each stem only uses 2 bones (the end one is not part of the skinning).
The dynamic models are deactivated by default, leaving only the cheap static ferns visible. No script is running in the background so there’s no overhead.
The root game object has a simple static box collider trigger. When Tilo enters the trigger that’s the signal that we should switch to the dynamic model.
Since the static and dynamic models have the same pivot point it means the wind animation (vegetation shader) is exactly the same on both meshes. So there is no visual pop whatsoever when switching between the models.
The dynamic model has a kind of “fake physics” (using this great asset) which acts as colliders on the stems’ joints. Those colliders collide with the actors’ limbs (head, chest, waist, etc…). Note: In this case I reuse the actor’s colliders from the game’s dynamic props system, so there’s no additional colliders to create (always reuse whenever possible!).
What this gives me is more accurate detection in that if a character plays an idle animation while remaining in contact with the fern, the stems will still react fairly precisely. In other words this is not a simple “capsule” avoidance.
So when Tilo is within the trigger the fern’s dynamic (skinned) model is visible, but when Tilo leaves the trigger then after a second or so -long enough for the fern to settle down- we switch back to the cheap static model.
Again, there is absolutely no visible pop during the change because the “rested” dynamic model and the static one have perfectly matching vertices positions.
There is a couple more details to keep in mind: I use a special vegetation shader (written by shader wizard Larsbertram) that produces translucency but uses the deferred rendering path (whereas normally you would have to use a slower forward rendering path).
A second important point is that I don’t use OnTriggerStay in the trigger detection process. I only use OntriggerEnter and OnTriggerExit. The reason is OnTriggerStay can prove quite heavy (depending on your physics matrix) and we don’t really need it. All we need is to be notified when Tilo enters and leaves the trigger.
There is also the tricky case where Tilo would have left the trigger (for whatever reason) without calling OnTriggerExit. Which is a fairly rare situation but it could happen. To remedy this case I use an Update function on the vegetation bend behavior script which tests from time to time (every couple of seconds) if the distance between the actor and itself (in this case the fern) is greater than a certain threshold. If it is then we know for sure we should switch back to the static model.
Of course that component only becomes active while Tilo is within the trigger. And it ensures we don’t accidentally leave some vegetation items in “high-quality” mode.
That’s it for this update! I will keep converting a lot of the game’s vegetation over the next build updates but some assets will remain “dynamic-but-rigid” (meaning non-skinned/rotation only) as they don’t require as much detail.
I hope this answered any questions you guys might have had regarding this topic, and I genuinely hope it didn’t bore you to tears. See you in the next update! 🙂