Draco Geometri Sıkıştırma ile 3D verileri optimize etme

1. Genel Bakış

3D grafikler, oyun, tasarım ve veri görselleştirme dahil birçok uygulamanın temel bir parçasıdır. Grafik işlemciler ve oluşturma araçları gelişmeye devam ettikçe daha büyük ve daha karmaşık 3D modeller yaygınlaşacak ve sürükleyici sanal gerçeklik (VR) ve artırılmış gerçeklik (AR) ile yeni uygulamaların desteklenmesine yardımcı olacak. Modellerin bu kadar karmaşık olması nedeniyle, depolama alanı ve bant genişliği gereksinimleri 3D verilerin artan rağbetine ayak uydurmakla yükümlüdür.

Draco sayesinde 3D grafikler kullanan uygulamalar, görsel kaliteden ödün vermeden önemli ölçüde daha küçük boyutlu olabiliyor. Kullanıcılar için bu, uygulamaların artık daha hızlı indirilebileceği, tarayıcıdaki 3D grafiklerin daha hızlı yüklenebileceği ve VR ve AR sahnelerinin artık bant genişliğinin çok küçük bir kısmıyla iletip hızlı bir şekilde oluşturulabileceği ve muhteşem görüneceği anlamına geliyor.

Draco nedir?

Draco, 3D geometrik örgüleri ve nokta bulutlarını sıkıştırmak ve açmak için kullanılan bir kitaplıktır. 3D grafiklerin depolanmasını ve iletimini iyileştirmek amacıyla tasarlanmıştır.

Draco, sıkıştırma verimliliği ve hızı için tasarlanmış ve üretilmiştir. Kod, sıkıştırma noktalarını, bağlantı bilgilerini, doku koordinatlarını, renk bilgilerini, normal değerleri ve geometriyle ilişkili diğer genel özellikleri destekler. Draco, 3D grafikleri ve kodlanmış veriler için C++ ve JavaScript kod çözücüleri sıkıştırmak amacıyla kullanılabilen C++ kaynak kodu olarak yayınlanır.

Öğrenecekleriniz

  • 3D modeli sıkıştırmak için Draco'yu kullanma
  • Farklı sıkıştırma modelleri nasıl kullanılır ve bu modellerin model kalitesi ile boyutunu nasıl etkilediği
  • Web'de 3D modeller nasıl görüntülenir?

Gerekenler

2. Kurulum

Şu komut satırını kullanarak GitHub deposunu klonlayın:

git clone https://github.com/google/draco

Draco kök dizinine gidin.

cd draco

3. Kodlayıcıyı oluşturma

Draco kodlama ve kod çözme işlemine başlamak için önce uygulamaları derleyerek başlayalım.

Derleme Kodlayıcı

  • Derleme dosyaları oluşturmak istediğiniz dizinden cmake'i çalıştırın ve Draco deponuza giden yolu iletin.
mkdir build

cd build

cmake ../

make

4. İlk 3D öğenizi kodlama

draco_encoder, OBJ veya PLY dosyalarını giriş olarak okur ve Draco olarak kodlanmış dosyalar çıkarır. Test için Stanford'ın Bunny örgüsünü ekledik. Temel komut satırı şöyle görünür:

./draco_encoder -i ../testdata/bun_zipper.ply -o bunny.drc

Şimdi çıkış dosyasının boyutuna bakabilir ve orijinal .ply dosyasıyla karşılaştırabilirsiniz. Sıkıştırılmış dosya, orijinal dosya boyutundan çok daha küçük olmalıdır.

Not: Sıkıştırılmış boyut, sıkıştırma seçeneklerine göre değişiklik gösterebilir.

5. Tarayıcıda bir Draco dosyasının kodunu çözme

Bu noktada, Draco dosyalarının kodunu çözmek için temel bir web sayfasıyla başlayacağız. Aşağıdaki kod bölümlerini kopyalayıp metin düzenleyiciye yapıştırarak başlayacağız.

  1. Temel HTML dosyasıyla başlayın.
<!DOCTYPE html>
<html>
<head>
  <title>Codelab - Draco Decoder</title>
  1. Aşağıdaki kod snippet'i Draco WASM kod çözücüyü yükler.
  <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>
  1. Ardından, Draco kod çözücü modülü oluşturacak bu işlevi ekleyin. Kod çözücü modülünün oluşturulması eşzamansız olduğundan, modülü kullanabilmek için geri çağırmanın çağrılmasını beklemeniz gerekir.
  <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);
    }
  1. Draco kodlamalı bir örgünün kodunu çözmek için işlevi ekleyin.
    // 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);
    }
  1. Artık Draco kod çözme işlevini etkinleştirdiğimize göre, Draco kodlamalı bir örgü indirmek için bir işlev ekleyebilirsiniz. "downloadEncodedMesh" işlevi yüklenecek Draco dosyasına ait bir parametreyi kabul eder. Bu örnekte, "bunny.drc" olacaktır. seçim yapabilirsiniz.
    // 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);
    }
  1. "createDracoDecoderModule" komutunu çağırın işlevini kullanarak "downloadEncodedMesh" çağıran Draco kod çözücü modülünü oluşturabilir. işlevini kullanarak "decodeMesh"i çağıracak ve kodlanmış Draco dosyasını işlevini kullanarak kodlanmış Draco ağının kodunu çözer.
    // Create the Draco decoder module.
    createDracoDecoderModule();
  </script>
</head>
<body>
</body>
</html>
  1. Bu dosyayı "DracoDecode.html" olarak kaydedin
  2. Python web sunucusunu başlatın. Terminal türünde:
python -m SimpleHTTPServer

  1. Chrome'da localhost:8000/DracoDecode.html adresini açın. Bu, modelde kodu çözülmüş noktaların (Puan sayısı = 34834) yer aldığı bir uyarı mesajı kutusu görüntülemelidir.

6. Üç.js ile Draco dosyası oluştur

Artık WASM kullanarak bir Draco dosyasının kodunu nasıl çözeceğimizi öğrendiğimize göre, popüler bir web 3D görüntüleyici olan üç.js'yi kullanacağız. Önceki örnekte olduğu gibi aşağıdaki kod bölümlerini kopyalayıp metin düzenleyiciye yapıştırarak başlayacağız.

  1. Temel HTML dosyasıyla başlayın
<!DOCTYPE html>
<html>
<head>
  <title>Codelab - Draco three.js Render</title>
  1. Two.js ve Dracothree.js yükleyicisini yüklemek için kod ekleyin.
  <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>
  1. Draco kod çözücü yolunu ayarlayın.
  <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/');
  1. Üç.js oluşturma kodu ekleyin.
    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 );
    }
  1. Draco yükleme ve kodu çözme işlemlerini ekleyin.
    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 );
      } );
    }

  1. Dosyayı yüklemek için kod ekleyin.
    window.onload = function() {
      initThreejs();
      animate();
      loadDracoMesh('bunny.drc');
    }
  </script>
</head>
<body>
  <div id="container"></div>
</body>
</html>
  1. Bu dosyayı "DracoRender.html" olarak kaydedin
  2. Gerekirse web sunucusunu yeniden başlatın.
python -m SimpleHTTPServer

  1. Chrome'da localhost:8000/DracoRender.html dosyasını açın. Draco dosyanızın tarayıcıda oluşturulduğunu göreceksiniz.

7. Farklı kodlama parametrelerini deneyin

Draco kodlayıcı, sıkıştırılmış dosyanın boyutunu ve kodun görsel kalitesini etkileyen birçok farklı parametreye olanak tanır. Komut satırında sonraki birkaç komutu çalıştırmayı ve sonuçları görmeyi deneyin.

  1. Aşağıdaki komut, modelin konumlarını 12 (varsayılan değer 11) bit kullanarak ölçer.
./draco_encoder -i ../testdata/bun_zipper.ply -o out12.drc -qp 12

  1. Önceki bölümdeki bunny.drc dosyasına kıyasla out12.drc dosyasının boyutuna dikkat edin. Daha fazla niceleme biti kullanmak, sıkıştırılmış dosyanın boyutunu artırabilir.

3.Aşağıdaki komut, 6 bit kullanarak modelin konumlarını ölçer.

./draco_encoder -i ../testdata/bun_zipper.ply -o out6.drc -qp 6

  1. Önceki bölümdeki bunny.drc dosyasına kıyasla out6.drc dosyasının boyutuna dikkat edin. Daha az niceleme biti kullanmak, sıkıştırılmış dosyanın boyutunu azaltabilir.
  1. Aşağıdaki parametreler modelin sıkıştırma düzeylerini etkiler. cl işaretini kullanarak sıkıştırmanızı 1'den (en düşük sıkıştırma oranı) 10'a (en yüksek) ayarlayabilirsiniz.
./draco_encoder -i ../testdata/bun_zipper.ply -o outLow.drc -cl 1

./draco_encoder -i ../testdata/bun_zipper.ply -o outHigh.drc -cl 10

Draco kodlayıcıdan alınan çıkışa dikkat edin. En yüksek sıkıştırma seviyelerinde sıkıştırma için gereken süre ile bit cinsinden tasarruf arasında bir denge olduğunu görebilirsiniz. Uygulamanız için doğru parametre, kodlama sırasındaki zamanlama ve boyut gereksinimlerine bağlıdır.

8. Tebrikler

Draco örgü sıkıştırma kodu laboratuvarını tamamladınız ve Draco'nun birçok temel özelliğini başarıyla keşfettiniz.

Umarım Draco'nun 3D öğelerinizi daha küçük ve web üzerinden daha verimli bir şekilde aktarmanıza nasıl yardımcı olabileceğini size açıklamıştır. github'dan Draco hakkında daha fazla bilgi edinebilir ve en son kütüphaneyi edinebilirsiniz.