Featured Article

Deep Dive: Understanding the 4 Preset Shaders

Volume Shader Team
2025-11-09
10 min read
556 views
Presets
Ray Marching
Tutorial
GLSL
Deep Dive: Understanding the 4 Preset Shaders

Our Shader Editor provides 4 carefully designed preset effects that are not only visually stunning but also excellent examples for learning Volume Shader development. Let's dive deep into the code and analyze the implementation principles of each preset 🚀

Table of Contents


1. Fog Sphere - Volumetric Fog Ball ☁️

Difficulty: ⭐⭐☆☆☆ Beginner Performance: 96 ray marching steps, medium performance cost Core Techniques: Ray Marching + Signed Distance Field

Effect Description

A volumetric fog effect rotating around a central sphere, with fog density decreasing from the sphere's center outward, creating a soft volumetric appearance.

Core Code Analysis

1. Signed Distance Field Definition

float sdSphere(vec3 p, float r) {
  return length(p) - r;
}

float map(vec3 p) {
  // Central sphere as density source, radius 0.7
  float d = sdSphere(p, 0.7);
  return d;
}

Here we use SDF to define a sphere. SDF returns the shortest distance from any point in space to the surface:

  • Negative value: Point is inside the sphere
  • Zero: Point is on the sphere surface
  • Positive value: Point is outside the sphere

2. Camera and Ray Setup

vec3 ro = vec3(0.0, 0.0, -2.5);  // Camera position
vec3 rd = rayDir(uv, 60.0);       // Ray direction, 60° field of view

// Scene rotation animation
float a = u_time * 0.3;
mat2 R = mat2(cos(a), -sin(a), sin(a), cos(a));
ro.xz = R * ro.xz;
rd.xz = R * rd.xz;

By rotating both camera position and ray direction, we achieve the entire scene rotation effect.

3. Ray Marching Main Loop

for (int i = 0; i < 96; i++) {
  vec3 p = ro + rd * t;              // Current sampling point
  float d = map(p);                   // Distance to sphere surface
  float density = clamp(0.7 - d, 0.0, 1.0);  // Density calculation
  fog += density * 0.04;              // Accumulate fog density
  t += 0.03 + density * 0.02;         // Adaptive step size
  if (t > 6.0) break;
}

Key Techniques:

  • Density Mapping: 0.7 - d converts distance to density, highest at sphere center
  • Adaptive Step Size: Smaller steps in high-density areas (+ density * 0.02) for better quality
  • Early Termination: Stop when ray travels far (t > 6.0) to save computation

4. Color Mapping

col = mix(
  vec3(0.05, 0.08, 0.12),  // Deep blue background
  vec3(0.3, 0.8, 1.0),     // Cyan fog
  clamp(fog, 0.0, 1.0)
);

Optimization Tips

  • Add Detail: Add noise function to perturb density
  • More Layers: Use multiple spheres of different sizes
  • Color Variation: Adjust color based on height or density

2. Twirl Smoke - Swirling Smoke 🌀

Difficulty: ⭐⭐☆☆☆ Beginner Performance: 2D noise, excellent performance Core Techniques: 2D Noise + Polar Coordinates

Effect Description

A smoke effect based on 2D noise, using polar coordinate transformation to create swirling distortion, forming dynamic flowing smoke patterns.

Core Code Analysis

1. Hash and Noise Functions

float hash(vec2 p) {
  p = fract(p * vec2(123.34, 345.45));
  p += dot(p, p + 34.345);
  return fract(p.x * p.y);
}

float noise(vec2 p) {
  vec2 i = floor(p);   // Integer part
  vec2 f = fract(p);   // Fractional part
  f = f * f * (3.0 - 2.0 * f);  // Smoothstep interpolation curve

  // Bilinear interpolation
  float a = hash(i);
  float b = hash(i + vec2(1, 0));
  float c = hash(i + vec2(0, 1));
  float d = hash(i + vec2(1, 1));

  return mix(mix(a, b, f.x), mix(c, d, f.x), f.y);
}

This is a classic 2D Perlin noise implementation using bilinear interpolation for smooth transitions between grid points.

2. Polar Coordinate Swirl Transformation

vec2 p = (uv * 2.0 - 1.0);
p.x *= u_resolution.x / u_resolution.y;  // Aspect ratio correction
float r = length(p);
float ang = atan(p.y, p.x)               // Original angle
        + 0.8 * sin(u_time * 0.5)        // Global rotation
        + 2.5 * r;                        // Radial distortion

Key Points:

  • atan(p.y, p.x): Converts Cartesian coordinates to polar angle
  • + 2.5 * r: Further from center = stronger distortion, creating the swirl
  • + 0.8 * sin(u_time * 0.5): Overall rotation animation

3. Noise Sampling and Coloring

vec2 q = vec2(cos(ang), sin(ang)) * r * 1.5 + 0.15 * u_time;
float n = noise(q * 3.0) + 0.5 * noise(q * 6.0);  // Multi-frequency layering
float smoke = smoothstep(0.35, 0.9, n);
vec3 col = mix(vec3(0.05, 0.08, 0.12), vec3(0.8, 0.9, 1.0), smoke);

Techniques:

  • Multi-frequency Noise Layering: noise(q*3.0) + 0.5*noise(q*6.0) adds detail layers
  • Time Offset: + 0.15*u_time makes smoke flow
  • Smoothstep Smoothing: Controls the softness of smoke edges

Optimization Tips

  • Adjust Distortion Strength: Modify the coefficient in 2.5 * r
  • Change Flow Speed: Adjust the coefficient in 0.15 * u_time
  • Add Turbulence: Add more noise at different frequencies

3. Cloud Layer - 3D Clouds ☁️

Difficulty: ⭐⭐⭐☆☆ Intermediate Performance: 64 steps of 3D ray marching Core Techniques: 3D Noise + Volume Accumulation

Effect Description

True 3D volumetric cloud layer rendering. Ray marching through a 3D noise field, accumulating cloud density to create realistic cloud layer effects.

Core Code Analysis

1. 3D Hash and Noise

float hash(vec3 p) {
  p = fract(p * 0.3183099 + 0.1);
  p *= 17.0;
  return fract(p.x * p.y * p.z * (p.x + p.y + p.z));
}

float noise(vec3 x) {
  vec3 p = floor(x);
  vec3 f = fract(x);
  f = f * f * (3.0 - 2.0 * f);  // Smoothstep

  // Trilinear interpolation (8 vertices)
  float n = mix(
    mix(mix(hash(p+vec3(0,0,0)), hash(p+vec3(1,0,0)), f.x),
        mix(hash(p+vec3(0,1,0)), hash(p+vec3(1,1,0)), f.x), f.y),
    mix(mix(hash(p+vec3(0,0,1)), hash(p+vec3(1,0,1)), f.x),
        mix(hash(p+vec3(0,1,1)), hash(p+vec3(1,1,1)), f.x), f.y),
    f.z
  );
  return n;
}

3D noise uses trilinear interpolation to smoothly interpolate between the 8 vertices of a cube.

2. Ray Marching Loop

vec3 ro = vec3(0.0, 0.0, -1.8);  // Camera position
vec3 rd = normalize(vec3(uv, 1.0)); // Ray direction
float t = 0.0, dens = 0.0;

for(int i = 0; i < 64; i++) {
  vec3 p = ro + rd * t;
  float h = noise(p * 1.5 + vec3(0.0, 0.0, u_time * 0.15));
  dens += smoothstep(0.55, 0.9, h) * 0.03;
  t += 0.03;
  if(t > 3.0) break;
}

Key Techniques:

  • p * 1.5: Controls cloud scale (higher coefficient = denser clouds)
  • + vec3(0,0, u_time*0.15): Movement along Z-axis simulates wind
  • smoothstep(0.55, 0.9, h): Density threshold, only noise values above 0.55 appear as clouds
  • * 0.03: Density accumulation per step

3. Color Mapping

col = mix(
  vec3(0.05, 0.07, 0.11),  // Dark background (night sky)
  vec3(0.9),               // White (clouds)
  clamp(dens, 0.0, 1.0)
);

Optimization Tips

  • Cloud Shape: Adjust the threshold in smoothstep(0.55, 0.9, h)
  • Cloud Density: Modify the accumulation per step * 0.03
  • Wind Speed: Change the coefficient in u_time * 0.15
  • Add Lighting: Add simple directional light in dense areas

4. 3D Fractal - Fractal Rendering 🌟

Difficulty: ⭐⭐⭐⭐⭐ Advanced Performance: 100 steps of ray marching + complex fractal calculations Core Techniques: Fractal Kernel + Normal Calculation + Phong Lighting

Effect Description

The most complex preset, rendering a 3D fractal structure (similar to Mandelbulb) with full lighting and specular reflections, demonstrating advanced shading techniques.

Core Code Analysis

1. Fractal Core Algorithm

float fractalKernel(vec3 ver) {
  vec3 a = ver;
  float b, c, d;

  for(int i = 0; i < MAXITER; i++) {  // MAXITER = 5
    b = length(a);
    if(b > MAXDIST) break;  // MAXDIST = 6.0

    // Spherical coordinate transformation
    c = atan(a.y, a.x) * 8.0;           // Azimuthal angle * 8 (8-fold symmetry)
    d = acos(clamp(a.z / b, -1.0, 1.0)) * 8.0;  // Polar angle * 8
    b = pow(b, 8.0);                    // 8th power transformation

    // Remap to Cartesian coordinates and accumulate
    a = vec3(
      b * sin(d) * cos(c),
      b * sin(d) * sin(c),
      b * cos(d)
    ) + ver;
  }

  return 4.0 - dot(a, a);
}

Mathematical Principle: This is an 8th power fractal (a variant similar to Mandelbulb):

  1. Convert point to spherical coordinates (r, θ, φ)
  2. Apply transformation: r' = r^8, θ' = 8θ, φ' = 8φ
  3. Convert back to Cartesian coordinates and add original position
  4. Iterate 5 times, each iteration continues the transformation on the previous result

Why 8? The 8th power and 8× angles produce 8-fold symmetry, creating complex geometric patterns.

2. Normal Calculation

vec3 getNormal(vec3 p) {
  float eps = 0.001;
  return normalize(vec3(
    fractalKernel(p + vec3(eps, 0, 0)) - fractalKernel(p - vec3(eps, 0, 0)),
    fractalKernel(p + vec3(0, eps, 0)) - fractalKernel(p - vec3(0, eps, 0)),
    fractalKernel(p + vec3(0, 0, eps)) - fractalKernel(p - vec3(0, 0, eps))
  ));
}

Uses central difference method to calculate gradient, obtaining surface normal vector. This is the standard method for computing normals of implicit surfaces.

3. Dynamic Camera System

float t = u_time * 0.2;
vec3 origin = vec3(sin(t) * 3.0, cos(t * 0.7) * 2.0, -5.0);
vec3 target = vec3(0.0, 0.0, 0.0);
vec3 forward = normalize(target - origin);
vec3 right = normalize(cross(forward, vec3(0.0, 1.0, 0.0)));
vec3 up = cross(right, forward);
vec3 dir = normalize(forward + right * uv.x + up * uv.y);

Constructs complete camera matrix to achieve orbital motion around the fractal.

4. Phong Lighting Model

vec3 normal = getNormal(pos);
vec3 lightDir = normalize(vec3(0.276, 0.920, 0.276));
vec3 viewDir = -dir;
vec3 reflectDir = reflect(-lightDir, normal);

float diffuse = max(0.0, dot(normal, lightDir));
float specular = pow(max(0.0, dot(viewDir, reflectDir)), 16.0);

Lighting Breakdown:

  • Diffuse: dot(normal, lightDir) Lambert's cosine law
  • Specular: pow(..., 16.0) Phong highlight, 16 is shininess

5. Position-Based Coloring

float colorPattern = dot(pos, pos) * 10.0;
vec3 surfaceColor = vec3(
  sin(colorPattern) * 0.5 + 0.5,
  sin(colorPattern + 2.094) * 0.5 + 0.5,  // 2π/3 phase offset
  sin(colorPattern - 2.094) * 0.5 + 0.5
);

Uses sine waves to generate rainbow colors, 120° phase offset produces RGB cycling.

Optimization Tips

  • Increase Detail: Raise MAXITER to 7 or 8 (performance cost)
  • Change Shape: Modify power (8.0 to 6.0 or 10.0)
  • Adjust Colors: Change colorPattern frequency or phase
  • Different Lighting: Try multiple lights or ambient lighting

Performance Comparison & Selection Guide ⚡

Preset Iterations Complexity FPS (Est.) Use Case
Fog Sphere 96 steps Medium ~60 FPS Learn ray marching basics
Twirl Smoke 0 (2D) Low ~120 FPS High performance, mobile
Cloud Layer 64 steps Medium ~50 FPS Realistic clouds, weather
3D Fractal 100 steps + complex High ~30 FPS Art showcase, desktop

Selection Recommendations:

  • 🚀 Performance Priority: Twirl Smoke
  • 🎓 Learning Basics: Fog Sphere
  • ☁️ Practical Effects: Cloud Layer
  • 🎨 Visual Impact: 3D Fractal

How to Modify and Extend 🛠️

1. Open Presets in Editor

Visit the Presets page and click "Open in Editor" on any preset.

2. Real-Time Parameter Modification

Try modifying these parameters to observe effect changes:

Fog Sphere:

  • Sphere radius: sdSphere(p, 0.7)sdSphere(p, 1.2)
  • Step count: for (int i = 0; i < 96; i++)for (int i = 0; i < 128; i++)
  • Color scheme: vec3(0.3, 0.8, 1.0)vec3(1.0, 0.3, 0.5)

Twirl Smoke:

  • Swirl strength: 2.5 * r5.0 * r
  • Smoke threshold: smoothstep(0.35, 0.9, n)smoothstep(0.2, 0.95, n)

Cloud Layer:

  • Cloud density threshold: smoothstep(0.55, 0.9, h)smoothstep(0.4, 0.8, h)
  • Wind speed: u_time * 0.15u_time * 0.5

3D Fractal:

  • Fractal order: #define MAXITER 5#define MAXITER 7
  • Symmetry: * 8.0* 6.0 (6-fold symmetry)

3. Combine Techniques

Combine techniques from different presets:

  • Fog Sphere + Cloud Layer noise = More realistic fog
  • Twirl Smoke swirl + Cloud Layer 3D = Tornado
  • 3D Fractal lighting + Fog Sphere fog = Glowing fractal fog

4. Save and Share

Use the editor's "Share" feature to generate a URL and share your improved version!


Summary

These 4 presets cover volume shader techniques from beginner to advanced:

Fog Sphere - Learn SDF and ray marching basics ✅ Twirl Smoke - Understand 2D noise and coordinate transformations ✅ Cloud Layer - Master 3D volumetric rendering ✅ 3D Fractal - Challenge complex mathematics and full lighting

By deeply understanding the implementation principles of these presets, you've mastered the core skills of volume shader development. Now you can start creating your own stunning effects! 🎨

Related Resources:

Happy Shader Coding! 🚀

Related Articles

Enjoyed this article?

Stay updated with the latest volume shading tutorials, techniques, and updates delivered straight to your inbox.

Subscribe to our newsletter