You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Three.js弧圈模型边缘平滑及管状分段优化咨询

问题

我现有一个弧圈模型,希望将其边缘处理为平滑圆形而非切割状,同时增加类似使用TorusGeometry时的管状分段(tubular segment)。请问针对该弧圈模型如何实现此效果?该需求是否可行?有没有更优的实现思路?

原代码如下:

HTML代码

<!DOCTYPE html>
<html>
    <body style="margin: 0px; overflow: hidden; text-align:center;">
    <div id = "fivesides">
    </div>
    </body>
</html>

Three.js代码

////////////////////////////////////////////////////////////////////////////////
//      Init
//////////////////////////////////////////////////////////////////////////////////
// init renderer
var renderer = new THREE.WebGLRenderer({
    antialias: true
});

renderer.setClearColor(new THREE.Color(0xdadae5), 1);
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
// array of functions for the rendering loop
var onRenderFcts = [];
// init scene and camera
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(
    45,
    window.innerWidth / window.innerHeight,
    0.01,
    1000
);
camera.position.z = 2;
var controls = new THREE.OrbitControls(camera);
//////////////////////////////////////////////////////////////////////////////////
//      add an object in the scene
//////////////////////////////////////////////////////////////////////////////////
var colors = [0x114575,0x1067AD,0x64A7D7];
var dimensions = [0.1,0.2,0.3];


let shape = new THREE.Shape();
let width, height, x, y, radius;
const pos = new THREE.Vector3();

var  previewSizes = [];
 previewSizes[0] = 20;
 previewSizes[1] = 10;

shape.moveTo( 5, 1 );
shape.absarc( 1, 1, 4, 0, Math.PI * 2, false );
const holePath = new THREE.Path();
holePath.moveTo( 2, 1 );
holePath.absarc( 1, 1, 1, 0, Math.PI * 2, true );
shape.holes.push( holePath );

var settings = { };
settings.depth = 0.4;
settings.bevelEnabled = false;


var geometry = new THREE.ExtrudeGeometry( shape, settings );
//var geometry = new THREE.CylinderGeometry(shape);

var material = new THREE.MeshBasicMaterial({
    color: 0x1067AD,
    vertexColors: THREE.FaceColors
});

//[red, Yellow,purple]
var colorSet = [0x114575, 0x1067AD, 0x64A7D7];

for (var i = 0; i < geometry.faces.length; i++) {
  if (geometry.faces[i].normal.y == 0) {
    geometry.faces[i].color.setHex(colorSet[2]);
  } else if (geometry.faces[i].normal.x == 0) {
    geometry.faces[i].color.setHex(colorSet[0]);
  } else {
    geometry.faces[i].color.setHex(colorSet[1]);
  }
}

var mesh = new THREE.Mesh(geometry, material);

scene.add(mesh);


//////////////////////////////////////////////////////////////////////////////////
//      render the whole thing on the page
//////////////////////////////////////////////////////////////////////////////////
// handle window resize
window.addEventListener(
    "resize",
    function() {
        renderer.setSize(window.innerWidth, window.innerHeight);
        camera.aspect = window.innerWidth / window.innerHeight;
        camera.updateProjectionMatrix();
    },
    false
);
// render the scene
onRenderFcts.push(function() {
    renderer.render(scene, camera);
});

// run the rendering loop
var lastTimeMsec = null;
requestAnimationFrame(function animate(nowMsec) {
    // keep looping
    requestAnimationFrame(animate);
    // measure time
    lastTimeMsec = lastTimeMsec || nowMsec - 1000 / 60;
    var deltaMsec = Math.min(200, nowMsec - lastTimeMsec);
    lastTimeMsec = nowMsec;
    // call each update function
    onRenderFcts.forEach(function(onRenderFct) {
        onRenderFct(deltaMsec / 1000, nowMsec / 1000);
    });
});

解决方案与思路

需求完全可行,有两种主流实现方式,可根据场景选择:

方法一:修改ExtrudeGeometry参数实现平滑边缘

你当前禁用了倒角(bevelEnabled: false),开启并配置倒角参数就能让边缘变成平滑圆形,同时调整形状分段数提升整体细腻度:

  1. 开启bevelEnabled,设置bevelThickness(倒角厚度)、bevelSize(倒角宽度)、bevelSegments(倒角分段数,数值越高边缘越平滑);
  2. 创建Shape的弧线路径时,增加curveSegments参数,提升圆弧本身的分段数,让弧圈轮廓更顺滑。

修改后的关键代码片段:

// 创建Shape时增加圆弧分段数,提升轮廓平滑度
shape.absarc(1, 1, 4, 0, Math.PI * 2, false, 64); // 最后一个参数为curveSegments,设为64足够细腻
const holePath = new THREE.Path();
holePath.moveTo(2, 1);
holePath.absarc(1, 1, 1, 0, Math.PI * 2, true, 64);

// 修改Extrude配置,开启倒角并设置参数
var settings = {
    depth: 0.4,
    bevelEnabled: true,
    bevelThickness: 0.1,
    bevelSize: 0.05,
    bevelSegments: 16 // 倒角分段数,控制边缘平滑度
};

方法二:直接使用TorusGeometry替代(更优方案)

如果你的需求是标准的管状弧圈,直接用TorusGeometry会更高效——它原生支持管状分段(tubularSegments)和圆环分段(radialSegments),无需手动创建Shape:

  • radius:圆环中心到管中心的距离(对应你原模型外弧半径与内弧半径的平均值,即(4+1)/2=2.5);
  • tube:管的半径(外弧半径减内弧半径的一半,即(4-1)/2=1.5);
  • radialSegments:圆环方向的分段数;
  • tubularSegments:管方向的分段数;
  • arc:圆环的弧度,设为Math.PI*2就是完整圆环。

替换后的关键代码:

// 用TorusGeometry替代ExtrudeGeometry,直接实现管状分段与平滑效果
var geometry = new THREE.TorusGeometry(2.5, 1.5, 32, 64); 
// 参数说明:2.5=圆环中心到管中心距离,1.5=管半径,32=圆环分段数,64=管状分段数

// 调整颜色分配逻辑适配TorusGeometry的面结构
for (var i = 0; i < geometry.faces.length; i++) {
    if (i % 3 === 0) {
        geometry.faces[i].color.setHex(colorSet[0]);
    } else if (i % 3 === 1) {
        geometry.faces[i].color.setHex(colorSet[1]);
    } else {
        geometry.faces[i].color.setHex(colorSet[2]);
    }
}

选择建议

  • 若需要保留自定义Shape的特殊轮廓,选方法一;
  • 若只是需要标准管状圆环,方法二更简洁高效,原生支持平滑分段,性能表现更好。

内容的提问来源于Stack Exchange,提问作者that guy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 21:15:52