Creating a simple particle effect mimicking fish boids was too easy, I wanted to have actual fishes in my environment that react to obstacles and surrounding fishes. This is the result of that side quest.
- This behaviour is a combination of C# scripts and an HLSL shader making fishes react to eachother, respect environment boundaries, avoid obstacles, maintain realistic orientation and maintain a good pace. The behaviour can be heavily tweaked to mimic multiple kinds of fishes at will.
- Each fish gets assigned a boid ID. They can only see and be seen by other fishes with the same ID. This both increases performance and stops for example clown fishes for trying to stick with a shark. Using this boid ID, we could create layered ecosystems of different fish types.
- The movement itself is a blend of forces. Noise-based wandering creates the first organic variation to avoid looping or robotic motion. A separation force pushes fishes away from eachother to avoid overlap. The alignment makes fishes gradually match their direction to that of nearby fishes. Using the cohesion force, fishes are gently pulled towards the center of their local group. This all together creates boids.
- Since this is made to have fishes swimming in the background for creating more immersion in the environment, I could not afford to lose any performance to this. Therefore, having every fish check for every other fish was not an option, and neither was having only ten fishes in the whole environment. Using the boid ID and a spatial grid, this problem is solved. Fishes are bucketed into 3D cells. Each fish only checks a capped amount of fishes in nearby cells.
- Fishes are "constrained" to a fishbowl. They can technically swim outside the fishbowl but will immediately start to steer back towards their fishbowl. Not having this hard snapping avoids artefacts at the edge of where the fishes are wanted. These fishbowls can be created, reassigned, moved and deleted at runtime. Every fish needs to have one fishbowl assigned, otherwise they will just roam around in an infinite void.
- The fish obstacles, are a kind of custom heavily optimized collider made specifically made for these fishes. Fishes already will detect these in front of them and steer away. On impact, they will actually get constrained out of the obstacle. This way hard forbidden zones are possible. The obstacles can be removed, moved and created at runtime, and handle their own presence in the global list.
This system was built for VR Base's upcoming game.
https://vrbase.be/
This work is inspired from Sebastian Lague's video on Boids, but is fully custom built by me for VR Base. models and albedo textures of fishes originate from Unity Asset Store and were heavily optimised in Houdini.
Fishes are grouped by ID, ignoring ones with any other ID.
Multiple fishbowls are possible. Fishes will only react to the fishbowl that is assigned to them. Gizmos visualize neighbours of a selected amount of fishes. These neighbours are only detected every n frames for a performance boost (flickering of gizmos)
Obstacles are injected in the global environment. All fishes will attempt to avoid them and possibly collide.
Obstacles can be created and moved at runtime
(or in editor before runtime of course)
fishes are animated using an HLSL shader. Each fish gets its own specific configuration
The animation if the fish itself is performed by a shader, applying three different rolling vertex transformations. A uniform side to side movement, layered with a rolling yaw rotation and a rolling roll rotation creates a realistic fish swim movement.