Three.js后期处理实战:镜头颜色、色差、点阵与颜色管道的深度解析

在Three.js的世界中,后期处理是提升视觉效果的关键技术。本文将深入探讨如何通过后期处理实现镜头颜色滤镜、点阵效果以及颜色管道的应用,为你的3D场景增添独特的视觉风格。

引言:后期处理的力量

Three.js的后期处理允许我们在渲染完成后对图像进行额外的处理,这为我们创造了无限的可能性。通过组合各种后期处理效果,我们可以模拟真实世界的镜头特性、创建风格化的视觉效果,甚至实现完全独特的视觉体验。

基础准备:设置后期处理管道

首先,我们需要设置基本的后期处理环境:

js 复制代码
import * as THREE from 'three';
import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer.js';
import { RenderPass } from 'three/examples/jsm/postprocessing/RenderPass.js';
import { ShaderPass } from 'three/examples/jsm/postprocessing/ShaderPass.js';

// 创建场景、相机和渲染器
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

// 创建效果组合器
const composer = new EffectComposer(renderer);
const renderPass = new RenderPass(scene, camera)
composer.addPass(renderPass);

const animate() {
  requestAnimationFrame(animate);
  //renderer.render(scene, camera);
  composer.render();
}
animate()

实现多通道颜色处理

js 复制代码
import { ColorifyShader } from 'three/examples/jsm/shaders/ColorifyShader.js';

// 添加颜色调整通道
const colorAisle = (color)=>{
    const colorifyPass = new ShaderPass(ColorifyShader);
    colorifyPass.uniforms.color.value = new Color( color || 0x1922FF); // 设置颜色调整值
    return colorifyPass
}
composer.addPass(colorAisle(0x19FFC9));

实现镜头颜色效果

js 复制代码
const LensColor = {
    uniforms: {
        tDiffuse: {
            value: null
        },
        vignetteColor: {
            value: new THREE.Color(0xff1212)
        },
        vignetteOffset: {
            value: 1.0
        },
        vignetteTexture: {
            value: null
        }
    },
    vertexShader: `
        
    varying vec2 vUv;
    void main() {
        vUv = uv;
        gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
    }
    `,
    fragmentShader: `
        uniform sampler2D tDiffuse;
        uniform float vignetteOffset;
        uniform vec3 vignetteColor;
        #ifdef USE_VIGNETTE_TEXTURE
            uniform sampler2D vignetteTexture;
        #endif
        varying vec2 vUv;
        void main() {
            vec4 color = texture2D(tDiffuse, vUv);
            vec2 uv = (vUv - vec2(0.5)) * vec2(vignetteOffset);
            vec3 color2 = vignetteColor;
            #ifdef USE_VIGNETTE_TEXTURE
                color2 *= texture2D(vignetteTexture, vUv).rgb;
            #endif
            color.rgb = mix(color.rgb, color2, clamp(dot(uv, uv), 0.0, 1.0));
            gl_FragColor = color;
        }
    `
}
// 镜头颜色
const lensColor = ()=> new ShaderPass(LensColor);
LensColor.uniforms.vignetteColor.value =  new THREE.Color(0xff1212)
LensColor.uniforms.vignetteOffset.value = 1
composer.addPass(lensColor);

实现点阵效果

js 复制代码
import { DotScreenPass } from 'three/examples/jsm/postprocessing/DotScreenPass.js';

//angle 1 点阵的旋转角度, scale 2 点大小
const dotScreenPass = ()=>  new DotScreenPass(new Vector2(window.innerWidth,window.innerHeight),1,2)
composer.addPass(dotScreenPass);

色差-红蓝分离

js 复制代码
const ColorDifference = {
    uniforms: {
        tDiffuse: {
            value: null
        },
        chromaFactor: {
            value: .025
        },
        uResolutionRatio: {
            value: new THREE.Vector2(1, 1)
        },
        resolution: {
            value: new THREE.Vector2(1 / 1024, 1 / 512)
        }
    },
    vertexShader: `
        varying vec2 vUv;
        void main() {
             vUv = uv;
            gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
        }
    `,
    fragmentShader: `
        uniform sampler2D tDiffuse;
        uniform float chromaFactor;
        uniform vec2 uResolutionRatio;
        uniform vec2 resolution;
        varying vec2 vUv;
        void main() {
            vec2 uv = vUv;
            vec2 dist = uv - 0.5;
            vec2 offset = chromaFactor * dist * length(dist);
            vec4 col = texture2D(tDiffuse, min(uv, 1.0 - resolution) * uResolutionRatio);
            col.r = texture2D(tDiffuse, min(uv - offset, 1.0 - resolution) * uResolutionRatio).r;
            col.b = texture2D(tDiffuse, min(uv + offset, 1.0 - resolution) * uResolutionRatio).b;
            gl_FragColor = col;
        }`
}
// 色差-红蓝分离
const chromaticAberration = ()=>{
    const chroma = new ShaderPass(ColorDifference);
    chroma.uniforms.chromaFactor.value = 0.25 // 设置颜色调整值
    return chroma
}
composer.addPass(chromaticAberration);

写在最后

实践是检验真理唯一且有效的途径。在three.js中后期处理 每一种效果的先后顺序会影响整体呈现效果

下一篇预告

噪点

1. 正常模式噪点

2. 深度模式

颜色调整

1. 调整前

2. 调整后

相关推荐
快手技术2 分钟前
入围AA总榜Top 10,Non-Reasoning Model榜单第一!KAT-Coder-Pro V1 新版本踏浪归来!
前端·后端·前端框架
wangpq3 分钟前
记录曾经打开半屏小程序遇到的事
前端·微信小程序
king王一帅9 分钟前
告别 AI 输出的重复解析:正常 markdown 解析渲染也能提速 2-10 倍以上
前端·javascript·ai编程
huangql52012 分钟前
网络体系结构在Web前端性能优化中的应用完全指南
前端·性能优化
代码or搬砖13 分钟前
ES6新增的新特性以及用法
前端·javascript·es6
LYFlied14 分钟前
【一句话概述】前端性能优化从页面加载到展示
前端·性能优化
小番茄夫斯基15 分钟前
Monorepo 架构:现代软件开发的代码管理革命
前端·javascript·架构
一只秋刀鱼17 分钟前
从 0 到 1 构建 React + TypeScript 车辆租赁后台管理系统
前端·typescript
How_doyou_do20 分钟前
pnpm优化理念 - 幻影依赖、monorepo - 升级npm
前端
雨落秋垣31 分钟前
在前端把图片自动转换为 WebP 格式
前端