OpenSubdiv:细分曲面求值

June 24, 2026 · View on GitHub

简介

OpenSubdiv 是一套开源库,用于在大规模并行 CPU 和 GPU 架构上求值和渲染细分曲面。由 Pixar 开发,现由 Academy Software Foundation 维护,它是细分曲面计算的行业标准。

细分曲面允许艺术家使用简单的控制笼对复杂的有机形状进行建模,在渲染时进行平滑细分。

什么是细分曲面?

细分曲面由粗糙的控制网格和一组细分规则定义。在每个级别,网格通过根据这些规则添加新的顶点和面来进行细化。

模型类型控制网格细分结果
简单立方体6 个面,8 个顶点平滑的类球体形状
角色头部~500 个面数百万个平滑多边形
车辆~2000 个面平滑的面板和曲线

为什么使用细分曲面?

优势描述
平滑曲面在奇异点处 C2 连续
拓扑灵活性任何网格拓扑都适用
内存效率小控制笼,详细结果
动画友好变形控制网格,而非密集网格
行业标准所有主要 DCC 工具都使用

细分方案

OpenSubdiv 支持多种细分方案。

方案创建者属性用例
Catmull-ClarkCatmull & Clark规则处 C2,奇异处 C1电影角色
LoopCharles Loop基于三角形,规则处 C2游戏角色
Bilinear-简单边分割平面面板

Catmull-Clark 规则

元素规则结果
面点面顶点的平均值每个面的中心
边点边端点 + 相邻面点的平均值平滑的边中点
顶点点邻域的加权平均值平滑的顶点位置

求值模式

OpenSubdiv 提供多种求值方法。

模式描述性能用例
CPU Uniform标准 CPU 细分良好离线渲染
CPU Feature Adaptive自适应细化更好动画
GPU ComputeOpenCL/CUDA 内核最快实时预览
GPU Vertex顶点着色器方法游戏引擎

安装

从源码构建

git clone https://github.com/AcademySoftwareFoundation/OpenSubdiv.git
cd OpenSubdiv
mkdir build && cd build
cmake .. \
  -DCMAKE_INSTALL_PREFIX=/usr/local \
  -DNO_TBB=OFF \
  -DNO_CUDA=OFF \
  -DNO_OPENCL=OFF
make -j$(nproc)
sudo make install

依赖项

依赖必需用途
CMake构建系统
TBB可选多线程
OpenCL可选GPU 计算
CUDA可选NVIDIA GPU 计算
OpenGL可选GPU 渲染
GLFW可选示例

包管理器

平台命令
macOSbrew install opensubdiv
Ubuntusudo apt install libopensubdiv-dev
vcpkgvcpkg install opensubdiv

核心概念

拓扑细化

拓扑细化决定网格连接在每个级别如何变化。

级别描述顶点数倍增
0控制笼1x
1第一次细分~4x (Catmull-Clark)
2第二次细分~16x
N第 N 次细分~4^N x

面片表

面片表存储细分面片的求值数据。它们对于高效的 GPU 求值至关重要。

面片类型顶点数形状用途
Regular164x4 网格内部面片
Boundary12边面片网格边界
Corner9角面片网格角落
Gregory20Gregory 面片奇异点

特征自适应细化

特征自适应细化不是均匀地细分整个网格,而是仅在奇异顶点和锐利特征附近进行细分。

区域细分原因
规则内部解析面片高效 GPU 求值
奇异点附近额外级别平滑收敛
锐利折痕额外级别精确折痕求值
边界额外级别正确的边界行为

API 概览

模板表

模板表预先计算求值曲面上任意点所需的权重。

#include <opensubdiv/far/topologyDescriptor.h>
#include <opensubdiv/far/stencilTableFactory.h>

using namespace OpenSubdiv;

// 定义网格拓扑
Far::TopologyDescriptor desc;
desc.numVertices = numVertices;
desc.numFaces = numFaces;
desc.numVertsPerFace = vertsPerFace;
desc.vertIndicesPerFace = faceIndices;

// 创建拓扑
Far::TopologyRefiner *refiner = 
    Far::TopologyRefinerFactory<Far::TopologyDescriptor>::Create(desc);

// 细化拓扑
refiner->RefineUniform(Far::TopologyRefiner::UniformOptions(maxLevel));

// 构建模板表
Far::StencilTableFactory::Options options;
options.generateControlVerts = true;
options.generateIntermediateLevels = true;

Far::StencilTable const *stencilTable =
    Far::StencilTableFactory::Create(*refiner, options);

求值

// 在模板点求值位置
std::vector<float> newPositions(stencilTable->GetNumStencils() * 3);

stencilTable->UpdateValues(controlPositions.data(), newPositions.data());

HBR vs FAR vs OSD

OpenSubdiv 有三个主要层。

名称用途性能
HBRHierarchical Boundary Rep参考实现慢(单线程)
FARFeature Adaptive Refinement生产细化快(多线程)
OSDOpenSubdivGPU 求值最快(并行)
用例
HBR正确性测试、旧版兼容
FAR生产细分、CPU 渲染
OSD实时预览、游戏引擎

GPU 求值

OpenSubdiv 通过多种后端支持 GPU 加速求值。

后端API供应商支持性能
OpenGL ComputeGLSL 4.3+全部非常快
OpenCLOpenCL 1.2+全部非常快
CUDACUDANVIDIA最快
DirectX ComputeHLSLWindows非常快

OpenGL 计算着色器示例

#include <opensubdiv/osd/glPatchTable.h>
#include <opensubdiv/osd/glVertexBuffer.h>

// 创建 GPU 缓冲区
Osd::GLVertexBuffer *vbo = Osd::GLVertexBuffer::Create(
    numVertices * 3, patchTable->GetPatchArrays());

// 上传控制顶点
vbo->UpdateCpuBuffer(controlPositions);

// 在 GPU 上求值
Osd::GLComputeEvaluator *evaluator = Osd::GLComputeEvaluator::Create(...);
evaluator->EvalPatches(vbo, ...);

锐利特征

折痕

折痕定义平滑曲面上的锐利边。

折痕权重效果
0.0完全平滑(默认)
1.0略微锐利
5.0非常锐利
10.0+接近硬边
// 设置边折痕权重
desc.numCreases = numCreaseEdges;
desc.creaseVertexIndexPairs = creaseEdges;
desc.creaseWeights = creaseWeights;

// 设置顶点折痕权重
desc.numCorners = numCornerVertices;
desc.cornerIndices = cornerIndices;
desc.cornerWeights = cornerWeights;

与 DCC 工具的集成

工具OpenSubdiv 用途备注
Maya原生 Viewport 2.0GPU 细分显示
Houdini视口细分实时反馈
Blender细分修改器CPU 和 GPU 模式
Katana渲染时细分属性驱动
3ds MaxTurboSmooth 集成基于插件

性能比较

配置细分时间(1M 面到 4M 面)内存
CPU 单线程 (HBR)1200ms
CPU 多线程 (FAR)180ms
GPU Compute (OSD)8ms较高
特征自适应 (FAR)90ms
特征自适应 (OSD)4ms较高

最佳实践

实践建议
拓扑保持控制笼尽可能简单
折痕谨慎使用,优先使用平滑过渡
级别显示用 3-4 级,渲染用更多
面片启用面片表以进行 GPU 求值
自适应对复杂网格使用特征自适应
内存高细分级别时监控 GPU 内存

附加资源

资源URL
文档opensubdiv.org
GitHubgithub.com/AcademySoftwareFoundation/OpenSubdiv
Pixar 技术备忘录Graphics.pixar.com/opensubdiv
SIGGRAPH 论文Graphics.pixar.com