Three.js-硬要自学系列18 (模型边界线、几何体顶点颜色、网格模型颜色渐变)

本章主要学习知识点

  • 了解模型边界线概念
  • 学会生成模型边界线
  • 学会为几何体顶点设置颜色
  • 掌握为网格模型生成渐变颜色

模型边界线

「模型边界线」可以理解为为3D模型添加轮廓描边,就像用荧光笔勾出物体的边缘。

我们需要用到 EdgesGeometry 工具分析模型几何体,自动找到所有棱角边缘。先来创建一个简单的立方体和圆柱体

js 复制代码
const geometry = new THREE.BoxGeometry( 1, 1, 1 );
const material = new THREE.MeshLambertMaterial( { 
    color: 'deepskyblue',
    transparent: true,
    opacity: 0.5
 });
cube = new THREE.Mesh( geometry, material );

const geometry2 = new THREE.CylinderGeometry( 0.4, 0.4, 1, 42 );
const material2 = new THREE.MeshLambertMaterial( { 
    color: 'deeppink',
    transparent: true,
    opacity: 0.5
 });
const cylinder = new THREE.Mesh( geometry2, material2 );

使用EdgesGeometry提取几何体的边线,然后使用LineSegments渲染线条

js 复制代码
const edges = new THREE.EdgesGeometry( geometry );
const edgesMaterial = new THREE.LineBasicMaterial( { color: 'deepskyblue' });
const line = new THREE.LineSegments( edges, edgesMaterial );
cube.add( line );

以上这个案例是加载three.js中内置的模型,我们尝试加载下外部模型看看,毕竟外部模型的边界线通常都是比较复杂的

js 复制代码
loader.load('model/low_poly_city_pack/scene.glb', function( gltf ) {
    // 递归遍历设置每个模型的材质和边线
    gltf.scene.traverse( function ( child ) {
        if( child.isMesh ){
            // 材质设置
            child.material = new THREE.MeshLambertMaterial({
                color: 'deepskyblue',
                transparent: true,
                opacity: 0.5,
            })
            // 边线设置
            const edges = new THREE.EdgesGeometry( child.geometry );
            const edgesMaterial = new THREE.LineBasicMaterial({color: 'deepskyblue'});
            const line = new THREE.LineSegments( edges, edgesMaterial );
            child.add(line);
        }
    })
    scene.add( gltf.scene );

    // 设置模型处于中心位置
    // 计算模型的边界盒
    const box = new THREE.Box3().setFromObject( gltf.scene );
    // 计算边界盒的中心点
    const center = new THREE.Vector3();
    // 获取边界盒的中心点坐标
    box.getCenter( center ); 
    // 将模型移动到中心点
    gltf.scene.position.x += (gltf.scene.position.x - center.x);
    gltf.scene.position.z += (gltf.scene.position.z - center.z);
});

注意这里要使用DRACO解压模型

几何体顶点颜色

「几何体顶点颜色」可以理解为为几何体的每个顶点单独设置颜色,让3D模型呈现出渐变或局部色彩效果,就像用不同颜色的蜡笔给立体模型的每个角涂色。

顶点颜色的作用

  • 单一颜色: 若整个模型只需一种颜色(如红色立方体),直接设置材质颜色更简单。
  • 渐变或复杂颜色:若需要表面颜色渐变(如温度云图、彩虹效果),则需通过顶点颜色实现,无需依赖贴图。

使用BufferGeometry创建高效缓冲几何体,并设置顶点

js 复制代码
const geometry = new THREE.BufferGeometry();
const vertices = new Float32Array([
    0,0,0,
    2,0,0,
    0,2,0,
])
// 设置顶点
geometry.setAttribute('position', new THREE.BufferAttribute(vertices, 3))

我们设置一个包含三个颜色的Float32Array数组

js 复制代码
const colors = new Float32Array([
    1,0,0, // 红色
    0,1,0, // 绿色
    0,0,1, // 蓝色
])
// 设置顶点颜色
geometry.setAttribute('color', new THREE.BufferAttribute(colors, 3))

为点模型着色

js 复制代码
const material = new THREE.PointsMaterial({
    size: 0.5,
    vertexColors: true, // 使用顶点颜色
})
const point = new THREE.Points(geometry, material)
scene.add(point)

网格模型颜色渐变

「模型颜色渐变」可以理解为让3D模型表面呈现从一种颜色平滑过渡到另一种颜色的效果,类似用渐变油漆刷过物体表面。

颜色渐变的本质是根据模型的位置、高度或时间变化,动态计算每个点的颜色值。在three.js主要通过三种方式实现

  • 顶点颜色渐变:为模型的每个顶点设置不同颜色,Three.js 自动在顶点间插值生成平滑过渡

    • 类比:像给立方体的四个角涂不同颜色,中间区域自动混合。
  • 材质颜色渐变:通过材质属性和时间参数动态调整颜色

    • 类比:像调节调色盘,让整个物体颜色随时间变化。
  • 着色器(Shader)控制:用代码精确控制每个像素的颜色计算规则

    • 类比:像用魔法笔刷自定义每个点的颜色逻辑。

前面我们已经学会了顶点颜色,接下来我们实现线条渐变

js 复制代码
const material2 = new THREE.LineBasicMaterial({
    vertexColors: true   // 使用顶点颜色进行着色
})
const line = new THREE.LineLoop(geometry, material2)
scene.add(line)

如果我们使用网格材质,将会看到如下效果

应用场景对比

场景 推荐方法 案例
静态地形高度染色 顶点颜色渐变 地图中的海拔颜色分层
动态光效(如呼吸灯) 材质颜色渐变 科技感UI元素的脉冲效果
复杂数学渐变(如波纹) 着色器控制 水流表面的动态颜色变化

以上案例均可在案例中心查看体验

THREE 案例中心

相关推荐
万事胜意50710 分钟前
前端切换Tab数据缓存实践
前端
渣渣宇a10 分钟前
Three_3D_Map 中国多个省份的组合边界绘制,填充背景
前端·javascript·three.js
点正13 分钟前
ResizeObserver 和nextTick 的用途
前端
zayyo16 分钟前
Web 应用轻量化实战
前端·javascript·面试
kovli19 分钟前
红宝书第十七讲:通俗详解JavaScript的Promise与链式调用
前端·javascript
lilye6620 分钟前
精益数据分析(19/126):走出数据误区,拥抱创业愿景
前端·人工智能·数据分析
工呈士25 分钟前
CSS 预处理器与模块化:Sass/LESS 实战技巧
css·less
李是啥也不会25 分钟前
Vue中Axios实战指南:高效网络请求的艺术
前端·javascript·vue.js
xiaoliang30 分钟前
《DNS优化真经》
前端
一只小海獭33 分钟前
了解uno.config.ts文件的配置项---转化器
前端