🎯 提示词

PROMPT
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
使用 Three.js 实现【图像扭曲滤镜效果】,具体要求:

【核心特效】
- 基于随机噪声的图像扭曲
- 可调节扭曲程度参数
- 实时预览滤镜效果

【场景与光照】
- 深色背景
- 无需光源(纹理自发光)

【交互与控制】
- OrbitControls 轨道控制器
- GUI 面板调节扭曲程度

【技术要求】
- Three.js 最新版本
- ShaderMaterial 自定义着色器
- TextureLoader 加载外部图片

📖 效果拆解

层次 视觉效果 技术实现
基础 全屏平面 PlaneGeometry(2, 2)
核心特效 随机像素偏移 伪随机数生成 + UV坐标扰动
交互 参数调节 lil-gui 控制面板
纹理 网络图片加载 TextureLoader

🔧 核心技术点

1. 伪随机数生成函数

使用经典的基于正弦函数的伪随机数生成算法,确保相同输入产生相同输出。

GLSL
1
2
3
float generateRandom(vec2 co) {
    return fract(sin(dot(co.xy, vec2(12.9898, 78.233))) * 43758.5453);
}

2. 像素级扭曲算法

将UV坐标转换为像素坐标,应用随机偏移后再转换回UV坐标进行纹理采样。

GLSL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void main() {
    // 将UV坐标转换为像素坐标
    vec2 pixelCoord = v_uv * u_resolution;
    
    // 生成随机偏移值
    float randomX = generateRandom(v_uv) * u_distortion * 2.0 - u_distortion;
    float randomY = generateRandom(vec2(v_uv.y, v_uv.x)) * u_distortion * 2.0 - u_distortion;
    
    // 应用随机偏移
    vec2 distortedCoord = (pixelCoord + vec2(randomX, randomY)) / u_resolution;
    
    // 从纹理中采样颜色
    vec4 finalColor = texture2D(u_texture, distortedCoord);
    gl_FragColor = finalColor;
}

3. 响应式分辨率处理

在窗口大小变化时更新着色器中的分辨率uniform,确保效果一致性。

JAVASCRIPT
1
2
3
4
5
6
7
const onWindowResize = () => {
    this.uniforms.u_resolution.value.set(
        this.container.clientWidth,
        this.container.clientHeight
    );
};
window.addEventListener("resize", onWindowResize);

💡 调试与优化

问题类型 表现形式 解决方案
图片加载失败 纹理显示黑色 检查图片URL是否有效,添加错误处理回调
扭曲效果不明显 画面无变化 增加 u_distortion 参数值
性能问题 大尺寸图片帧率下降 使用较小分辨率图片或降低扭曲程度
伪随机模式重复 图案有明显重复 修改随机数生成函数的种子参数

🚀 扩展思路

变体效果 核心改动 难度
动态扭曲 添加时间变量控制扭曲动画 ⭐⭐
方向扭曲 限制偏移方向,实现单向模糊 ⭐⭐
噪声动画 使用 simplex noise 替代伪随机 ⭐⭐⭐
边缘检测叠加 添加 Sobel 边缘检测 ⭐⭐⭐

本文档由 ThreeLab 编辑整理,如需转载,请注明出处。