← Return to Main OS

Shader Development

A technical breakdown of custom rendering solutions, Shader Graph implementations, and post-processing logic. Documenting the challenges, goals, and node-level solutions.

2D Wind Vertex Shader

The Goal

To breathe life into 2D environments (foliage, cloth) without relying on expensive CPU-based physical simulations or heavy skeletal animations. The solution needed to be fully processed on the GPU.

How It Works

Instead of animating the sprite, I built a Shader Graph that manipulates the object's vertices in real-time to simulate organic, rolling wind patterns.

  • Procedural Noise: Driven by a Gradient Noise node combined with Time and Speed parameters to generate the waving force.
  • UV Masking (The Anchor): The core challenge was keeping the bottom of the plants attached to the ground. I split the UV coordinates and used the vertical gradient as a mathematical mask.
  • Vertex Displacement: By multiplying the noise output by the UV mask, the displacement force drops to zero at the root, while the top receives the full sway. This data is injected into the X-axis of the Vertex Position.
  • GPU Performance: Moves all wind calculations entirely to the GPU, ensuring zero overhead on the CPU logic thread.
🎮 View Project: Lumen
2D Wind Shader Graph Logic

Sobel Outline & Edge Detection

The Goal

Fast-paced melee combat requires excellent visual readability. The goal was to create a striking, comic-book aesthetic that draws thick, stylized outlines around characters and environmental hazards to make silhouettes pop.

How It Works

I utilized a Full-Screen Render Feature to apply the effect globally across the camera view, utilizing a custom dual-shader approach.

  • HLSL Integration: Relies on a custom HLSL Sobel function node setup to mathematically trace hard geometric edges and creases.
  • Normal & Depth Sampling: Samples the URP Normal Buffer and depth data based on screen position to accurately detect where object silhouettes begin and end.
  • Full Screen Post-Process: Because outlines are calculated dynamically as a full-screen pass, the performance cost remains stable regardless of the physical polycount in the scene.
🎮 View Project: Knuckle
Sobel HLSL Setup Normal Buffer Sampling

Thermal Vision (X-Ray)

The Goal

Developed specifically for the gunner role in an asymmetric multiplayer game. The gunner needed a high-contrast thermal view capable of spotting enemy heat signatures through physical walls and geometry.

How It Works

Built as a URP Full Screen Render Feature, this shader processes object tags and world data into a high-contrast thermal image.

  • Layer Masking: Implements strict layer and tag separation to accurately identify and isolate enemy data from the surrounding environmental geometry.
  • X-Ray Depth Logic: Intentionally bypasses standard depth culling for designated layers. This allows enemy heat signatures to render flawlessly on top of physical walls and cover.
  • Global Rendering: Applying the post-processing logic globally ensures visual consistency across the entire viewport without attaching scripts to individual enemies.
🎮 View Project: Rotor Warfare
Thermal Vision Render Pass

Dynamic Impact Frames

The Goal

To drastically improve the sense of weight and "punchiness" during heavy combat. The visual feedback needed to sync perfectly with the game's mechanical hit-stop (time freeze) logic.

How It Works

Unlike continuous ambient shaders, this is a highly targeted event tied directly to the combat state machine.

  • C# Integration: Triggered dynamically via C# scripts during specific hit-stop animation frames upon a successful heavy attack.
  • Material Overrides: Overrides standard materials momentarily to flash the screen with high-contrast, stylized impact colors, before seamlessly returning materials to their standard state.
  • Artistic Control: Exposes color clamping properties to the inspector, allowing artists to easily tweak the intensity of physical hits without editing code.
🎮 View Project: Knuckle
Impact Frame Gameplay Impact Frame Shader Logic