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 应用打下坚实基础。

相关推荐
一颗奇趣蛋几秒前
Vue 3 父子&爷孙组件通信
前端·vue.js
百锦再6 分钟前
Microsoft前后端不分离编程新风向:cshtml
javascript·css·microsoft·html·web·web2.0·cshtml
子洋9 分钟前
从零搭建一个免费稳定的私有短链接服务
前端·javascript·后端
GeGarron13 分钟前
AI N8N 技术文档
前端·aigc
站在风口的猪110815 分钟前
《前端面试题:CSS有哪些单位!》
前端·css·html·css3·html5
imkaifan16 分钟前
10、vue中路由的两种形式
前端·javascript·vue.js
好青崧18 分钟前
json中对象转字符串和字符串转对象的方法
javascript
1024小神19 分钟前
tauri2项目中自定义执行cmd命令界面卡死以及中文出错问题
前端·javascript
菜菜驴22 分钟前
关于 AI 应用的前端具体实践
前端·架构
打破砂锅问到底00725 分钟前
前端验证下跨域问题(npm验证)
前端·npm·node.js