GStatic 用户请注意:Draco 团队强烈建议使用版本化 URL 来访问 Draco GStatic 内容。如果您使用的 URL 中包含v1/decoders
字符串,则边缘缓存和 GStatic 传播延迟可能会导致暂时性错误,在启动新的 Draco 版本时很难诊断这些错误。为了避免此问题,请将您的网站固定到版本控制版本。
src/draco/tools
的install_test
子目录。https://github.com/google/draco/releases
Draco 是一个用于压缩和解压缩 3D 几何网格和点云的库。它旨在改进 3D 图形的存储和传输。
Draco 专为压缩效率和速度而设计和制造。该代码支持压缩点、连接信息、纹理坐标、颜色信息、法线以及与几何相关的任何其他通用属性。借助 Draco,使用 3D 图形的应用程序可以显着缩小,而不会影响视觉保真度。对于用户来说,这意味着应用程序现在可以更快地下载,浏览器中的 3D 图形可以更快地加载,VR 和 AR 场景现在可以用一小部分带宽进行传输并快速渲染。
Draco 以 C++ 源代码形式发布,可用于压缩 3D 图形以及用于编码数据的 C++ 和 Javascript 解码器。
内容
有关搭建说明,请参阅“搭建”。
有关将 Unity 与 Draco 结合使用的最佳信息,请访问 https://github.com/atteneder/DracoUnity
有关将 Unity 与 Draco 结合使用的简单示例,请参阅 unity 文件夹中的 README。
建议始终从以下位置提取 Draco WASM 和 JavaScript 解码器:
https://www.gstatic.com/draco/v1/decoders/
随着越来越多的站点开始使用静态 URL,用户将受益于缓存中的 Draco 解码器。
从构建文件创建的默认目标将是draco_encoder
和draco_decoder
命令行应用程序。此外,当 CMake 在 DRACO_TRANSCODER_SUPPORTED 变量设置为 ON 的情况下运行时,会生成draco_transcoder
(有关更多详细信息,请参阅 BUILDING)。对于所有应用程序,如果您在没有任何参数或-h
情况下运行它们,应用程序将输出用法和选项。
draco_encoder
将读取 OBJ、STL 或 PLY 文件作为输入,并输出 Draco 编码文件。我们已经使用斯坦福大学的兔子网格进行测试。基本的命令行如下所示:
./draco_encoder -i testdata/bun_zipper.ply -o out.drc
量化参数值为0
时,不会对指定属性执行任何量化。 0
以外的任何值都会将指定属性的输入值量化为该位数。例如:
./draco_encoder -i testdata/bun_zipper.ply -o out.drc -qp 14
将位置量化为 14 位(位置坐标默认为 11 位)。
一般来说,对属性的量化越多,获得的压缩率就越高。由您的项目决定它能容忍多少偏差。一般来说,大多数项目可以将量化值设置为11
左右,而不会出现任何明显的质量差异。
压缩级别( -cl
)参数打开/关闭不同的压缩功能。
./draco_encoder -i testdata/bun_zipper.ply -o out.drc -cl 8
一般来说,最高设置10
将具有最大的压缩速度,但解压速度最差。 0
将具有最少的压缩,但解压速度最好。默认设置为7
。
您可以通过指定-point_cloud
参数,使用draco_encoder
对点云数据进行编码。如果您使用网格输入文件指定-point_cloud
参数, draco_encoder
将忽略连接数据并对网格文件中的位置进行编码。
./draco_encoder -point_cloud -i testdata/bun_zipper.ply -o out.drc
此命令行会将网格输入编码为点云,即使输入可能不会产生代表其他点云的压缩。具体来说,对于更大、更密集的点云,我们可以期待更好的压缩率。
draco_decoder
将读取 Draco 文件作为输入,并输出 OBJ、STL 或 PLY 文件。基本的命令行如下所示:
./draco_decoder -i in.drc -o out.obj
draco_transcoder
可用于向 glTF 资源添加 Draco 压缩。基本的命令行如下所示:
./draco_transcoder -i in.glb -o out.glb
此命令行将为in.glb
文件中的所有网格添加几何压缩。可以与draco_encoder
工具类似地指定不同 glTF 属性的量化值。例如-qp
可用于定义位置属性的量化:
./draco_transcoder -i in.glb -o out.glb -qp 12
如果您想向应用程序添加解码功能,则需要包含draco_dec
库。为了使用 Draco 解码器,您需要使用压缩数据初始化DecoderBuffer
。然后调用DecodeMeshFromBuffer()
返回解码后的网格对象,或调用DecodePointCloudFromBuffer()
返回解码后的PointCloud
对象。例如:
draco::DecoderBuffer buffer;
buffer.Init(data.data(), data.size());
const draco::EncodedGeometryType geom_type =
draco::GetEncodedGeometryType (&buffer);
if (geom_type == draco::TRIANGULAR_MESH) {
unique_ptr<draco::Mesh> mesh = draco::DecodeMeshFromBuffer (&buffer);
} else if (geom_type == draco::POINT_CLOUD) {
unique_ptr<draco::PointCloud> pc = draco::DecodePointCloudFromBuffer (&buffer);
}
请参阅 src/draco/mesh/mesh.h 了解完整的Mesh
类接口,请参阅 src/draco/point_cloud/point_cloud.h 了解完整的PointCloud
类接口。
Javascript 编码器位于javascript/draco_encoder.js
。编码器 API 可用于压缩网格和点云。为了使用编码器,您需要首先创建DracoEncoderModule
的实例。然后使用该实例创建MeshBuilder
和Encoder
对象。 MeshBuilder
用于根据几何数据构造网格,稍后可以通过Encoder
进行压缩。首先使用new encoderModule.Mesh()
创建一个网格对象。然后,使用AddFacesToMesh()
向网格添加索引,并使用AddFloatAttributeToMesh()
向网格添加属性数据,例如位置、法线、颜色和纹理坐标。构建网格后,您可以使用EncodeMeshToDracoBuffer()
来压缩网格。例如:
const mesh = {
indices : new Uint32Array ( indices ) ,
vertices : new Float32Array ( vertices ) ,
normals : new Float32Array ( normals )
} ;
const encoderModule = DracoEncoderModule ( ) ;
const encoder = new encoderModule . Encoder ( ) ;
const meshBuilder = new encoderModule . MeshBuilder ( ) ;
const dracoMesh = new encoderModule . Mesh ( ) ;
const numFaces = mesh . indices . length / 3 ;
const numPoints = mesh . vertices . length ;
meshBuilder . AddFacesToMesh ( dracoMesh , numFaces , mesh . indices ) ;
meshBuilder . AddFloatAttributeToMesh ( dracoMesh , encoderModule . POSITION ,
numPoints , 3 , mesh . vertices ) ;
if ( mesh . hasOwnProperty ( 'normals' ) ) {
meshBuilder . AddFloatAttributeToMesh (
dracoMesh , encoderModule . NORMAL , numPoints , 3 , mesh . normals ) ;
}
if ( mesh . hasOwnProperty ( 'colors' ) ) {
meshBuilder . AddFloatAttributeToMesh (
dracoMesh , encoderModule . COLOR , numPoints , 3 , mesh . colors ) ;
}
if ( mesh . hasOwnProperty ( 'texcoords' ) ) {
meshBuilder . AddFloatAttributeToMesh (
dracoMesh , encoderModule . TEX_COORD , numPoints , 3 , mesh . texcoords ) ;
}
if ( method === "edgebreaker" ) {
encoder . SetEncodingMethod ( encoderModule . MESH_EDGEBREAKER_ENCODING ) ;
} else if ( method === "sequential" ) {
encoder . SetEncodingMethod ( encoderModule . MESH_SEQUENTIAL_ENCODING ) ;
}
const encodedData = new encoderModule . DracoInt8Array ( ) ;
// Use default encoding setting.
const encodedLen = encoder . EncodeMeshToDracoBuffer ( dracoMesh ,
encodedData ) ;
encoderModule . destroy ( dracoMesh ) ;
encoderModule . destroy ( encoder ) ;
encoderModule . destroy ( meshBuilder ) ;
请参阅 src/draco/javascript/emscripten/draco_web_encoder.idl 了解完整的 API。
Javascript 解码器位于 javascript/draco_decoder.js 中。 Javascript解码器可以解码网格和点云。为了使用解码器,您必须首先创建DracoDecoderModule
的实例。然后该实例用于创建DecoderBuffer
和Decoder
对象。在DecoderBuffer
中设置编码数据。然后调用GetEncodedGeometryType()
来识别几何图形的类型,例如网格或点云。然后调用DecodeBufferToMesh()
或DecodeBufferToPointCloud()
,这将返回一个 Mesh 对象或点云。例如:
// Create the Draco decoder.
const decoderModule = DracoDecoderModule ( ) ;
const buffer = new decoderModule . DecoderBuffer ( ) ;
buffer . Init ( byteArray , byteArray . length ) ;
// Create a buffer to hold the encoded data.
const decoder = new decoderModule . Decoder ( ) ;
const geometryType = decoder . GetEncodedGeometryType ( buffer ) ;
// Decode the encoded geometry.
let outputGeometry ;
let status ;
if ( geometryType == decoderModule . TRIANGULAR_MESH ) {
outputGeometry = new decoderModule . Mesh ( ) ;
status = decoder . DecodeBufferToMesh ( buffer , outputGeometry ) ;
} else {
outputGeometry = new decoderModule . PointCloud ( ) ;
status = decoder . DecodeBufferToPointCloud ( buffer , outputGeometry ) ;
}
// You must explicitly delete objects created from the DracoDecoderModule
// or Decoder.
decoderModule . destroy ( outputGeometry ) ;
decoderModule . destroy ( decoder ) ;
decoderModule . destroy ( buffer ) ;
请参阅 src/draco/javascript/emscripten/draco_web_decoder.idl 了解完整的 API。
Javascript 解码器是使用动态内存构建的。这将使解码器能够处理所有压缩数据。但这个选项并不是最快的。预分配内存可使解码器速度提高约 2 倍。如果您知道项目的所有内存要求,则可以通过相应更改CMakeLists.txt
来打开静态内存。
从 v1.0 开始,Draco 提供元数据功能,用于编码几何以外的数据。它可用于对任何自定义数据以及几何图形进行编码。例如,我们可以启用元数据功能来对属性名称、子对象名称和自定义信息进行编码。对于一个网格和点云,它可以有一个顶级几何元数据类。然后,顶级元数据可以具有分层元数据。除此之外,顶级元数据可以具有每个属性的元数据,称为属性元数据。属性元数据应使用网格内相应的属性 ID 进行初始化。元数据 API 以 C++ 和 Javascript 形式提供。例如,要在 C++ 中添加元数据:
draco::PointCloud pc;
// Add metadata for the geometry.
std::unique_ptr<draco::GeometryMetadata> metadata =
std::unique_ptr<draco::GeometryMetadata>( new draco::GeometryMetadata());
metadata-> AddEntryString ( " description " , " This is an example. " );
pc.AddMetadata(std::move(metadata));
// Add metadata for attributes.
draco::GeometryAttribute pos_att;
pos_att.Init(draco::GeometryAttribute::POSITION, nullptr , 3 ,
draco::DT_FLOAT32, false , 12 , 0 );
const uint32_t pos_att_id = pc.AddAttribute(pos_att, false , 0 );
std::unique_ptr<draco::AttributeMetadata> pos_metadata =
std::unique_ptr<draco::AttributeMetadata>(
new draco::AttributeMetadata(pos_att_id));
pos_metadata-> AddEntryString ( " name " , " position " );
// Directly add attribute metadata to geometry.
// You can do this without explicitly add |GeometryMetadata| to mesh.
pc.AddAttributeMetadata(pos_att_id, std::move(pos_metadata));
要从 C++ 中的几何图形读取元数据:
// Get metadata for the geometry.
const draco::GeometryMetadata *pc_metadata = pc.GetMetadata();
// Request metadata for a specific attribute.
const draco::AttributeMetadata *requested_pos_metadata =
pc.GetAttributeMetadataByStringEntry( " name " , " position " );
请参阅 src/draco/metadata 和 src/draco/point_cloud 了解完整的 API。
Draco NPM NodeJS 包位于 javascript/npm/draco3d 中。详细使用方法请查看文件夹中的文档。
以下是使用three.js
渲染器通过 Javascript 解码器加载的 Draco 进行几何压缩的示例。
请参阅 javascript/example/README.md 文件以获取更多信息。
Emscripten 构建的 Draco javascript 解码器的预构建版本托管在 www.gstatic.com 上的版本标记目录中:
https://www.gstatic.com/draco/versioned/decoders/VERSION/*
从 v1.4.3 版本开始,可用的文件有:
从 v1.5.1 版本开始,启用断言的以下文件的版本可用:
如有问题/意见,请发送电子邮件至 [email protected]
如果您在此库中发现错误,请在 https://github.com/google/draco/issues 提交问题
鼓励修补程序,并且可以通过分叉此项目并通过 GitHub 提交拉取请求来提交修补程序。有关更多详细信息,请参阅贡献。
根据 Apache 许可证 2.0 版(“许可证”)获得许可;除非遵守许可证,否则您不得使用此文件。您可以在以下位置获取许可证副本:
http://www.apache.org/licenses/LICENSE-2.0
除非适用法律要求或书面同意,否则根据许可证分发的软件均按“原样”分发,不带任何明示或暗示的保证或条件。请参阅许可证,了解许可证下管理权限和限制的特定语言。
斯坦福大学图形系的兔子模型 https://graphics.stanford.edu/data/3Dscanrep/