Skip to main content

2 posts tagged with "Shader"

Graphics programming and visual effects.

View All Tags

Advanced Vertex Displacement for Flesh & Gore

· 2 min read
Thang Le
Senior Lead Engineer

Flesh and Gore

The Art of Visceral Realism

In modern horror game development, the "feel" of an environment is often just as important as its visual fidelity. When it comes to organic, fleshy surfaces—think of the pulsating walls in a biological nightmare or the squishy impact of a weapon on a monster—standard static meshes often fall short. This is where Advanced Vertex Displacement comes into play.

Using Unity's Universal Render Pipeline (URP) and Shader Graph, we can move beyond simple texture swaps and into the realm of dynamic, responsive geometry. By manipulating vertex positions in real-time, we create an illusion of depth and movement that feels unsettlingly real.

The Mathematics of Pulsation

The core of a good "flesh" shader is the combination of multiple sine waves operating at different frequencies and amplitudes. We don't want a uniform pulse; that feels mechanical. Instead, we use a Noise-Driven Displacement approach. By sampling a Perlin or Simplex noise texture and using it to offset the vertex normal, we achieve that irregular, organic heaving that characterizes living tissue.

// Conceptual logic for vertex offset
float3 offset = normal * noiseValue * displacementStrength;
positionOS.xyz += offset;

Implementing in URP Shader Graph

  1. Vertex Position Node: Start by getting the object-space position.
  2. Normal Vector Node: Displacement should almost always happen along the vertex normal to maintain the volume's integrity.
  3. Time-Based Noise: Use a Time node multiplied by a speed constant to scroll a 3D noise function.
  4. Tessellation (Optional): For high-end hardware, adding hardware tessellation allows for much finer detail without requiring incredibly dense base meshes.

Performance Considerations

Vertex displacement is computationally cheaper than some might think, especially when handled entirely on the GPU. However, the biggest bottleneck is often Shadow Mapping. Displaced vertices must also be accounted for in the Shadow Caster pass, otherwise, the shadows will remain static while the mesh pulses, breaking the immersion. Ensure your Shader Graph has the "Shadow Caster" pass properly configured to use the same displacement logic.

By layering these techniques with subsurface scattering and a high-quality specular map (to give that "wet" look), you can create environments that don't just look scary—they feel alive.

Volumetric Fog in URP: A Deep Dive

· 2 min read
Thang Le
Senior Lead Engineer

Volumetric Fog

The Atmosphere of Dread

Fog is a staple of the horror genre, famously used in Silent Hill to mask hardware limitations. Today, however, fog is a deliberate stylistic and atmospheric choice. Volumetric Fog—fog that interacts with light sources and casts shadows—is the gold standard for creating "thick" atmosphere.

Raymarching: The Engine of Volume

Most volumetric fog systems in modern engines like Unity URP rely on Raymarching. The shader "marches" a ray from the camera into the scene, sampling the light and density at various points along that ray.

The challenge is the sheer number of samples required. A naive implementation will tank the frame rate. To optimize this, we use a Froxel-based approach (Frustum Voxels). By dividing the camera frustum into a 3D grid of voxels, we can pre-calculate the lighting for each voxel once per frame and then simply sample that grid during the main rendering pass.

Optimizing for URP

Unity's URP doesn't include a robust volumetric fog out of the box (unlike HDRP). To implement this effectively, we use Scriptable Render Features.

  1. Downsampling: Render the volumetric effect at a lower resolution (e.g., half or quarter res) and then upsample it using a bilateral filter to preserve edges.
  2. Temporal Reprojection: Use data from the previous frame to "fill in the blanks," allowing for fewer samples per frame while maintaining a smooth look.
  3. Phase Function: Implementing a Henyey-Greenstein phase function allows for realistic forward and backward scattering, making the fog "glow" when a light source is behind it.

Strategic Implementation

In horror, fog isn't just about visibility; it's about what it hides. By dynamically adjusting fog density based on player location or sanity levels, you can create a shifting sense of claustrophobia. For example, as the player's "Fear" meter rises, the fog's Extinction coefficient can increase, pulling the "wall of mist" closer to the player.

Performance-wise, always keep an eye on your Overdraw. Thick volumes of fog can overlap with other transparent effects (like particles), leading to significant GPU pressure. Balancing the Froxel resolution with the camera's far clip plane is the key to maintaining 60 FPS on mid-range hardware.