Optimizing 3D data with Draco Geometry Compression
利用Draco几何压缩优化三维数据
About this codelab
subjectLast updated Mar 12, 2024
subject上次更新时间:2024年3月12日
account_circleWritten by a Googler
account_circle由谷歌用户编写
1. Overview
1.概述
3D graphics are a fundamental part of many applications, including gaming, design and data visualization. As graphics processors and creation tools continue to improve, larger and more complex 3D models will become commonplace and help fuel new applications in immersive virtual reality (VR) and augmented reality (AR). Because of this increased model complexity, storage and bandwidth requirements are forced to keep pace with the explosion of 3D data.
3D图形是许多应用程序的基本组成部分,包括游戏、设计和数据可视化。随着图形处理器和创建工具的不断改进,更大、更复杂的3D模型将变得司空见惯,并有助于推动沉浸式虚拟现实(VR)和增强现实(AR)的新应用。由于模型复杂性的增加,存储和带宽需求被迫跟上3D数据爆炸的步伐。
With Draco, applications using 3D graphics can be significantly smaller without compromising visual fidelity. For users this means apps can now be downloaded faster, 3D graphics in the browser can load quicker, and VR and AR scenes can now be transmitted with a fraction of the bandwidth, rendered quickly and look fantastic.
有了Draco,使用3D图形的应用程序可以大大缩小,而不会影响视觉逼真度。对用户来说,这意味着应用程序现在可以更快地下载,浏览器中的3D图形可以更快地加载,VR和AR场景现在可以用一小部分带宽传输,快速渲染,看起来非常棒。
What is Draco?
Draco是什么?
Draco is a library for compressing and decompressing 3D geometric meshes and point clouds. It is intended to improve the storage and transmission of 3D graphics.
Draco是一个用于压缩和解压缩三维几何网格和点云的库。它旨在改善3D图形的存储和传输。
Draco was designed and built for compression efficiency and speed. The code supports compressing points, connectivity information, texture coordinates, color information, normals, and any other generic attributes associated with geometry. Draco is released as C++ source code that can be used to compress 3D graphics as well as C++ and Javascript decoders for the encoded data.
Draco是为压缩效率和速度而设计和制造的。该代码支持压缩点、连接信息、纹理坐标、颜色信息、法线以及与几何体关联的任何其他通用属性。Draco作为C++源代码发布,可用于压缩3D图形以及编码数据的C++和Javascript解码器。
What you will learn
你将学到什么
- How to use Draco to compress a 3D model
- 如何使用Draco压缩3D模型
- How to use different compression models and how they impact model quality and size
- 如何使用不同的压缩模型以及它们如何影响模型质量和大小
- How to view a 3D model on the web
- 如何在web上查看三维模型
What you'll need
你需要什么
- A recent version of Chrome
- Chrome的最新版本
- The sample code
- 示例代码
- A text editor
- 文本编辑器
- Python
- cmake
2. Getting set up
2.设置
Clone the Github repository using this command line:
使用以下命令行克隆Github存储库:
git clone https://github.com/google/draco
Navigate to the Draco root directory.
导航到Draco根目录。
cd draco
3. Build the encoder
3.构建编码器
To start with Draco encoding and decoding, let's start first by building the apps.
要从Draco编码和解码开始,让我们首先从构建应用程序开始。
Build Encoder
生成编码器
- Run cmake from a directory where you would like to generate build files, and pass it the path to your Draco repository.
- 从要生成构建文件的目录中运行cmake,并将路径传递给Draco存储库。
A good place to create your build directory is one directory below the Draco root directory.
创建构建目录的好地方是Draco根目录下的一个目录。
Note: You cannot run cmake out of the Draco root directory.
注意:您不能在Draco根目录之外运行cmake。
mkdir build
cd build
cmake ../
make
4. Encode your first 3D asset
4.对第一个3D资产进行编码
draco_encoder will read OBJ or PLY files as input, and output Draco-encoded files. We have included Stanford's Bunny mesh for testing. The basic command line looks like this:
draco_encoder将读取OBJ或PLY文件作为输入,并输出draco编码的文件。我们已经包括了斯坦福大学的兔子网进行测试。基本命令行如下所示:
./draco_encoder -i ../testdata/bun_zipper.ply -o bunny.drc
You can now look at the size of the output file and compare to the original .ply file. The compressed file should be much smaller than the original file size.
现在可以查看输出文件的大小,并与原始.ply文件进行比较。压缩后的文件应该比原始文件的大小小得多。
The original file was 2.9 MB and the compressed file is about 46 kB. A size reduction of over 60 times.
原始文件为2.9 MB,压缩文件约为46 kB。尺寸缩小了60多倍。
Note: The compressed size can vary based on compression options.
注意:压缩后的大小可能因压缩选项而异。
5. Decode a Draco file in the browser
5.在浏览器中解码Draco文件
At this point we will start with a basic web page to decode Draco files. We'll start by copying and pasting the following code sections into the text editor.
在这一点上,我们将从一个基本的网页开始解码Draco文件。我们将首先将以下代码部分复制并粘贴到文本编辑器中。
5.1Start with basic HTML file.
5.1从基本的HTML文件开始。
<!DOCTYPE html>
<html>
<head>
<title>Codelab - Draco Decoder</title>
5.2The following code snippet will load the Draco WASM decoder.
5.2以下代码片段将加载Draco WASM解码器。
It is recommended to always pull your Draco WASM decoders from https://www.gstatic.com/draco/versioned/decoders/1.4.1/ as it will benefit users having the Draco decoder stored in cache.
建议始终从https://www.gstatic.com/draco/versioned/decoders/1.4.1/因为它将有利于将Draco解码器存储在高速缓存中的用户。
<script src="https://www.gstatic.com/draco/versioned/decoders/1.4.1/draco_wasm_wrapper.js">
// It is recommended to always pull your Draco JavaScript and WASM decoders
// from the above URL. Users will benefit from having the Draco decoder in
// cache as more sites start using the static URL.
</script>
5.3Next add this function, that will create a Draco decoder module. The creation of the decoder module is asynchronous, so you need to wait until the callback is called before you can use the module.
5.3接下来添加这个功能,它将创建一个Draco解码器模块。解码器模块的创建是异步的,因此需要等待回调被调用后才能使用该模块。
<script>
'use strict';
// The global Draco decoder module.
let decoderModule = null;
// Creates the Draco decoder module.
function createDracoDecoderModule() {
let dracoDecoderType = {};
// Callback when the Draco decoder module is fully instantiated. The
// module parameter is the created Draco decoder module.
dracoDecoderType['onModuleLoaded'] = function(module) {
decoderModule = module;
// Download the Draco encoded file and decode.
downloadEncodedMesh('bunny.drc');
};
DracoDecoderModule(dracoDecoderType);
}
5.4Add the function to decode a Draco encoded mesh.
5.4添加解码Draco编码网格的功能。
// Decode an encoded Draco mesh. byteArray is the encoded mesh as
// an Uint8Array.
function decodeMesh(byteArray) {
// Create the Draco decoder.
const decoder = new decoderModule.Decoder();
// Create a buffer to hold the encoded data.
const buffer = new decoderModule.DecoderBuffer();
buffer.Init(byteArray, byteArray.length);
// Decode the encoded geometry.
let outputGeometry = new decoderModule.Mesh();
let decodingStatus = decoder.DecodeBufferToMesh(buffer, outputGeometry);
alert('Num points = ' + outputGeometry.num_points());
// You must explicitly delete objects created from the DracoModule
// or Decoder.
decoderModule.destroy(outputGeometry);
decoderModule.destroy(decoder);
decoderModule.destroy(buffer);
}
5.5Now that we have the Draco decode function in place, add a function to download a Draco encoded mesh. The function ‘downloadEncodedMesh' accepts a parameter to the Draco file to be loaded. In this case it will be ‘bunny.drc' from the previous stage.
5.5现在我们已经有了Draco解码功能,添加一个下载Draco编码网格的功能。函数“downloadEncodedMesh”接受要加载的Draco文件的参数。在这种情况下,它将是前一阶段的“bunny.drc”。
// Download and decode the Draco encoded geometry.
function downloadEncodedMesh(filename) {
// Download the encoded file.
const xhr = new XMLHttpRequest();
xhr.open("GET", filename, true);
xhr.responseType = "arraybuffer";
xhr.onload = function(event) {
const arrayBuffer = xhr.response;
if (arrayBuffer) {
const byteArray = new Uint8Array(arrayBuffer);
decodeMesh(byteArray);
}
};
xhr.send(null);
}
5.6Call the ‘createDracoDecoderModule' function to create the Draco decoder module, which will call ‘downloadEncodedMesh' function to download the encoded Draco file, which will call the ‘decodeMesh' function to decode the encoded Draco mesh.
5.6调用“createDracoDecoderModule”函数创建Draco解码器模块,该模块将调用“downloadEncodedMesh”函数下载编码的Draco文件,该模块会调用“decodeMesh”函数解码编码的Draco-mesh。
// Create the Draco decoder module.
createDracoDecoderModule();
</script>
</head>
<body>
</body>
</html>
5.7Save this file as "DracoDecode.html"
5.7将此文件保存为“DracoDecode.html”
5.8Start the python webserver. In the terminal type:
5.8启动python网络服务器。在终端类型中:
python -m SimpleHTTPServer
5.9Open localhost:8000/DracoDecode.html in Chrome. This should display an alert message box with the number of points (Num points = 34834) that have been decoded from the model.
5.9在Chrome中打开localhost:8000/DracoDecode.html。这将显示一个警告消息框,其中包含已从模型中解码的点数(点数=34834)。
6. Render a Draco file with three.js
6.使用three.js渲染Draco文件
Now that we know how to decode a Draco file using WASM, we'll use a popular web 3D viewer - three.js. As in the previous example we'll start by copying and pasting the following code sections into the text editor.
现在我们知道了如何使用WASM解码Draco文件,我们将使用一个流行的web 3D查看器three.js。与前面的示例一样,我们将首先将以下代码部分复制并粘贴到文本编辑器中。
6.1Start with basic HTML file
6.1从基本HTML文件开始
<!DOCTYPE html>
<html>
<head>
<title>Codelab - Draco three.js Render</title>
6.2Add code to load three.js and Draco three.js loader.
6.2添加代码以加载three.js和Draco three.js加载程序。
<script type="importmap">
{
"imports": {
"three": "https://unpkg.com/three@v0.162.0/build/three.module.js",
"three/addons/": "https://unpkg.com/three@v0.162.0/examples/jsm/"
}
}
</script>
6.3Setup the Draco decoder path.
6.3设置Draco解码器路径。
<script type="module">
// import three.js and DRACOLoader.
import * as THREE from 'three';
import {DRACOLoader} from 'three/addons/loaders/DRACOLoader.js'
// three.js globals.
var camera, scene, renderer;
// Create the Draco loader.
var dracoLoader = new DRACOLoader();
// Specify path to a folder containing WASM/JS decoding libraries.
// It is recommended to always pull your Draco JavaScript and WASM decoders
// from the below URL. Users will benefit from having the Draco decoder in
// cache as more sites start using the static URL.
dracoLoader.setDecoderPath('https://www.gstatic.com/draco/versioned/decoders/1.4.1/');
6.4Add three.js rendering code.
6.4添加three.js渲染代码。
function initThreejs() {
camera = new THREE.PerspectiveCamera( 35, window.innerWidth / window.innerHeight, 0.1, 15 );
camera.position.set( 3, 0.25, 3 );
scene = new THREE.Scene();
scene.background = new THREE.Color( 0x443333 );
scene.fog = new THREE.Fog( 0x443333, 1, 4 );
// Ground
var plane = new THREE.Mesh(
new THREE.PlaneGeometry( 8, 8 ),
new THREE.MeshPhongMaterial( { color: 0x999999, specular: 0x101010 } )
);
plane.rotation.x = - Math.PI / 2;
plane.position.y = 0.03;
plane.receiveShadow = true;
scene.add(plane);
// Lights
var light = new THREE.HemisphereLight( 0x443333, 0x111122 );
scene.add( light );
var light = new THREE.SpotLight();
light.angle = Math.PI / 16;
light.penumbra = 0.5;
light.castShadow = true;
light.position.set( - 1, 1, 1 );
scene.add( light );
// renderer
renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.shadowMap.enabled = true;
const container = document.getElementById('container');
container.appendChild( renderer.domElement );
window.addEventListener( 'resize', onWindowResize, false );
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
function animate() {
render();
requestAnimationFrame( animate );
}
function render() {
var timer = Date.now() * 0.0003;
camera.position.x = Math.sin( timer ) * 0.5;
camera.position.z = Math.cos( timer ) * 0.5;
camera.lookAt( new THREE.Vector3( 0, 0.1, 0 ) );
renderer.render( scene, camera );
}
6.5Add Draco loading and decode code.
6.5添加Draco加载和解码代码。
function loadDracoMesh(dracoFile) {
dracoLoader.load(dracoFile, function ( geometry ) {
geometry.computeVertexNormals();
var material = new THREE.MeshStandardMaterial( { vertexColors: THREE.VertexColors } );
var mesh = new THREE.Mesh( geometry, material );
mesh.castShadow = true;
mesh.receiveShadow = true;
scene.add( mesh );
} );
}
6.6Add code to load the file.
6.6添加代码以加载文件。
window.onload = function() {
initThreejs();
animate();
loadDracoMesh('bunny.drc');
}
</script>
</head>
<body>
<div id="container"></div>
</body>
</html>
6.7Save this file as "DracoRender.html"
6.7将此文件保存为“DracoRender.html”
6.8If needed, restart the webserver.
6.8如果需要,请重新启动Web服务器。
python -m SimpleHTTPServer
6.9Open localhost:8000/DracoRender.html in Chrome. You should now see your Draco file rendered in the browser.
6.9在Chrome中打开localhost:8000/DracoRender.html。现在,应该可以在浏览器中看到渲染的Draco文件。
7. Try different encoding parameters
7.尝试不同的编码参数
The Draco encoder allows for many different parameters that impact the size of the compressed file and visual quality of the code. Try running the next few commands in the command line and seeing the results.
Draco编码器允许许多不同的参数,这些参数会影响压缩文件的大小和代码的视觉质量。尝试在命令行中运行接下来的几个命令并查看结果。
7.1The following command quantizes the model's positions using 12 (default is 11) bits.
7.1以下命令使用12位(默认为11位)量化模型的位置。
./draco_encoder -i ../testdata/bun_zipper.ply -o out12.drc -qp 12
7.2Note the size of the out12.drc compared to the bunny.drc file in the previous section. Using more quantization bits can increase the size of the compressed file.
7.2注意out12.drc与上一节中的bunny.drc文件相比的大小。使用更多的量化比特可以增加压缩文件的大小。
7.3The following command quantizes the model's positions using 6 bits.
7.3以下命令使用6位量化模型的位置。
./draco_encoder -i ../testdata/bun_zipper.ply -o out6.drc -qp 6
7.4Note the size of the out6.drc compared to the bunny.drc file in the previous section. Using fewer quantization bits can reduce the size of the compressed file.
7.4注意out6.drc与上一节中的bunny.drc文件相比的大小。使用更少的量化比特可以减小压缩文件的大小。
Quantizing with too few bits, while resulting in impressive compression ratios, can seriously degrade the quality of the model. If you render out6.drc you should notice that the visual quality is vastly different than the original.
用太少的比特进行量化,同时产生令人印象深刻的压缩比,会严重降低模型的质量。如果渲染out6.drc,应该注意到视觉质量与原始图像有很大不同。
7.5The following parameters impact the compression levels of the model. Using the cl flag, you can tune your compression from 1 (lowest compression ratio) to 10 (highest).
7.5以下参数会影响模型的压缩级别。使用cl标志,可以将压缩从1(最低压缩比)调整到10(最高)。
./draco_encoder -i ../testdata/bun_zipper.ply -o outLow.drc -cl 1
./draco_encoder -i ../testdata/bun_zipper.ply -o outHigh.drc -cl 10
Note the output from the Draco encoder. You can see that there is a tradeoff in the time required to compress at the highest compression levels compared to the savings in bits. The correct parameter for your application will depend on timing and size requirements at encode time.
注意Draco编码器的输出。可以看到,与比特节省相比,在最高压缩级别下压缩所需的时间是有折衷的。应用程序的正确参数将取决于编码时的时间和大小要求。
8. Congratulations
8.祝贺
You've finished the Draco mesh compression code lab and successfully explored many key features of Draco!
您已经完成了Draco网格压缩代码实验室,并成功探索了Draco的许多关键功能!
Hopefully it's clear to you how Draco can help make your 3D assets smaller and more efficient to transmit over the web. You can learn more about Draco and get the latest library from github.
希望你能清楚地知道Draco如何帮助你的3D资产变得更小,更高效地在网络上传输。可以了解更多关于Draco的信息,并从github获取最新的库。