Blender导出OBJ模型在Three.js中加载时顶点数增多原因
核心原因
两边的顶点统计规则从根上就不一样,不是导出或者加载出了bug:
- Blender里显示的顶点数,只按空间位置去重,只要坐标完全一样就算同一个顶点,默认新建的平面就是4个几何顶点。
- Three.js跑在WebGL实时渲染管线上,只有位置、法线、UV、顶点色所有属性全一致的顶点,才会被GPU复用,只要有一个属性对不上,就必须拆成独立顶点,不然渲染结果会出错。
- 所有实时渲染API都只认三角形,不认Blender里的四边面。你看到的平面是1个四边面,进渲染管线会自动拆成2个三角面。如果导出的时候没带统一的平滑法线,OBJLoader默认会给每个三角面算独立的面法线——两个三角面的公共边上的顶点,在两个面里法线方向不一样,自然会被拆成独立顶点,原本4个顶点直接变成6个,看起来就比Blender里的数多。如果模型更复杂、有硬边、UV割裂,顶点数涨30%-100%都很常见。
相关状态参考:

解决方法
Blender端导出前调整
- 选中模型按
Ctrl+A选「全部变换」,把没应用的缩放、旋转先应用,避免法线计算偏移。 - 导出OBJ时按下面调整设置:
- 勾选
Write Normals,把Blender里算好的法线导出去,不要让加载器自行计算面法线 - 有UV的话勾选
Write UVs,保证UV连续不割裂 - 关掉
Triangulate Faces选项,要是必须开的话,先给模型开自动平滑,角度阈值拉到180度,保证整个平面法线完全统一,不会被硬边拆顶点 - 关掉冗余分组选项,比如
Objects as OBJ Groups,减少无效顶点生成
- 勾选
- 如果要纯平面效果,进编辑模式全选顶点,执行
网格>法线>平均面法线,把整个面的法线统一成一个方向。
Three.js端加载后处理
- 拿到模型几何体后,不要直接用默认生成的法线,要是做平滑平面效果,可以手动统一法线,或者用官方工具类把重复顶点合并,示例代码:
import { BufferGeometryUtils } from 'three/addons/utils/BufferGeometryUtils.js'; // 从OBJLoader拿到mesh对象后执行 const mergedGeometry = BufferGeometryUtils.mergeVertices(mesh.geometry, 0.001); mesh.geometry.dispose(); mesh.geometry = mergedGeometry;
- 要是不需要特别精准的法线,也可以调用
geometry.computeVertexNormals()重新计算平滑法线,能消掉大部分没必要的顶点拆分。
内容的提问来源于stack exchange,提问作者Solitary
相关产品推荐
相关产品推荐

