shader-effects by bbeierle12/skill-mcp-claude
npx skills add https://github.com/bbeierle12/skill-mcp-claude --skill shader-effects为着色器输出增添精致感、风格和氛围的视觉效果。
// 组合多种特效
vec3 color = baseColor;
color = applyVignette(color, uv, 0.5);
color = applyGrain(color, uv, uTime, 0.1);
color = applyChromaticAberration(color, uv, 0.005);
// 基于距离的辉光
float glow(float d, float radius, float intensity) {
return pow(radius / max(d, 0.001), intensity);
}
// 用法
float d = sdCircle(uv, 0.2);
vec3 color = vec3(glow(d, 0.1, 2.0)) * glowColor;
// 使用十字采样模式实现廉价泛光
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;
}
// 水平通道
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;
}
// 垂直通道(相同,交换 x/y)
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
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;
}
// 径向色差(边缘更强)
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;
}
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;
}
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;
}
vec2 heatHaze(vec2 uv, float time, float intensity) {
float noise = snoise(vec3(uv * 10.0, time));
return uv + vec2(noise) * intensity;
}
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;
}
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;
}
// 彩色暗角
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);
}
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;
}
// 动画颗粒(更平滑)
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;
}
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 风格扫描线
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);
}
vec3 glitch(sampler2D tex, vec2 uv, float time, float intensity) {
// 随机块偏移
float blockTime = floor(time * 20.0);
float blockRand = random(vec2(blockTime, 0.0));
if (blockRand > 0.9) {
// 水平偏移
float shift = (random(vec2(uv.y, blockTime)) - 0.5) * intensity;
uv.x += shift;
}
// 颜色通道分离
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;
// 随机颜色反转块
if (random(vec2(floor(uv.y * 20.0), blockTime)) > 0.98) {
color = 1.0 - color;
}
return color;
}
// 带块的数字故障
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;
}
vec3 dissolve(vec3 color, vec2 uv, float progress, float edgeWidth, vec3 edgeColor) {
float noise = snoise(uv * 10.0);
// 丢弃已溶解的像素
if (noise < progress) {
discard;
}
// 边缘发光
float edge = smoothstep(progress, progress + edgeWidth, noise);
return mix(edgeColor, color, edge);
}
// 使用 alpha 而非丢弃
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);
}
// 基于 SDF 的轮廓
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));
}
// 基于纹理的轮廓(采样相邻像素)
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);
}
// 3D 菲涅尔(需要视线方向和法线)
float fresnel(vec3 viewDir, vec3 normal, float power) {
return pow(1.0 - max(dot(viewDir, normal), 0.0), power);
}
// 2D 伪菲涅尔(基于 UV 到中心的距离)
float fakeFresnel2D(vec2 uv, float power) {
vec2 centered = uv - 0.5;
float dist = length(centered) * 2.0;
return pow(dist, power);
}
// 用法
vec3 color = baseColor;
float rim = fresnel(viewDir, normal, 3.0);
color += rimColor * rim * rimIntensity;
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 mix(vec3(gray), color, saturation);
}
vec3 colorRemap(vec3 color, vec3 shadowColor, vec3 highlightColor) {
float luma = dot(color, vec3(0.299, 0.587, 0.114));
return mix(shadowColor, highlightColor, luma);
}
vec3 posterize(vec3 color, float levels) {
return floor(color * levels) / levels;
}
// Bayer 4x4 抖动
float bayer4x4(vec2 fragCoord) {
int x = int(mod(fragCoord.x, 4.0));
int y = int(mod(fragCoord.y, 4.0));
int bayer[16] = int[](
0, 8, 2, 10,
12, 4, 14, 6,
3, 11, 1, 9,
15, 7, 13, 5
);
return float(bayer[y * 4 + x]) / 16.0;
}
vec3 dither(vec3 color, vec2 fragCoord, float levels) {
float threshold = bayer4x4(fragCoord);
return floor(color * levels + threshold) / levels;
}
vec3 applyEffects(vec3 color, vec2 uv, float time) {
// 顺序很重要!
// 1. 扭曲(首先修改 UV)
// 已在纹理采样中应用
// 2. 色彩调整
color = adjustContrast(color, 1.1);
color = adjustSaturation(color, 1.2);
// 3. 色差
// (在纹理采样期间应用)
// 4. 暗角
color = vignette(color, uv, 1.2, 0.4);
// 5. 胶片颗粒(最后,在最终输出之前)
color = filmGrain(color, uv, time, 0.05);
return color;
}
shader-effects/
├── SKILL.md
├── references/
│ ├── effect-order.md # 推荐的特效组合顺序
│ └── performance.md # 特效性能开销
└── scripts/
├── effects/
│ ├── glow.glsl # 辉光/泛光
│ ├── distortion.glsl # 扭曲特效
│ ├── color.glsl # 色彩分级
│ └── retro.glsl # CRT/复古特效
└── examples/
├── cyberpunk.glsl # 赛博朋克风格组合
└── vintage.glsl # 复古胶片外观
references/effect-order.md — 组合特效的推荐顺序references/performance.md — 每个特效的性能开销每周安装量
83
代码仓库
GitHub 星标数
7
首次出现
2026年1月22日
安全审计
安装于
codex68
opencode68
claude-code66
gemini-cli61
cursor61
github-copilot55
Visual effects that add polish, style, and atmosphere to shader output.
// 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);
// 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;
// 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;
}
// 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)
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;
}
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;
}
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;
}
vec2 heatHaze(vec2 uv, float time, float intensity) {
float noise = snoise(vec3(uv * 10.0, time));
return uv + vec2(noise) * intensity;
}
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;
}
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);
}
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;
}
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);
}
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;
}
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);
}
// 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);
}
// 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;
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 mix(vec3(gray), color, saturation);
}
vec3 colorRemap(vec3 color, vec3 shadowColor, vec3 highlightColor) {
float luma = dot(color, vec3(0.299, 0.587, 0.114));
return mix(shadowColor, highlightColor, luma);
}
vec3 posterize(vec3 color, float levels) {
return floor(color * levels) / levels;
}
// Bayer 4x4 dithering
float bayer4x4(vec2 fragCoord) {
int x = int(mod(fragCoord.x, 4.0));
int y = int(mod(fragCoord.y, 4.0));
int bayer[16] = int[](
0, 8, 2, 10,
12, 4, 14, 6,
3, 11, 1, 9,
15, 7, 13, 5
);
return float(bayer[y * 4 + x]) / 16.0;
}
vec3 dither(vec3 color, vec2 fragCoord, float levels) {
float threshold = bayer4x4(fragCoord);
return floor(color * levels + threshold) / levels;
}
vec3 applyEffects(vec3 color, vec2 uv, float time) {
// Order matters!
// 1. Distortion (modify UVs first)
// Already applied to texture sampling
// 2. Color adjustments
color = adjustContrast(color, 1.1);
color = adjustSaturation(color, 1.2);
// 3. Chromatic aberration
// (apply during texture sampling)
// 4. Vignette
color = vignette(color, uv, 1.2, 0.4);
// 5. Film grain (last, before final output)
color = filmGrain(color, uv, time, 0.05);
return color;
}
shader-effects/
├── SKILL.md
├── references/
│ ├── effect-order.md # Recommended effect ordering
│ └── performance.md # Effect costs
└── scripts/
├── effects/
│ ├── glow.glsl # Glow/bloom
│ ├── distortion.glsl # Distortion effects
│ ├── color.glsl # Color grading
│ └── retro.glsl # CRT/retro effects
└── examples/
├── cyberpunk.glsl # Cyberpunk style combo
└── vintage.glsl # Vintage film look
references/effect-order.md — Recommended order for combining effectsreferences/performance.md — Performance cost of each effectWeekly Installs
83
Repository
GitHub Stars
7
First Seen
Jan 22, 2026
Security Audits
Gen Agent Trust HubPassSocketPassSnykPass
Installed on
codex68
opencode68
claude-code66
gemini-cli61
cursor61
github-copilot55
Shader Craft:36种GLSL着色器技术,实时视觉效果开发指南
512 周安装