如何在three.js中实现如示例所示的几何体轮廓效果?
实现Three.js几何体轮廓效果的几种方案
你用的MeshNormalMaterial和MeshBasicMaterial本身不自带轮廓渲染能力,要实现目标效果可以试试下面几种方法:
方案1:使用官方扩展OutlineEffect(推荐,适合整体外轮廓)
这是Three.js官方提供的效果扩展,专门用于生成模型的外轮廓,配置灵活:
import * as THREE from 'three'; import { OutlineEffect } from 'three/addons/effects/OutlineEffect.js'; // 初始化基础场景、相机、渲染器 const scene = new THREE.Scene(); const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); const renderer = new THREE.WebGLRenderer(); renderer.setSize(window.innerWidth, window.innerHeight); document.body.appendChild(renderer.domElement); // 创建模型和材质(用MeshStandardMaterial配合光源效果更好) const geometry = new THREE.BoxGeometry(1, 1, 1); const material = new THREE.MeshStandardMaterial({ color: 0x556670 }); const mesh = new THREE.Mesh(geometry, material); scene.add(mesh); // 添加方向光(MeshStandardMaterial需要光源才能显示正确质感) const light = new THREE.DirectionalLight(0xffffff, 1); light.position.set(5, 5, 5); scene.add(light); // 初始化OutlineEffect,配置轮廓参数 const effect = new OutlineEffect(renderer, { defaultThickness: 0.01, // 轮廓厚度 defaultColor: new THREE.Color(0x000000), // 轮廓颜色 defaultAlpha: 1 }); // 渲染循环中用effect.render替代原渲染方法 function animate() { requestAnimationFrame(animate); mesh.rotation.x += 0.01; mesh.rotation.y += 0.01; effect.render(scene, camera); } animate();
方案2:双重渲染法(手动实现外轮廓,无需额外扩展)
原理是先渲染一个放大的背面模型作为轮廓,再渲染正常模型:
import * as THREE from 'three'; const scene = new THREE.Scene(); const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); const renderer = new THREE.WebGLRenderer(); renderer.setSize(window.innerWidth, window.innerHeight); document.body.appendChild(renderer.domElement); // 正常模型 const geometry = new THREE.BoxGeometry(1, 1, 1); const material = new THREE.MeshStandardMaterial({ color: 0x556670 }); const mesh = new THREE.Mesh(geometry, material); scene.add(mesh); // 创建轮廓模型:使用背面渲染的基础材质,放大模型尺寸 const outlineMaterial = new THREE.MeshBasicMaterial({ color: 0x000000, side: THREE.BackSide }); const outlineMesh = new THREE.Mesh(geometry, outlineMaterial); outlineMesh.scale.set(1.02, 1.02, 1.02); // 放大比例控制轮廓粗细 mesh.add(outlineMesh); // 作为子对象跟随原模型变换 // 添加光源 const light = new THREE.DirectionalLight(0xffffff, 1); light.position.set(5, 5, 5); scene.add(light); // 常规渲染循环 function animate() { requestAnimationFrame(animate); mesh.rotation.x += 0.01; mesh.rotation.y += 0.01; renderer.render(scene, camera); } animate();
方案3:EdgesGeometry+LineSegments(显示几何体棱边,适合CAD类模型)
如果需要显示模型的每条棱边轮廓,而非整体外轮廓,可以用这个方法:
import * as THREE from 'three'; const scene = new THREE.Scene(); const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); const renderer = new THREE.WebGLRenderer(); renderer.setSize(window.innerWidth, window.innerHeight); document.body.appendChild(renderer.domElement); // 基础模型 const geometry = new THREE.BoxGeometry(1, 1, 1); const material = new THREE.MeshStandardMaterial({ color: 0x556670 }); const mesh = new THREE.Mesh(geometry, material); scene.add(mesh); // 生成棱边几何和线段材质 const edgesGeometry = new THREE.EdgesGeometry(geometry); const lineMaterial = new THREE.LineBasicMaterial({ color: 0x000000 }); const edgeLines = new THREE.LineSegments(edgesGeometry, lineMaterial); mesh.add(edgeLines); // 添加光源 const light = new THREE.DirectionalLight(0xffffff, 1); light.position.set(5, 5, 5); scene.add(light); // 渲染循环 function animate() { requestAnimationFrame(animate); mesh.rotation.x += 0.01; mesh.rotation.y += 0.01; renderer.render(scene, camera); } animate();
内容的提问来源于stack exchange,提问作者Kong
相关产品推荐
相关产品推荐

