ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

three.js ExtrudeGeometry 完全指南:用 Shape 轮廓生成可倒角、可沿路径扫掠的三维几何体

three.js ExtrudeGeometry 完全指南:用 Shape 轮廓生成可倒角、可沿路径扫掠的三维几何体 three.js ExtrudeGeometry 完全指南用 Shape 轮廓生成可倒角、可沿路径扫掠的三维几何体【免费下载链接】three.jsJavaScript 3D Library.项目地址: https://gitcode.com/GitHub_Trending/th/three.jsExtrudeGeometry拉伸几何体是 three.js 中把二维平面轮廓Shape拉出厚度变成三维实体的核心工具广泛用于 3D 文字牌匾、建筑体块、徽章图标、管状管道以及任意带孔轮廓实体等场景。本文基于 官方文档页面 展开并结合仓库内 源码实现 与其配套单元测试与官方示例系统讲解它的构造方式、全部拉伸与倒角bevel参数、UV 生成机制、沿 3D 曲线扫掠的进阶用法以及 JSON 序列化往返的底层细节。读完你即可在 WebGL 场景中从零构造出可控的拉伸几何体并理解每个参数在源码层面如何影响顶点与面片的生成。功能与继承关系ExtrudeGeometry从二维Shape可以是一个也可以是数组出发按一定厚度沿 Z 轴直线拉伸或沿一条三维样条曲线路径扫掠生成具有顶盖、底面与侧壁的封闭网格。它继承自BufferGeometry其继承链为EventDispatcher → BufferGeometry → ExtrudeGeometry因此它拥有BufferGeometry提供的全部能力setAttribute、computeVertexNormals、addGroup、toJSON、dispose等。从源码this.type ExtrudeGeometryExtrudeGeometry.js可以看出其类型标识继承关系也被单元测试中object instanceof BufferGeometry true的断言所验证。在几何体工厂集合src/geometries/Geometries.js中它通过export *统一导出因此可直接import { ExtrudeGeometry } from three使用也可通过new THREE.ExtrudeGeometry(...)访问。快速上手矩形拉伸示例文档首页给出的最小可用示例同样内嵌于源码 JSDoc见 ExtrudeGeometry.jsconst length 12, width 8; const shape new THREE.Shape(); shape.moveTo( 0, 0 ); shape.lineTo( 0, width ); shape.lineTo( length, width ); shape.lineTo( length, 0 ); shape.lineTo( 0, 0 ); const geometry new THREE.ExtrudeGeometry( shape ); const material new THREE.MeshBasicMaterial( { color: 0x00ff00 } ); const mesh new THREE.Mesh( geometry, material ); scene.add( mesh );moveTo/lineTo以当前坐标系为单位绘制 2D 多边形路径默认参数深度depth 1、开启倒角bevelEnabled true下会生成一块边缘带圆滑倒角的矩形板。若想获得平整边缘的立方体块可显式关闭倒角const geometry new THREE.ExtrudeGeometry( shape, { depth: 8, bevelEnabled: false, steps: 1 } );构造器与参数总览new ExtrudeGeometry( shapes : Shape | Array.Shape, options : ExtrudeGeometry~Options )shapes单个Shape或多个Shape组成的数组。源码在构造时先将入参规整为数组再逐个处理shapes Array.isArray( shapes ) ? shapes : [ shapes ]每个 Shape 都会经过一次addShape()完整流程ExtrudeGeometry.js。options拉伸设置对象。未传入时默认使用{}所有参数走源码默认值见 ExtrudeGeometry.js下表汇总了完整参数项、默认值与含义参数类型默认值含义curveSegmentsnumber12轮廓曲线上用于近似曲线的取样点数量值越大曲线越平滑、顶点越多stepsnumber1沿拉伸深度或扫掠路径方向细分的层段数depthnumber1沿 Z 轴拉伸的深度仅直线拉伸时生效bevelEnabledbooleantrue是否在轮廓边缘生成倒角bevelThicknessnumber0.2倒角沿 Z 轴即向原轮廓内部纵深方向的厚度bevelSizenumberbevelThickness - 0.1倒角从轮廓边缘向外XY 平面法线方向扩展的距离bevelOffsetnumber0倒角在 XY 平面内从轮廓边缘算起的起始偏移距离bevelSegmentsnumber3倒角的分层数越大越圆润extrudePathCurveCurve3null供 Shape 沿其扫掠的三维曲线路径沿路径拉伸时不支持倒角UVGeneratorObjectWorldUVGenerator提供自定义 UV 生成函数的对象generateTopUV/generateSideWallUV逐项参数详解与源码行为curveSegments当 Shape 中包含曲线圆弧、样条、二次/三次贝塞尔时曲线会被离散成若干个点。文档描述为曲线上的取样点数量。它同时传递给shape.extractPoints( curveSegments )用于控制 Shape 轮廓含孔洞的取点密度ExtrudeGeometry.js。steps拉伸方向的分层数。直线拉伸时相邻两层间距为depth / steps * sExtrudeGeometry.js沿路径扫掠时对应路径上取样点数量——源码通过extrudePath.getSpacedPoints( steps )在路径上均匀取steps 1个点ExtrudeGeometry.js。steps越大侧面越顺滑但顶点数线性增长。depth仅对直线拉伸有意义控制 Z 方向拉伸总高度。默认1若depth: 0且关闭倒角可得到近似平面但合法正反面朝向相反的双面片结构。倒角五参数bevelEnabled / bevelThickness / bevelSize / bevelOffset / bevelSegments这是ExtrudeGeometry最有特色的能力用于把生硬的棱边修出 45° 切角乃至圆角。源码中的取值规律为当bevelEnabled false时其余倒角参数会被强制清零bevelSegments 0; bevelThickness 0; bevelSize 0; bevelOffset 0ExtrudeGeometry.js。倒角层的几何位置按三角函数插值计算ExtrudeGeometry.jsconst t b / bevelSegments; const z bevelThickness * Math.cos( t * Math.PI / 2 ); // Z 方向厚度 const bs bevelSize * Math.sin( t * Math.PI / 2 ) bevelOffset; // XY 平面扩缩可见厚度按余弦衰减、向外扩缩量按正弦递增从而形成过渡自然的锥形倒角b从 0 扫到bevelSegments即产生层。extrudePath传一条三维曲线Curve典型如CatmullRomCurve3后Shape 会像牙膏一样沿曲线方向扫掠出管状实体。源码为该分支做了两件关键事通过extrudePath.getSpacedPoints( steps )取路径点调用extrudePath.computeFrenetFrames( steps, isClosed )计算 Frenet 活动标架法线/副法线/切线把二维 Shape 的x、y分别映射到法线与副法线方向ExtrudeGeometry.js。UVGenerator传入自定义对象可接管 UV 映射。默认实现WorldUVGenerator提供两个方法generateTopUV直接把顶面/底面的世界 XY 坐标当作 UVgenerateSideWallUV则依据侧壁面法向选择 XZ 或 YZ 平面展开为 UVExtrudeGeometry.js。因此默认 UV 并非归一化的 0–1若希望纹理按单位比例平铺可基于默认实现自定义。源码级原理顶点、面、UV 与材质分组如何生成深入 addShape 实现 可以看清整个网格生成管线大致分六步方向统一调用ShapeUtils.isClockWise检测轮廓绕向非顺时针轮廓会被reverse()保证内外环方向一致、面朝向稳定ExtrudeGeometry.js。重叠点清理mergeOverlappingPoints会把距离在1e-10量级按点坐标幅值缩放的相邻重合点原地剔除防止退化三角面ExtrudeGeometry.js。倒角方向向量为每个顶点计算使其轮廓向内/外平移的单位位移向量getBevelVec它基于相邻两条边做左移 1 单位的平行线求交得到并针对共线边、尖角做了特判防止尖刺ExtrudeGeometry.js。平面三角化把轮廓与孔洞交给ShapeUtils.triangulateShape做耳切法三角剖分得到顶/底盖面的三角索引ExtrudeGeometry.js。生成各层顶点依次写入底面、中部steps层、倒角层的顶点每次写入通过内部函数v()/addVertex()追加到统一verticesArray层与层之间以vlen单层顶点数为步长偏移ExtrudeGeometry.js。生成三角面与 UVbuildLidFaces()生成顶/底盖面buildSideFaces()按四边形的两个对角拆三角形生成侧壁面随后调用 UVGenerator 补全每张面的 UV 坐标ExtrudeGeometry.js。值得关注的是材质分组groupsaddShape会分别执行scope.addGroup( ..., 0 )盖面与scope.addGroup( ..., 1 )侧壁面ExtrudeGeometry.js因此可以直接给Mesh传材质数组例如让盖面与侧壁使用不同材质。构造收尾处调用this.computeVertexNormals()统一计算逐顶点法线ExtrudeGeometry.js整个构造过程默认不产生索引index 为空以非索引三角形列表存储。使用带孔洞Holes的 ShapeExtrudeGeometry天然支持内孔只要在Shape上追加孔洞路径即可。以官方 webgl_geometry_shapes 示例 中的笑脸造型为例const smileyShape new THREE.Shape(); // ... 绘制面部外轮廓 ... smileyShape.holes.push( smileyEye1Path ); // 左眼 smileyShape.holes.push( smileyEye2Path ); // 右眼 smileyShape.holes.push( smileyMouthPath ); // 嘴 const geometry new THREE.ExtrudeGeometry( smileyShape, extrudeSettings );示例实际使用的拉伸参数为{ depth: 8, bevelEnabled: true, bevelSegments: 2, steps: 2, bevelSize: 1, bevelThickness: 1 }webgl_geometry_shapes.html。源码中孔洞会作为独立轮廓参与绕向修正与三角化holes.forEach( mergeOverlappingPoints )并对孔洞顶点计算各自的外扩倒角方向孔洞外扩对应实体收缩见expandedHoleVertices逻辑保证带孔造型的倒角在几何上依然正确。进阶实战沿 3D 路径扫掠这是extrudePath参数的经典用法。官方示例 webgl_geometry_extrude_shapes.html 展示了完整的参数组合把三角形、星形等平面轮廓沿闭合或随机样条扫掠成三维轨迹体。沿一条闭合样条扫掠的完整配置// 1. 构造三维路径闭合的 CatmullRom 样条 const closedSpline new THREE.CatmullRomCurve3( [ new THREE.Vector3( - 60, - 100, 60 ), new THREE.Vector3( - 60, 20, 60 ), new THREE.Vector3( - 60, 120, 60 ), new THREE.Vector3( 60, 20, - 60 ), new THREE.Vector3( 60, - 100, - 60 ) ] ); closedSpline.curveType catmullrom; closedSpline.closed true; // 2. 构造二维截面轮廓三角形 const pts [], count 3; for ( let i 0; i count; i ) { const l 20; const a 2 * i / count * Math.PI; pts.push( new THREE.Vector2( Math.cos( a ) * l, Math.sin( a ) * l ) ); } const shape new THREE.Shape( pts ); // 3. 沿路径拉伸注意路径拉伸不支持倒角 const extrudeSettings { steps: 100, // 路径上的取样密度 bevelEnabled: false, // 必须关闭源码会自动强制关闭 extrudePath: closedSpline }; const geometry new THREE.ExtrudeGeometry( shape, extrudeSettings ); const mesh new THREE.Mesh( geometry, new THREE.MeshLambertMaterial( { color: 0xb00000 } ) ); scene.add( mesh );同示例还对同一轮廓分别演示了直线拉伸 开启倒角的对照配置webgl_geometry_extrude_shapes.htmlconst extrudeSettings3 { depth: 20, steps: 1, bevelEnabled: true, bevelThickness: 2, bevelSize: 4, bevelSegments: 1 };使用提示路径拉伸路径上的扫掠密度由steps控制steps越大轨迹越平滑示例中分别用了100、200但顶点开销同步上升若路径闭合需将样条的closed属性置true否则收尾会出现接缝。若目标是沿路径生成中空圆管可改看 TubeGeometry 扫掠示例 中new THREE.TubeGeometry( extrudePath, tubularSegments, radius, radialSegments, closed )的用法——它与ExtrudeGeometry的路径扫掠互为补充前者以固定圆形截面扫掠后者以任意二维轮廓扫掠。Properties 属性.parameters : Object保存构造时传入的{ shapes, options }ExtrudeGeometry.js用于几何体自描述。文档特别强调实例化后修改.parameters不会改变几何体本身——因为网格已在构造期一次性生成参数仅作存档与序列化用途。序列化toJSON 与 fromJSONExtrudeGeometry继承并重写了toJSON()额外把 Shape 引用序列化为uuid列表、把options整体浅拷贝到data.options若存在extrudePath则调用options.extrudePath.toJSON()输出路径曲线ExtrudeGeometry.js。由于 Shape 本体通常通过scene.toJSON()的geometries/shapes映射表存储因此toJSON输出中只保留引用关系。对应的工厂方法ExtrudeGeometry.fromJSON( data : Object, shapes : Array.Shape ) : ExtrudeGeometry静态方法fromJSON从 JSON 反序列化出新实例它根据data.shapes里的uuid从传入的shapes数组中还原每个 Shape并把data.options.extrudePath依其type如CatmullRomCurve3通过new Curves[ type ]().fromJSON( extrudePath )重建为真正的曲线对象最后return new ExtrudeGeometry( geometryShapes, data.options )ExtrudeGeometry.js。所有曲线类型统一注册在 Curves.js 工厂中。此外该类还覆写了copy( source )用Object.assign浅拷贝源实例的parametersExtrudeGeometry.js保证克隆出的几何体在参数层面可自描述。测试与常见注意事项仓库的单元测试覆盖了三类基础断言继承自BufferGeometry、可正常实例化、type字段为ExtrudeGeometry。若要自定义测试可将相关扩展用例置于test/unit/src/geometries/下运行 QUnit 测试套件。结合源码与实际使用还需注意几个易踩点路径扫掠与倒角互斥传入extrudePath时无论bevelEnabled是否为true源码都会强制bevelEnabled falseExtrudeGeometry.js所以别期待沿曲线且带倒角的组合。steps与curveSegments都是成本开关前者增加层数、后者增加每层顶点数二者叠加会显著抬高顶点总量注意与bevelSegments一起控制。闭合路径需显式声明computeFrenetFrames依据isCatmullRomCurve3 ? closed : false判断路径是否闭合ExtrudeGeometry.js非CatmullRomCurve3的路径类型需自行保证语义。UV 为世界坐标量纲默认 UV 未归一化纹理映射表现与模型单位尺度直接相关需要铺贴一致纹理时可考虑自定义UVGenerator。法线已自动计算构造完成后几何体即带有平滑后的顶点法线直接用于MeshStandardMaterial/MeshLambertMaterial即可获得正确光照如希望硬边效果可自行computeVertexNormals()或拆离顶点。如需查阅类文档全文、源码与配套用例可分别查看 ExtrudeGeometry 文档页、ExtrudeGeometry 源码、单元测试并在 webgl_geometry_extrude_shapes 示例 与 webgl_geometry_shapes 示例 中动手调整参数体验效果。【免费下载链接】three.jsJavaScript 3D Library.项目地址: https://gitcode.com/GitHub_Trending/th/three.js创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表