Claude
Skills
Sign in
Back

shader-effects

Included with Lifetime
$97 forever

Visual shader effects—glow/bloom, chromatic aberration, distortion, vignette, film grain, scanlines, glitch, dissolve, outline, and fresnel. Use when adding visual polish, post-processing effects, or stylized rendering to shaders.

General

What this skill does


# Shader Effects

Visual effects that add polish, style, and atmosphere to shader output.

## Quick Start

```glsl
// Combine multiple effects
vec3 color = baseColor;
color = applyVignette(color, uv, 0.5);
color = applyGrain(color, uv, uTime, 0.1);
color = applyChromaticAberration(color, uv, 0.005);
```

## Glow / Bloom

### Simple Glow

```glsl
// Distance-based glow
float glow(float d, float radius, float intensity) {
  return pow(radius / max(d, 0.001), intensity);
}

// Usage
float d = sdCircle(uv, 0.2);
vec3 color = vec3(glow(d, 0.1, 2.0)) * glowColor;
```

### Bloom (Multi-sample)

```glsl
// Sample in cross pattern for cheap bloom
vec3 bloom(sampler2D tex, vec2 uv, float radius) {
  vec3 color = vec3(0.0);
  float total = 0.0;
  
  for (float x = -4.0; x <= 4.0; x += 1.0) {
    for (float y = -4.0; y <= 4.0; y += 1.0) {
      float weight = 1.0 / (1.0 + length(vec2(x, y)));
      color += texture2D(tex, uv + vec2(x, y) * radius).rgb * weight;
      total += weight;
    }
  }
  
  return color / total;
}
```

### Gaussian Blur (Separable)

```glsl
// Horizontal pass
vec3 blurH(sampler2D tex, vec2 uv, float radius) {
  vec3 color = vec3(0.0);
  float weights[5] = float[](0.227, 0.194, 0.121, 0.054, 0.016);
  
  color += texture2D(tex, uv).rgb * weights[0];
  for (int i = 1; i < 5; i++) {
    vec2 offset = vec2(float(i) * radius, 0.0);
    color += texture2D(tex, uv + offset).rgb * weights[i];
    color += texture2D(tex, uv - offset).rgb * weights[i];
  }
  
  return color;
}

// Vertical pass (same, swap x/y)
```

## Chromatic Aberration

```glsl
vec3 chromaticAberration(sampler2D tex, vec2 uv, float amount) {
  vec2 dir = uv - 0.5;
  vec2 offset = dir * amount;
  
  vec3 color;
  color.r = texture2D(tex, uv + offset).r;
  color.g = texture2D(tex, uv).g;
  color.b = texture2D(tex, uv - offset).b;
  
  return color;
}

// Radial chromatic aberration (stronger at edges)
vec3 radialCA(sampler2D tex, vec2 uv, float amount) {
  vec2 dir = uv - 0.5;
  float dist = length(dir);
  vec2 offset = dir * amount * dist;
  
  vec3 color;
  color.r = texture2D(tex, uv + offset).r;
  color.g = texture2D(tex, uv).g;
  color.b = texture2D(tex, uv - offset).b;
  
  return color;
}
```

## Distortion

### Wave Distortion

```glsl
vec2 waveDistort(vec2 uv, float time, float freq, float amp) {
  uv.x += sin(uv.y * freq + time) * amp;
  uv.y += cos(uv.x * freq + time) * amp;
  return uv;
}
```

### Barrel/Pincushion Distortion

```glsl
vec2 barrelDistort(vec2 uv, float amount) {
  vec2 centered = uv - 0.5;
  float r2 = dot(centered, centered);
  vec2 distorted = centered * (1.0 + amount * r2);
  return distorted + 0.5;
}
```

### Heat Haze

```glsl
vec2 heatHaze(vec2 uv, float time, float intensity) {
  float noise = snoise(vec3(uv * 10.0, time));
  return uv + vec2(noise) * intensity;
}
```

### Ripple

```glsl
vec2 ripple(vec2 uv, vec2 center, float time, float freq, float amp) {
  vec2 dir = uv - center;
  float dist = length(dir);
  float wave = sin(dist * freq - time) * amp;
  return uv + normalize(dir) * wave;
}
```

## Vignette

```glsl
vec3 vignette(vec3 color, vec2 uv, float intensity, float smoothness) {
  vec2 centered = uv - 0.5;
  float dist = length(centered);
  float vig = smoothstep(0.5, 0.5 - smoothness, dist * intensity);
  return color * vig;
}

// Colored vignette
vec3 coloredVignette(vec3 color, vec2 uv, vec3 vigColor, float intensity) {
  vec2 centered = uv - 0.5;
  float dist = length(centered);
  float vig = smoothstep(0.0, 0.5, dist * intensity);
  return mix(color, vigColor, vig);
}
```

## Film Grain

```glsl
float random(vec2 st) {
  return fract(sin(dot(st.xy, vec2(12.9898, 78.233))) * 43758.5453123);
}

vec3 filmGrain(vec3 color, vec2 uv, float time, float intensity) {
  float grain = random(uv + fract(time)) * 2.0 - 1.0;
  return color + grain * intensity;
}

// Animated grain (smoother)
vec3 animatedGrain(vec3 color, vec2 uv, float time, float intensity) {
  float x = (uv.x + 4.0) * (uv.y + 4.0) * (time * 10.0);
  float grain = mod((mod(x, 13.0) + 1.0) * (mod(x, 123.0) + 1.0), 0.01) - 0.005;
  return color + grain * intensity * 50.0;
}
```

## Scanlines

```glsl
vec3 scanlines(vec3 color, vec2 uv, float count, float intensity) {
  float scanline = sin(uv.y * count * 3.14159) * 0.5 + 0.5;
  return color * (1.0 - intensity + scanline * intensity);
}

// CRT-style scanlines
vec3 crtScanlines(vec3 color, vec2 fragCoord, float intensity) {
  float scanline = sin(fragCoord.y * 0.7) * 0.1 * intensity;
  float flicker = sin(uTime * 10.0) * 0.01 * intensity;
  return color * (1.0 - scanline - flicker);
}
```

## Glitch

```glsl
vec3 glitch(sampler2D tex, vec2 uv, float time, float intensity) {
  // Random block offset
  float blockTime = floor(time * 20.0);
  float blockRand = random(vec2(blockTime, 0.0));
  
  if (blockRand > 0.9) {
    // Horizontal shift
    float shift = (random(vec2(uv.y, blockTime)) - 0.5) * intensity;
    uv.x += shift;
  }
  
  // Color channel split
  vec3 color;
  color.r = texture2D(tex, uv + vec2(intensity * 0.01, 0.0)).r;
  color.g = texture2D(tex, uv).g;
  color.b = texture2D(tex, uv - vec2(intensity * 0.01, 0.0)).b;
  
  // Random color inversion blocks
  if (random(vec2(floor(uv.y * 20.0), blockTime)) > 0.98) {
    color = 1.0 - color;
  }
  
  return color;
}

// Digital glitch with blocks
vec3 blockGlitch(sampler2D tex, vec2 uv, float time, float intensity) {
  vec2 blockSize = vec2(0.1, 0.05);
  vec2 block = floor(uv / blockSize);
  float blockRand = random(block + floor(time * 10.0));
  
  if (blockRand > 1.0 - intensity * 0.1) {
    uv.x += (blockRand - 0.5) * 0.1;
  }
  
  return texture2D(tex, uv).rgb;
}
```

## Dissolve

```glsl
vec3 dissolve(vec3 color, vec2 uv, float progress, float edgeWidth, vec3 edgeColor) {
  float noise = snoise(uv * 10.0);
  
  // Discard dissolved pixels
  if (noise < progress) {
    discard;
  }
  
  // Edge glow
  float edge = smoothstep(progress, progress + edgeWidth, noise);
  return mix(edgeColor, color, edge);
}

// With alpha instead of discard
vec4 dissolveAlpha(vec3 color, vec2 uv, float progress, float edgeWidth, vec3 edgeColor) {
  float noise = snoise(uv * 10.0);
  
  float alpha = smoothstep(progress - edgeWidth, progress, noise);
  float edge = smoothstep(progress, progress + edgeWidth, noise);
  vec3 finalColor = mix(edgeColor, color, edge);
  
  return vec4(finalColor, alpha);
}
```

## Outline

```glsl
// SDF-based outline
vec3 sdfOutline(float d, vec3 fillColor, vec3 outlineColor, float outlineWidth) {
  float aa = fwidth(d);
  float fill = smoothstep(aa, -aa, d);
  float outline = smoothstep(aa, -aa, abs(d) - outlineWidth);
  
  return mix(vec3(0.0), mix(outlineColor, fillColor, fill), max(fill, outline));
}

// Texture-based outline (sample neighbors)
float textureOutline(sampler2D tex, vec2 uv, float thickness) {
  float alpha = texture2D(tex, uv).a;
  
  float outline = 0.0;
  for (float x = -1.0; x <= 1.0; x += 1.0) {
    for (float y = -1.0; y <= 1.0; y += 1.0) {
      outline += texture2D(tex, uv + vec2(x, y) * thickness).a;
    }
  }
  
  return clamp(outline - alpha * 9.0, 0.0, 1.0);
}
```

## Fresnel / Rim Light

```glsl
// 3D fresnel (needs view direction and normal)
float fresnel(vec3 viewDir, vec3 normal, float power) {
  return pow(1.0 - max(dot(viewDir, normal), 0.0), power);
}

// 2D fake fresnel (based on UV distance from center)
float fakeFresnel2D(vec2 uv, float power) {
  vec2 centered = uv - 0.5;
  float dist = length(centered) * 2.0;
  return pow(dist, power);
}

// Usage
vec3 color = baseColor;
float rim = fresnel(viewDir, normal, 3.0);
color += rimColor * rim * rimIntensity;
```

## Color Grading

### Contrast / Brightness / Saturation

```glsl
vec3 adjustContrast(vec3 color, float contrast) {
  return (color - 0.5) * contrast + 0.5;
}

vec3 adjustBrightness(vec3 color, float brightness) {
  return color + brightness;
}

vec3 adjustSaturation(vec3 color, float saturation) {
  float gray = dot(color, vec3(0.299, 0.587, 0.114));
  return
Files: 2
Size: 10.8 KB
Complexity: 16/100
Category: General

Related in General