Three.js 着色器使用教程:进阶指南

在 Three.js 的三维场景构建中,着色器(Shader)是极为强大的工具,能显著提升场景渲染效果,创造独特视觉体验。本文假定你已掌握 Three.js 基础,将深入探讨着色器在 Three.js 中的运用。

理解着色器

着色器是运行在 GPU 上的小程序,分为顶点着色器(Vertex Shader)和片段着色器(Fragment Shader)。顶点着色器处理几何体顶点,常用于控制物体形状、位置和方向;片段着色器处理每个像素颜色,决定物体表面最终呈现颜色。在 Three.js 中,通过自定义着色器可实现复杂光影效果、材质模拟等。

在 Three.js 中使用自定义着色器

1. 创建着色器材质

使用ShaderMaterial类创建自定义着色器材质。需提供顶点着色器和片段着色器代码字符串。

js 复制代码
const vertexShader = `
    void main() {
        gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
    }
`;
const fragmentShader = `
    void main() {
        gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
    }
`;
const shaderMaterial = new THREE.ShaderMaterial({
    vertexShader,
    fragmentShader
});

上述代码中,顶点着色器仅进行常规坐标变换,将顶点位置转换到屏幕空间。片段着色器将所有像素设置为红色。

2. 应用材质到几何体

将创建的ShaderMaterial应用到几何体上,与使用普通材质类似。

js 复制代码
const geometry = new THREE.BoxGeometry(1, 1, 1);
const mesh = new THREE.Mesh(geometry, shaderMaterial);
scene.add(mesh);

此时,场景中立方体将呈现红色。

示例:实现简单的渐变效果

修改片段着色器实现从顶部蓝色到底部绿色的渐变效果。

js 复制代码
const vertexShader = `
    void main() {
        gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
    }
`;
const fragmentShader = `
    varying vec2 vUv;
    void main() {
        vec4 topColor = vec4(0.0, 0.0, 1.0, 1.0);
        vec4 bottomColor = vec4(0.0, 1.0, 0.0, 1.0);
        float interpolate = vUv.y;
        gl_FragColor = mix(topColor, bottomColor, interpolate);
    }
`;
const shaderMaterial = new THREE.ShaderMaterial({
    vertexShader,
    fragmentShader
});
// 在顶点着色器中传递纹理坐标
const geometry = new THREE.BoxGeometry(1, 1, 1);
geometry.setAttribute('uv', new THREE.BufferAttribute(new Float32Array([
    0, 0,  1, 0,  1, 1,  0, 1
]), 2));
const mesh = new THREE.Mesh(geometry, shaderMaterial);
scene.add(mesh);

这里,在顶点着色器中未做太多修改。片段着色器引入vUv变量(用于存储纹理坐标),通过vUv.y值(范围 0 - 1)对顶部蓝色和底部绿色进行线性插值,实现渐变效果。需注意,要为几何体设置uv属性传递纹理坐标信息。

传递 Uniform 变量

Uniform 变量是在着色器中可在每一帧更新的全局变量。如传递时间变量实现动画效果。

js 复制代码
const vertexShader = `
    uniform float time;
    void main() {
        vec3 newPosition = position;
        newPosition.y += sin(time + position.x) * 0.2;
        gl_Position = projectionMatrix * modelViewMatrix * vec4(newPosition, 1.0);
    }
`;
const fragmentShader = `
    void main() {
        gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
    }
`;
const shaderMaterial = new THREE.ShaderMaterial({
    vertexShader,
    fragmentShader,
    uniforms: {
        time: { value: 0 }
    }
});
function animate() {
    requestAnimationFrame(animate);
    shaderMaterial.uniforms.time.value += 0.05;
    renderer.render(scene, camera);
}
animate();

在上述代码中,顶点着色器引入time uniform 变量,根据时间和顶点x坐标修改顶点y坐标,实现波浪状动画效果。在animate函数中每一帧更新time uniform 变量值。

总结

通过上述示例,你了解了在 Three.js 中创建和使用自定义着色器、实现渐变效果及传递 uniform 变量。着色器功能强大,可实现复杂材质、光影和动画效果。深入研究着色器语言(GLSL)语法和特性,能为 Three.js 场景开发带来更多创意和可能。

相关推荐
隐藏用户_y7 分钟前
JavaScript闭包概念和应用详解
javascript·面试
Dream耀7 分钟前
CSS选择器完全手册:精准控制网页样式的艺术
前端·css·html
wordbaby8 分钟前
React 19 亮点:让异步请求和数据变更也能用 Transition 管理!
前端·react.js
月亮慢慢圆8 分钟前
VUE3基础之Hooks
前端
我想说一句10 分钟前
CSS 基础知识小课堂:从“选择器”到“声明块”,带你玩转网页的时尚穿搭!
前端·javascript·面试
红衣信19 分钟前
深入浅出 CSS 基础:从概念到选择器实战
前端·css
饮茶三千21 分钟前
五分钟!带你开发一个 VS Code 插件,实现状态栏文案轮播效果
前端
和雍21 分钟前
”做技术分享?苟都不做“做,做的就是 module.rules 加工过程
javascript·面试·webpack
GIS之路22 分钟前
OpenLayers 地图投影转换
前端