Three.js 第三天进阶:几何体组合、高级材质与灯光布局

在 Three.js 的学习旅程中,第三天我们将解锁更高级的技能,深入探索几何体组合、高级材质特性以及灯光布局技巧,让 3D 场景变得更加丰富立体。

一、复杂几何体构建

1.1 几何体组合

实际项目中,单个基础几何体很难满足需求,这时就需要将多个基础几何体组合成复杂形状。比如创建一个带轮子的小车,我们可以使用Group对象将多个几何体组合在一起。

js 复制代码
// 创建车身
const bodyGeometry = new THREE.BoxGeometry(2, 1, 1);
const bodyMaterial = new THREE.MeshStandardMaterial({ color: 0x007bff });
const body = new THREE.Mesh(bodyGeometry, bodyMaterial);
// 创建轮子
const wheelGeometry = new THREE.CylinderGeometry(0.3, 0.3, 0.2, 32);
const wheelMaterial = new THREE.MeshStandardMaterial({ color: 0x343a40 });
const wheel1 = new THREE.Mesh(wheelGeometry, wheelMaterial);
const wheel2 = new THREE.Mesh(wheelGeometry, wheelMaterial);
wheel1.position.set(-0.8, -0.5, 0);
wheel2.position.set(0.8, -0.5, 0);
// 创建小车组
const car = new THREE.Group();
car.add(body);
car.add(wheel1);
car.add(wheel2);
scene.add(car);

上述代码中,我们分别创建了车身和轮子的几何体,然后通过Group对象将它们组合成一个完整的小车模型,最后添加到场景中。

1.2 变形几何体

Three.js 还支持对几何体进行变形操作,以实现独特的视觉效果。例如使用ExtrudeGeometry创建一个拉伸的文本。

js 复制代码
const fontLoader = new THREE.FontLoader();
fontLoader.load(
    'fonts/helvetiker_regular.typeface.json',
    function (font) {
        const textGeometry = new THREE.TextGeometry('THREE', {
            font: font,
            size: 0.8,
            height: 0.1,
            curveSegments: 12
        });
        const textMaterial = new THREE.MeshStandardMaterial({ color: 0xffc107 });
        const textMesh = new THREE.Mesh(textGeometry, textMaterial);
        scene.add(textMesh);
    }
);

这里通过加载字体文件,利用TextGeometry创建文本形状,再进行拉伸处理,赋予材质后添加到场景,实现了立体文本效果。

二、高级材质应用

2.1 物理材质

MeshStandardMaterial是基于物理的材质,它能更真实地模拟现实世界中物体的反射、折射和阴影效果。我们来设置一个金属材质的球体:

js 复制代码
const metalSphereGeometry = new THREE.SphereGeometry(1, 32, 32);
const metalMaterial = new THREE.MeshStandardMaterial({
    color: 0x009688,
    metalness: 1,
    roughness: 0.1
});
const metalSphere = new THREE.Mesh(metalSphereGeometry, metalMaterial);
scene.add(metalSphere);

metalness属性控制材质的金属程度,roughness属性控制粗糙度,通过调整这两个参数,可以表现出不同质感的金属表面。

2.2 透明材质与混合模式

想要创建透明物体,可以使用MeshStandardMaterial的opacity和transparent属性。同时,还能设置混合模式,如正常混合、相加混合等。

js 复制代码
const glassGeometry = new THREE.BoxGeometry(1, 1, 1);
const glassMaterial = new THREE.MeshStandardMaterial({
    color: 0x00ffff,
    opacity: 0.5,
    transparent: true,
    blending: THREE.AdditiveBlending
});
const glassBox = new THREE.Mesh(glassGeometry, glassMaterial);
scene.add(glassBox);

上述代码创建了一个透明的玻璃盒子,blending: THREE.AdditiveBlending设置为相加混合模式,让透明物体在光照下呈现出更绚丽的效果。

三、灯光布局与氛围营造

3.1 多光源组合

在一个场景中,通常需要多种灯光配合使用,才能营造出理想的氛围。下面我们同时使用环境光、平行光和点光源来照亮场景。

js 复制代码
// 环境光
const ambientLight = new THREE.AmbientLight(0x333333);
scene.add(ambientLight);
// 平行光
const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8);
directionalLight.position.set(1, 2, 3);
directionalLight.castShadow = true;
scene.add(directionalLight);
// 点光源
const pointLight = new THREE.PointLight(0xff0000, 1, 10);
pointLight.position.set(0, 3, 0);
scene.add(pointLight);

通过组合不同类型的灯光,并设置各自的属性,如强度、位置、阴影投射等,让场景中的物体呈现出丰富的光影效果。

3.2 阴影设置

在 Three.js 中开启阴影效果,能让场景更加真实。首先需要在渲染器上开启阴影计算:

js 复制代码
renderer.shadowMap.enabled = true;

然后为相应的灯光和物体设置阴影投射与接收属性,比如让平行光投射阴影,物体接收阴影:

js 复制代码
directionalLight.castShadow = true;
directionalLight.shadow.mapSize.width = 1024;
directionalLight.shadow.mapSize.height = 1024;
const groundGeometry = new THREE.PlaneGeometry(10, 10);
const groundMaterial = new THREE.MeshStandardMaterial({ color: 0x999999 });
const ground = new THREE.Mesh(groundGeometry, groundMaterial);
ground.receiveShadow = true;
ground.rotation.x = -Math.PI / 2;
scene.add(ground);

以上设置使场景中的物体在光照下产生真实的阴影,增强了场景的立体感和真实感。

通过今天的学习,我们在 Three.js 的世界里又前进了一大步。掌握了复杂几何体的构建、高级材质的运用以及灯光阴影的布局,这些知识将为后续创建更精彩的 3D 应用打下坚实基础。

相关推荐
少糖研究所6 分钟前
ACPA算法详解
前端
Mores18 分钟前
开源 | ImageMinify:轻量级智能图片压缩工具,为你的项目瘦身加速
前端
CHQIUU18 分钟前
PDF.js 生态中如何处理“添加注释\添加批注”以及 annotations.contents 属性
开发语言·javascript·pdf
执梦起航19 分钟前
webpack理解与使用
前端·webpack·node.js
ai大师19 分钟前
Cursor怎么使用,3分钟上手Cursor:比ChatGPT更懂需求,用聊天的方式写代码,GPT4、Claude 3.5等先进LLM辅助编程
前端
Json_22 分钟前
使用vue2技术写了一个纯前端的静态网站商城-鲜花销售商城
前端·vue.js·html
1024熙23 分钟前
【Qt】——理解信号与槽,学会使用connect
前端·数据库·c++·qt5
少糖研究所24 分钟前
ColorThief库是如何实现图片取色的?
前端
冴羽24 分钟前
SvelteKit 最新中文文档教程(22)—— 最佳实践之无障碍与 SEO
前端·javascript·svelte
ZYLAB26 分钟前
我写了一个简易的 SEO 教程,希望能让新手朋友看完以后, SEO 能做到 80 分
前端·seo