Implemented a crab simulation in OpenGL. Wrote custom shaders and a modified flocking algorithm to produce pixel-based agents with emergent, interactive behavior.
I’ll walk through both the initial concept and the most recent iteration of the system.
I call this iteration pixel crab because every pixel of the crab was drawn in the code. No textures were used, instead each square was defined and drawn with C++ or GLSL.
In this inital iteration, there were both fun implemenations of behavior as well as definite drawbacks.
Attributes such as size, spawn location, speed of the crabs were all randomly assigned to give each crab unique characteristics.
One of the shaders I wrote changed the colors with time as input. The rate of change and range of the colors were randomly generated for each crab. This is demonstrated on the left.
Crabs were given a custom flocking behavior. Defined attraction towards the mouse position (tracked through glfw inputs) as well as crab-to-crab repulsion.
An early implementation of the attraction behavior is shown on the left.
I hand-wrote integer bitmaps where the values correlated to different body parts and manually defined meshes for each individual pixel in VBOs.
Clearly, this implementation is incredibly inefficient for my purposes of rendering a static frame of a walk cycle to the screen. I addressed this issue in future versions.
This is a snippet of my vertex shader that shows where I was at in the beginning of my shader/OPENGL journey. It adjusts the transform of the leg pixels to create the walk animation.
If the nested if-statements aren't a blatant indication, my code was inefficient at this point. The upper threshold for number of crabs produced was in the order of hundreds. I changed the implementation to address this issue as will be seen below.
I call this one rectCrab because I rendered the crab sprites into a rectangle object. I defined the crab with a single VAO (rectangle) which allowed me to cut down on the number of VAOs per crab by over 200 (I previously stored a VAO for each pixel).
In addition to adding features, I refactored much of the original code for improved clarity and efficiency.
I modified the rendering approach of the crab so that I instead sampled each frame from a texture. Because I was no longer defining each animation frame with hand-written intermaps, this allowed me more flexiblity to create individual animations for different beahviors.
Some of these new beahviors are pictured to the left.
To more similarly emulate the movement of a crab, I removed the crab's ability to move directly toward a target position. Instead, the crab breaks down the movement into horizontal and vertical translations.
I also changed the crab's attraction behavior toward the mouse so that it no longer moved indefinitely to no 'end.'
I refactored almost all of my orignal code so that there was significantly better organization.
One example of this is shown on the left. I sampled the texture of my crabs from a single sprite sheet (containing all behavior animation frames) which required me to have better organization when storing and accessing data concerning these behaviors.
I am currently working to iterate a jump, parachute, and landing behavior/animation for the crab. The motion drifting downward with the parachute is simulated with a sinusoid.