一、什么是着色器?

着色器是运行在GPU上的小程序,用于控制3D图形的渲染过程。在Three.js中,主要有两种着色器:

GLSL(OpenGL Shading Language)作为面向图形编程的着色器语言,数据类型体系围绕图形计算需求设计

GLSL支持多种数据类型:

float f = 1.0;              // 浮点数
int i = 1;                  // 整数
bool b = true;              // 布尔值
vec2 v2 = vec2(1.0, 2.0);  // 2维向量
vec3 v3 = vec3(1.0,2.0,3.0); // 3维向量
vec4 v4 = vec4(v3, 1.0);   // 4维向量
mat4 m4 = mat4(1.0);       // 4x4矩阵

准备工作

首先,创建一个基本的Three.js场景


顶点着色器与片段着色器

让我们先了解两种着色器的基本结构示例

顶点着色器(vertexShader):

// attribute: 每个顶点特有的数据(位置、法线、UV坐标等)
// uniform: 所有顶点共享的数据(变换矩阵、时间等)
// varying: 从顶点着色器传递到片段着色器的数据

// Three.js会自动提供的变量:
// attribute vec3 position; // 顶点位置
// attribute vec3 normal;   // 法线向量
// attribute vec2 uv;       // UV坐标

// Three.js会自动提供的uniform:
// uniform mat4 projectionMatrix; // 投影矩阵
// uniform mat4 modelViewMatrix;  // 模型视图矩阵

varying vec2 vUv; // 声明一个varying变量,将UV坐标传递到片段着色器

void main() {
    vUv = uv; // 传递UV坐标
    
    // 将顶点位置转换为屏幕坐标
    // position: 当前顶点的原始位置
    // modelViewMatrix: 模型视图矩阵,将模型空间转换到视图空间
    // projectionMatrix: 投影矩阵,将视图空间转换到裁剪空间
    // gl_Position: OpenGL内置变量,表示顶点在裁剪空间中的位置
    gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}

片段着色器(fragmentShader):

// 主要负责计算每个像素的最终颜色
// 精度限定符,mediump表示中等精度(Three.js会自动提供)
precision mediump float;

// 从顶点着色器接收的变量
varying vec2 vUv;

void main() {
    // 设置像素颜色
    gl_FragColor = vec4(vUv, 0.0, 1.0); // 使用UV坐标作为颜色
}

二、创建第一个自定义着色器材质

现在让我们创建一个简单的自定义着色器材质:

// 创建自定义着色器材质
const vertexShader = `
    varying vec2 vUv;
    
    void main() {
        vUv = uv;
        gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
    }
`;

const fragmentShader = `
    precision mediump float;
    varying vec2 vUv;
    
    void main() {
        // 使用UV坐标创建颜色渐变
        vec3 color = vec3(vUv.x, vUv.y, 0.5);
        gl_FragColor = vec4(color, 1.0);
    }
`;

// 使用ShaderMaterial(Three.js会自动添加一些默认的uniform和attribute)
const shaderMaterial = new THREE.ShaderMaterial({
    vertexShader: vertexShader,   // 顶点着色器
    fragmentShader: fragmentShader, // 片段着色器
    wireframe: false // 设置为true可以查看网格结构
});

// 创建几何体并应用着色器材质
const geometry = new THREE.PlaneGeometry(10, 10, 100, 100);
const plane = new THREE.Mesh(geometry, shaderMaterial);
plane.rotation.x = -Math.PI / 2;
scene.add(plane);
提示

着色器是 GPU 编程的核心,掌握了着色器编程,就掌握了高性能图形渲染的关键技术。通过自定义着色器,可以创造出无限可能的视觉效果。