This page uses several animated GIFs to show effects in motion. These may take time to load and play at real time
Shaders give more options for both graphics and gameplay possibilities, offloading heavy computations from the CPU onto the GPU via Graphics API. My work includes SPH fluid simulations, paintable walls, LiDAR scanners, water surfaces, shell textured grass, and bottled liquids.
Smooth Particle Hydrodynamics

Using Compute Shaders
Using a compute shader, it is possible to simulate a body of water by representing it as a discrete number of particles with a position, mass, and viscosity. The Navier-Stokes Equations (everyone’s favorite, discrete calculus!) are used to apply forces.
Link to the GitHub repo.

Optimizations
To maximize performance, we need to do more than just handing the GPU the computation. We use spatial hashing proposed by Nvidia to save us from having to compare every point to every other point, lowering runtime notation to O(n).
We also precalculate and store needed values like radius2 to minimize GPU calculations.

Outside Collision
While running the simulation on the GPU is incredibly performant, it prevents interactions with the system through game objects and Unity’s built in physics system. Collider data is sent to the compute every frame through a structured buffer and then collisions are calculated. Sphere and Cube colliders are the only currently supported.
Busing data from the CPU to the GPU is inherently slower, and should be kept to a minimum.


Ocean Surface Simulation

Creating A Wave
Using the vertex world positions of a flat mesh as an input, we can calculate an output to apply to a vertex’s height, creating waves. A sin wave was the original used equation, but switching to a wave based off of esin(x) created sharper peaks and longer troughs.
The normals are then calculated by taking the partial derivatives (known as the binormal and tangent) into a normalized vector.
Link to the GitHub repo.

Visualizing Simulation
After predefining a few waves, a C# script is used to generate additional waves and send them to a StructuredBuffer in the shader. Making every additional wave have less amplitude and a greater frequency, allows for more nuanced, detailed results.
GPU instancing is used to draw in the mesh to a predefined distance, and makes it easy to cull polygons not visible to the camera.

Physics Objects
Creating buoyant objects that interact with the ocean leads to an issue. The shader is running on the GPU while physics runs on the CPU. By tracking the variables sent to the shader, the calculations can be performed again on the CPU on positions along the object to determine where the object sits along
Applying a buoyancy force if those points are below the water’s surface keeps the object above water.
Several checks are done on the object to ensure its rotation and positional drift are kept within a specified bounds. While this breaks physical accuracy, it ensures a better gameplay experience by making results be more reliable.

Objects Interact With Simulation
By giving physics objects a way to impact the visuals of the water surface simulation, those objects begin to feel like they belong in the scene, creating a greater sense of cohesion.
Using VFX only visible to an overhead camera, a RenderTextures, and shaders to edit the created image, ripples and wakes can be added to the ocean surface as a normal map, impacting the lighting calculations.
Paintable Surfaces

Splatoon Ink
A recreation of ink painting from Splatoon. It uses a surface point, determined by a raycast, and then converts it to UV space for RenderTexture painting. The RenderTexture is applied as a mask to the surface, allowing us to add more effects like specularity, normal maps, and a subtle AO on the edges.

LiDAR Scan
Using the knowledge I gained from the ink, I created a LiDAR scanner effect. Similarly, it uses raycasts to find points in 3D space and then passes the position data over to a VFX graph as an array of colors.


Visual Shaders
Clay Finish
A simple shader to give models a clay-like appearance with thumbprints and creases inside of Unity. I created a blender addon to generate normal and roughness maps quickly.

Stylized Water & Shell Texture Grass
Sampling and scrolling a single noise texture several times, overlapping the result, and then applying multiple clipping masks creates a pleasing water surface effect. The ground below is then distorted with another shader, creating a shallow bodies of water effect, similar to the look of Super Mario Galaxy.
A shell texture grass with wind was also added to the scene.

Bottle Fluids
This shader creates the effect of fluid in a bottle. It maintains volume as the bottle is rotated, the surface wobbles with momentum, and the fill percentage is controlled with a single slider.







