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/