Atenção, usuários do GStatic: a equipe do Draco recomenda fortemente o uso de URLs versionados para acessar o conteúdo do Draco GStatic. Se você estiver usando URLs que incluem a substring v1/decoders
na URL, o cache de borda e os atrasos de propagação GStatic podem resultar em erros transitórios que podem ser difíceis de diagnosticar quando novas versões do Draco são lançadas. Para evitar o problema, fixe seus sites em uma versão com versão.
install_test
de src/draco/tools
para obter mais informações.https://github.com/google/draco/releases
Draco é uma biblioteca para compactar e descompactar malhas geométricas 3D e nuvens de pontos. Destina-se a melhorar o armazenamento e transmissão de gráficos 3D.
Draco foi projetado e construído para eficiência e velocidade de compressão. O código suporta pontos de compactação, informações de conectividade, coordenadas de textura, informações de cores, normais e quaisquer outros atributos genéricos associados à geometria. Com o Draco, os aplicativos que usam gráficos 3D podem ser significativamente menores sem comprometer a fidelidade visual. Para os usuários, isso significa que os aplicativos agora podem ser baixados mais rapidamente, os gráficos 3D no navegador podem carregar mais rapidamente e as cenas de VR e AR agora podem ser transmitidas com uma fração da largura de banda e renderizadas rapidamente.
Draco é lançado como código-fonte C++ que pode ser usado para compactar gráficos 3D, bem como decodificadores C++ e Javascript para os dados codificados.
Conteúdo
Consulte CONSTRUÇÃO para obter instruções de construção.
Para obter as melhores informações sobre como usar o Unity com Draco, visite https://github.com/atteneder/DracoUnity
Para um exemplo simples de uso do Unity com Draco, consulte README na pasta Unity.
É recomendado sempre extrair seus decodificadores Draco WASM e JavaScript de:
https://www.gstatic.com/draco/v1/decoders/
Os usuários se beneficiarão com o decodificador Draco em cache à medida que mais sites começarem a usar o URL estático.
O destino padrão criado a partir dos arquivos de construção serão os aplicativos de linha de comando draco_encoder
e draco_decoder
. Além disso, draco_transcoder
é gerado quando o CMake é executado com a variável DRACO_TRANSCODER_SUPPORTED definida como ON (veja BUILDING para mais detalhes). Para todos os aplicativos, se você executá-los sem argumentos ou -h
, os aplicativos exibirão uso e opções.
draco_encoder
lerá arquivos OBJ, STL ou PLY como entrada e produzirá arquivos codificados em Draco. Incluímos a malha Bunny de Stanford para teste. A linha de comando básica é assim:
./draco_encoder -i testdata/bun_zipper.ply -o out.drc
Um valor 0
para o parâmetro de quantização não executará nenhuma quantização no atributo especificado. Qualquer valor diferente de 0
quantizará os valores de entrada do atributo especificado para esse número de bits. Por exemplo:
./draco_encoder -i testdata/bun_zipper.ply -o out.drc -qp 14
quantizará as posições em 14 bits (o padrão é 11 para as coordenadas de posição).
Em geral, quanto mais você quantizar seus atributos, melhor será a taxa de compressão. Cabe ao seu projeto decidir quanto desvio ele tolerará. Em geral, a maioria dos projetos pode definir valores de quantização de cerca de 11
sem qualquer diferença perceptível na qualidade.
O parâmetro nível de compactação ( -cl
) ativa/desativa diferentes recursos de compactação.
./draco_encoder -i testdata/bun_zipper.ply -o out.drc -cl 8
Em geral, a configuração mais alta, 10
, terá a maior compressão, mas a pior velocidade de descompressão. 0
terá a menor compactação, mas a melhor velocidade de descompactação. A configuração padrão é 7
.
Você pode codificar dados de nuvem de pontos com draco_encoder
especificando o parâmetro -point_cloud
. Se você especificar o parâmetro -point_cloud
com um arquivo de entrada de malha, draco_encoder
ignorará os dados de conectividade e codificará as posições do arquivo de malha.
./draco_encoder -point_cloud -i testdata/bun_zipper.ply -o out.drc
Esta linha de comando codificará a entrada da malha como uma nuvem de pontos, mesmo que a entrada possa não produzir uma compactação representativa de outras nuvens de pontos. Especificamente, pode-se esperar taxas de compressão muito melhores para nuvens de pontos maiores e mais densas.
draco_decoder
irá ler arquivos Draco como entrada e gerar arquivos OBJ, STL ou PLY. A linha de comando básica é assim:
./draco_decoder -i in.drc -o out.obj
draco_transcoder
pode ser usado para adicionar compactação Draco aos ativos glTF. A linha de comando básica é assim:
./draco_transcoder -i in.glb -o out.glb
Esta linha de comando adicionará compactação geométrica a todas as malhas no arquivo in.glb
. Os valores de quantização para diferentes atributos glTF podem ser especificados de forma semelhante à ferramenta draco_encoder
. Por exemplo -qp
pode ser usado para definir a quantização do atributo de posição:
./draco_transcoder -i in.glb -o out.glb -qp 12
Se desejar adicionar decodificação aos seus aplicativos, você precisará incluir a biblioteca draco_dec
. Para usar o decodificador Draco você precisa inicializar um DecoderBuffer
com os dados compactados. Em seguida, chame DecodeMeshFromBuffer()
para retornar um objeto de malha decodificado ou chame DecodePointCloudFromBuffer()
para retornar um objeto PointCloud
decodificado. Por exemplo:
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);
}
Consulte src/draco/mesh/mesh.h para a interface completa da classe Mesh
e src/draco/point_cloud/point_cloud.h para a interface completa da classe PointCloud
.
O codificador Javascript está localizado em javascript/draco_encoder.js
. A API do codificador pode ser usada para compactar malha e nuvem de pontos. Para usar o codificador, você precisa primeiro criar uma instância de DracoEncoderModule
. Em seguida, use esta instância para criar objetos MeshBuilder
e Encoder
. MeshBuilder
é usado para construir uma malha a partir de dados geométricos que podem ser posteriormente compactados pelo Encoder
. Primeiro crie um objeto de malha usando new encoderModule.Mesh()
. Em seguida, use AddFacesToMesh()
para adicionar índices à malha e use AddFloatAttributeToMesh()
para adicionar dados de atributos à malha, por exemplo, coordenadas de posição, normal, cor e textura. Depois que uma malha for construída, você poderá usar EncodeMeshToDracoBuffer()
para compactar a malha. Por exemplo:
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 ) ;
Consulte src/draco/javascript/emscripten/draco_web_encoder.idl para obter a API completa.
O decodificador Javascript está localizado em javascript/draco_decoder.js. O decodificador Javascript pode decodificar malha e nuvem de pontos. Para usar o decodificador, você deve primeiro criar uma instância de DracoDecoderModule
. A instância é então usada para criar objetos DecoderBuffer
e Decoder
. Defina os dados codificados no DecoderBuffer
. Em seguida, chame GetEncodedGeometryType()
para identificar o tipo de geometria, por exemplo, malha ou nuvem de pontos. Em seguida, chame DecodeBufferToMesh()
ou DecodeBufferToPointCloud()
, que retornará um objeto Mesh ou uma nuvem de pontos. Por exemplo:
// 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 ) ;
Consulte src/draco/javascript/emscripten/draco_web_decoder.idl para obter a API completa.
O decodificador Javascript é construído com memória dinâmica. Isso permitirá que o decodificador funcione com todos os dados compactados. Mas esta opção não é a mais rápida. A pré-alocação de memória proporciona uma melhoria de 2x na velocidade do decodificador. Se você conhece todos os requisitos de memória do seu projeto, pode ativar a memória estática alterando CMakeLists.txt
adequadamente.
A partir da versão 1.0, o Draco fornece funcionalidade de metadados para codificação de dados diferentes da geometria. Ele pode ser usado para codificar quaisquer dados personalizados junto com a geometria. Por exemplo, podemos habilitar a funcionalidade de metadados para codificar o nome dos atributos, nome dos subobjetos e informações personalizadas. Para uma malha e nuvem de pontos, ela pode ter uma classe de metadados de geometria de nível superior. Os metadados de nível superior podem então ter metadados hierárquicos. Fora isso, os metadados de nível superior podem ter metadados para cada atributo, que são chamados de metadados de atributos. Os metadados do atributo devem ser inicializados com o ID do atributo correspondente dentro da malha. A API de metadados é fornecida em C++ e Javascript. Por exemplo, para adicionar metadados em 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));
Para ler metadados de uma geometria em 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 " );
Consulte src/draco/metadata e src/draco/point_cloud para obter a API completa.
O pacote Draco NPM NodeJS está localizado em javascript/npm/draco3d. Consulte o documento na pasta para uso detalhado.
Aqui está um exemplo de uma geometria compactada com Draco carregada por meio de um decodificador Javascript usando o renderizador three.js
.
Consulte o arquivo javascript/example/README.md para obter mais informações.
Versões pré-construídas dos decodificadores javascript Draco construídos em Emscripten estão hospedadas em www.gstatic.com em diretórios rotulados de versão:
https://www.gstatic.com/draco/versioned/decoders/VERSION/*
A partir da versão v1.4.3, os arquivos disponíveis são:
A partir da versão v1.5.1, compilações habilitadas dos seguintes arquivos estão disponíveis:
Para perguntas/comentários, envie um e-mail para [email protected]
Se você encontrou um erro nesta biblioteca, registre um problema em https://github.com/google/draco/issues
Patches são incentivados e podem ser enviados bifurcando este projeto e enviando uma solicitação pull por meio do GitHub. Consulte CONTRIBUINDO para obter mais detalhes.
Licenciado sob a Licença Apache, Versão 2.0 (a "Licença"); você não pode usar este arquivo exceto em conformidade com a Licença. Você pode obter uma cópia da Licença em
http://www.apache.org/licenses/LICENSE-2.0
A menos que exigido pela lei aplicável ou acordado por escrito, o software distribuído sob a Licença é distribuído "COMO ESTÁ", SEM GARANTIAS OU CONDIÇÕES DE QUALQUER TIPO, expressas ou implícitas. Consulte a Licença para saber o idioma específico que rege as permissões e limitações da Licença.
Modelo de coelho do departamento gráfico de Stanford https://graphics.stanford.edu/data/3Dscanrep/