Sunday, November 11, 2018

unity - How can one replicate the 'Quake Disruptor' of Wipeout XL/2097?


Following my previous question, I am wondering how one can achieve the same effect under Unity?



enter image description here


https://youtu.be/kzmmLeCwL0g?t=790




When you fire the Quake Disruptor weapon, it creates a sine wave that mimics an earth quake, it happens over the next track sections forward to the player ship as you can see on the small video. This results in instant-damage and slowdown to the ships that are caught in the quake.



Deforming the mesh


The function for generating a quake-like wave to apply to each section of the track mesh is easy, e.g. a Gaussian filter will probably be good enough:


enter image description here


https://www.desmos.com/calculator/goasdepcmv


Applying the deformation to mesh


This is where it starts to get trickier, a track is made out of sections that have few faces, each face being nothing more than a quad.


Here you can see three sections and their faces (wall, track, track, wall):


enter image description here



The challenge in here is how to apply the deformation and yet being able to check collisions against the track (remember that we can't use a mesh collider since it'll be updated in real-time).


I first thought that subdividing the mesh using tessellation would be needed to apply smooth deformations, hence my previous question. However, if you look closely at the video they simply move either edge of faces according to where they're against the 'quake' function being applied to the track mesh.


Here's a link to a video with the best quality, around 13 mins 10 secs:


https://archive.org/details/PSX_Longplay_243_Wipeout_2097


We're getting closer but we still need to be able to check for collisions.


Being able to still collide against the track


This is the big question mark, since we cannot update a mesh collider in real-time as it's a CPU hog, I really have no idea on how to address this part of the problem.


This also leads to another problem, since we cannot use a mesh collider, how are physics are going to be handled, by writing a physics system from scratch ?



How can such effect be achieved under Unity, if possible at all?



PS You will want to remember that the PS1 had a 33Mhz CPU and certainly no mesh collider like the one we can find in Unity, yet they achieved to do it. For sure there is a trick involved but I couldn't figure it out.



Answer



This effect is almost certainly not achieved by reshaping a mesh collider.


In fact, it's very unlikely Wipeout even used what we'd recognize as a mesh collider for its track. If you have such a constrained problem case, you can use much simpler approaches.


I don't have any information about the game's internals, but I'd suspect they store their track as something a bit more like a spline. If you know a given car's progress "forward" around the racetrack, and a lateral position between the track's left and right edge, you can efficiently evaluate the (collection of) spline(s) at that parameter index to compute the height, bank angle, etc. of the terrain under that point sample.


The fact that the vehicles hover means a point sample is enough - you don't need to simulate a wheeled vehicle rolling until all its wheels are in contact - the banking of the ship can be a purely visual effect as a function of the track's banking and the player's steering.


Now, if we want to add a sine wave, we can literally do exactly that: calculate a sinusoidal function of that same "around the track progress" parameter, and add it to the height we got from the spline. You can do the same with its derivative to bias the calculated slope of the track accordingly.


Now, in Unity, you probably don't want to create your own whole new track physics model just to imitate an older game, so building on a mesh collider is not a bad start.


We can still draw inspiration from the method outlined above, and think of it as an additive force:


Create a kinematic trigger volume to represent the area of effect of your wave, and push it along your track at the desired speed to match the visual progression of the wave (that you're applying in the vertex shader, likely - you could even use this trigger object's transformation matrix as an input to the shader to keep the two exactly in sync). For all bodies touching this trigger, calculate their proximity to the wave shape, and apply a force that pushes them outward, away from the wave surface, proportionate to their proximity.



Or, if your vehicle hover behaviour is based on a raycast at a distance, you could have them detect a raycast intersection with a collider representing a "distortion decal" - if they hit such an object, then instead of using the raycast hit position/distance/normal to determine your hovering force, they instead ask the distortion decal component, "where should I pretend the ground is?" and it can reply using any custom shape function it likes. Then the rest of the hover forces are computed just as though that was the real ground position returned by the raycast - as far as the code downstream is concerned, you really did distort the collider in realtime. It doesn't need to know you just computed an offset with some sinusoidal math. ;)


(The upshot: in games, beware the temptation to believe that what's driving the logical simulation is the same thing you see on the screen as a player - these two things very rarely have much to do with each other in the underlying code/data, and it's an act of delicate choreography that makes them look consistent with one another)


No comments:

Post a Comment

Simple past, Present perfect Past perfect

Can you tell me which form of the following sentences is the correct one please? Imagine two friends discussing the gym... I was in a good s...