Sofia Sorace - Portfolio

Procedural Jellyfish



Procedural Content Generation - Jellyfish Customisation

In gaming, 3D character and creature models often focus on familiar archetypes like humanoids and dragons, leaving intriguing designs like jellyfish largely underrepresented. Their diverse textures and fluid, sine-wave movements make jellyfish ideal candidates for Procedural Content Generation (PCG).

The initial aim of this project was to create a jellyfish customization game using UI sliders for real-time adjustments. As development progressed, the project evolved to include multiple updates that enhance technical efficiency, such as an API for streamlined asset management and an array of jellyfish clones to populate the environment. These features not only optimize performance but also enable a rich variety of jellyfish while minimizing file size and resource usage, showcasing the powerful capabilities of PCG in game development.

Skills Gained:

The sea Nettle jellyfish:
The portuguese man o' war jellyfish:
3D models concept art inspired from the jellyfish above:



Materials

In developing the jellyfish textures, I focused on enhancing my expertise with material nodes (specifcially, learning the ‘Parallax occlusion Mapping’ and ‘Fresnel’ nodes) and exploring advanced techniques for generating unique visual effects. My objectives included creating a realistic jellyfish texture that captures its characteristic transparency, along with more striking and visually appealing options designed to attract players, such as the camouflage material, inspired by the mimic octopus.

Most common jellyfish texture:
Example of chrome metal:
The mimic octopus:



Regular:
Chrome:
Rock:
Camouflage:
Gif of camouflage material:

With numerous unique customizable variables, such as color, animation speed, transparency, and pattern manipulation, my effective and optimised use of PCG textures allow for multiple jellyfish variations with minimal disk space usage.



Movement

Jellyfish move in flowing, sine-like motions, making vertex displacement—a branch of PCG—ideal for capturing this behaviour. This technique enables organic, fluid movements while minimising disk space. Therefore, I created 3 different animations using this method.

Asymetrical sine wave:
Sine nodes producing drift:
Gif of 'Drift' effect:

Reverse linear fall off sine wave:
Rotation nodes:
Gif of 'Twist' effect:

Screenshot from Hoover's essay, showing jellyfish propultion & sine wave motion:

Absolute sine wave:
Tapering function:
Sine nodes producing bounce:
Gif of 'Bounce' effect:

The final 3 vertex displacement movements:

By leveraging multiple sine equations and advanced mathematical methods, I created numerous animation variations with customizable parameters, allowing for a multitude of unique possible outcomes.



Profiling & Optimization

An experienced technical artist recommended that I improve my equations, and through GPU profiling, I found that a populated scene with these equations was indeed impacting performance. By consolidating all calculations into a single sine equation, I successfully optimized my movement blueprints. While the unoptimized equations had only a slight effect on frame rates, this practice is crucial for maintaining sustained performance in larger-scale games.

Example of movement equation before optimization:
GPU profiling before:

Example of movement equation after optimization:
GPU profiling after:



UI Sliders - What if there were 100 jellyfish models and textures?

During an interview, I was challenged with a crucial question: how could my code accommodate 100 jellyfish models for an MMO open-world setting? At that time, my approach relied on copy-pasting code for each jellyfish (in my case, 2 models), which was neither efficient nor scalable. Therefore, I set out to completely restructure my codebase.

For the sliders, users can cycle through several widgets, each controlling specific materials and their variables. Initially, I repeated code for the light switch and buttons within each widget. To eliminate this redundancy, I added a separate “select model” widget that remains fixed on top, consolidating all controls for jellyfish model selection and lighting.

'Select Model' widget:
Example of material widget:

To accomodate 100 jellyfish, I used a static variable that would update to whichever jellyfish is currently being displayed. This is possible as all relevant variables share the same name. All of the jellyfish models and textures are stored in a list array that an artist could comfortably edit. As my game currently uses buttons, when a jellyfish button is selected, its corresponding index is called from the list array, updating the static variable. Of course, a keyboard input or number-insert system could easily be used in its place.

Code in a material widget before the restructure:
Code in a material widget after the restructure:
List array of jellyfish models & textures:
Jellyfish model button selection code:


This newer method allows the user to instantiate multiple, unique jellyfish with much fewer lines of code. This improvement not only streamlined the implementation process but also significantly improved performance, allowing for a cheap, intuitive method to populate an environment.

Environment

In developing the environment for the jellyfish, I aimed to create a underwater atmosphere that would compliment the jellyfish models & MMO scenario

I created a PCG sand texture and a Post Processing volume (PPV) to create an underwater atmosphere with animated sand rays and a disappearing render distance. I also added a daytime/night-time switch to better view emissive customisation options. Finally, I created god rays; they were made using simple geometric shapes & a PCG material. I created different instances with out of sync sine values to create a seemingly random scattering-light effect.

Gif of sliders being used:
Scene with light-off button active:
Gif of cheap godrays:

The sand texture and PPV enhance the environment while cleverly masking the small loaded area, conserving disk space. Meanwhile, the god rays provide a visually effective and cost-effective alternative to Unreal’s more expensive environment light mixture effects.



Jellyfish Clone System

As mentioned, users can populate their environment with custom jellyfish. I included this feature to showcase how artists could utilize my project to fill a space with NPCs or allow players to save their personalized jellyfish creations.

To do this, I used an array and velocity script. The submitted jellyfish is cloned, with the clone containing a random velocity that changes direction if colliding with an invisible wall, to avoid jellyfish leaving the area. The clone is also added to an array list that deletes that oldest list item once 10 items have been added, to avoid overcrowding. This creates an intuitive, easily editable set up for an artist to use or for a player, of any specs, to admire their creations.

Velocity calculated through the 'Euler Method' equation.:
List array of all clones, maxing at 10 jellyfish:
Gif of completed Jellyfish being added into the background:



Conclusion

This extensive project began as my final project for a computing MA and has since undergone numerous updates as my technical art and programming skills have evolved. After utilizing Unreal Engine’s colorblind testing feature and adding several original soundtracks, my jellyfish program was complete. With optimized movement equations, an API for jellyfish models and textures, an enhanced environment, numerous stored materials & movements all within a zipped file size of under 100MB, I take great pride in this project as it demonstrates essential skills in both programming and technical art.