การเพิ่มประสิทธิภาพข้อมูล 3 มิติด้วย Draco Geometry Compression

การเพิ่มประสิทธิภาพข้อมูล 3 มิติด้วย Draco Geometry Compression

เกี่ยวกับ Codelab นี้

subjectอัปเดตล่าสุดเมื่อ มี.ค. 11, 2024
account_circleเขียนโดย Googler

1 ภาพรวม

กราฟิก 3 มิติเป็นส่วนพื้นฐานของแอปพลิเคชันมากมาย รวมถึงเกม การออกแบบ และการแสดงข้อมูลเป็นภาพ ในขณะที่ตัวประมวลผลกราฟิกและเครื่องมือในการสร้างสรรค์มีการปรับปรุงอย่างต่อเนื่อง โมเดล 3 มิติที่มีขนาดใหญ่และซับซ้อนจะกลายเป็นเรื่องที่พบได้ทั่วไป และช่วยขับเคลื่อนแอปพลิเคชันใหม่ๆ ในระบบ Virtual Reality (VR) และ Augmented Reality (AR) และเนื่องจากความซับซ้อนของโมเดลที่เพิ่มขึ้นนี้ ข้อกำหนดด้านพื้นที่เก็บข้อมูลและแบนด์วิดท์จึงจำเป็นต้องตามทันการระเบิดของข้อมูล 3 มิติ

Draco ทำให้แอปพลิเคชันที่ใช้กราฟิก 3 มิติมีขนาดเล็กลงอย่างมากโดยไม่กระทบต่อรายละเอียดของภาพ สำหรับผู้ใช้ นี่หมายความว่าตอนนี้แอปจะดาวน์โหลดได้เร็วขึ้น กราฟิก 3 มิติในเบราว์เซอร์จะโหลดได้เร็วขึ้น อีกทั้งสามารถรับส่งฉาก VR และ AR ได้ด้วยแบนด์วิดท์เพียงเศษเสี้ยว แสดงผลอย่างรวดเร็ว แล้วดูน่าประทับใจ

ดราโก้คืออะไร

ดราโกคือคลังสำหรับการบีบอัดและคลายการบีบอัดเรขาคณิต 3 มิติเมชและจุดเมฆแบบจุด แต่มีวัตถุประสงค์เพื่อปรับปรุงการจัดเก็บและการส่งกราฟิก 3 มิติ

Draco ออกแบบและผลิตมาให้บีบอัดได้อย่างมีประสิทธิภาพและรวดเร็วยิ่งขึ้น โค้ดสนับสนุนจุดบีบอัด ข้อมูลการเชื่อมต่อ พิกัดของพื้นผิว ข้อมูลสี เส้นปกติ และแอตทริบิวต์ทั่วไปอื่นๆ ที่เกี่ยวข้องกับเรขาคณิต Draco เปิดตัวเป็นซอร์สโค้ด C++ ที่สามารถใช้เพื่อบีบอัดกราฟิก 3 มิติ รวมทั้งตัวถอดรหัส C++ และ JavaScript สำหรับข้อมูลที่เข้ารหัส

สิ่งที่คุณจะได้เรียนรู้

  • วิธีใช้ Draco บีบอัดโมเดล 3 มิติ
  • วิธีใช้รูปแบบการบีบอัดแบบต่างๆ และผลกระทบต่อคุณภาพและขนาดของรูปแบบ
  • วิธีดูโมเดล 3 มิติบนเว็บ

สิ่งที่ต้องมี

2 การตั้งค่า

โคลนที่เก็บ GitHub โดยใช้บรรทัดคำสั่งนี้

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

ไปที่ไดเรกทอรีราก Draco

cd draco

3 สร้างโปรแกรมเปลี่ยนไฟล์

เรามาเริ่มด้วยการสร้างแอปกัน ก่อนที่จะเข้ารหัสและถอดรหัสของ Draco

สร้างโปรแกรมเปลี่ยนไฟล์

  • เรียกใช้ cmake จากไดเรกทอรีที่คุณต้องการสร้างไฟล์บิลด์ แล้วส่งเส้นทางไปยังที่เก็บ Draco
mkdir build

cd build

cmake
../

make

4 เข้ารหัสเนื้อหา 3 มิติรายการแรกของคุณ

draco_encoder จะอ่านไฟล์ OBJ หรือ PLY เป็นอินพุตและเอาต์พุตไฟล์ที่เข้ารหัส Draco เราได้รวมตาข่ายกระต่ายของ Stanford's Bunny สำหรับการทดสอบ บรรทัดคำสั่งพื้นฐานจะมีลักษณะดังนี้

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

ตอนนี้คุณจะดูขนาดของไฟล์เอาต์พุตและเปรียบเทียบกับไฟล์ .ply ต้นฉบับได้ ไฟล์ที่บีบอัดควรมีขนาดเล็กกว่าขนาดไฟล์ดั้งเดิมมาก

หมายเหตุ: ขนาดของที่บีบอัดอาจแตกต่างกันไปตามตัวเลือกการบีบอัด

5 ถอดรหัสไฟล์ Draco ในเบราว์เซอร์

ถึงตอนนี้เราจะเริ่มด้วยหน้าเว็บพื้นฐานสำหรับถอดรหัสไฟล์ Draco เราจะเริ่มต้นด้วยการคัดลอกและวางส่วนของโค้ดต่อไปนี้ลงในโปรแกรมแก้ไขข้อความ

  1. เริ่มต้นด้วยไฟล์ HTML พื้นฐาน
<!DOCTYPE html>
<html>
<head>
 
<title>Codelab - Draco Decoder</title>
  1. ข้อมูลโค้ดต่อไปนี้จะโหลดตัวถอดรหัส Draco WASM
  <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. จากนั้นเพิ่มฟังก์ชันนี้ ซึ่งจะสร้างโมดูลตัวถอดรหัส Draco การสร้างโมดูลตัวถอดรหัสเป็นแบบไม่พร้อมกัน คุณจึงต้องรอจนกว่าจะมีการเรียกใช้ Callback ก่อนที่จะใช้โมดูลได้
  <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. เพิ่มฟังก์ชันเพื่อถอดรหัส Mesh ที่เข้ารหัสด้วยดราโก
    // 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. ตอนนี้เรามีฟังก์ชันถอดรหัสของ Draco แล้ว ให้เพิ่มฟังก์ชันเพื่อดาวน์โหลด Mesh ที่เข้ารหัสแบบดราโก ฟังก์ชัน "downloadEncodingMesh" ยอมรับพารามิเตอร์ลงในไฟล์ 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);
   
}
  1. เรียกใช้ "createDracoDecoderModule" เพื่อสร้างโมดูลตัวถอดรหัส Draco ซึ่งจะเรียก "downloadEncodingMesh" เพื่อดาวน์โหลดไฟล์ Draco ที่เข้ารหัส ซึ่งจะเรียกฟังก์ชัน "decodeMesh" เพื่อถอดรหัสตาข่ายของดราโกที่เข้ารหัส
    // Create the Draco decoder module.
    createDracoDecoderModule
();
 
</script>
</
head>
<body>
</body>
</
html>
  1. บันทึกไฟล์นี้เป็น "DracoDecode.html"
  2. เริ่มต้นเว็บเซิร์ฟเวอร์ Python ในประเภทเทอร์มินัล ให้ทำดังนี้
python -m SimpleHTTPServer

  1. เปิด localhost:8000/DracoDecode.html ใน Chrome ระบบจะแสดงกล่องข้อความแจ้งเตือนพร้อมจำนวนจุด (Num points = 34834) ที่มีการถอดรหัสจากโมเดล

6 แสดงผลไฟล์ Draco ด้วย third.js

เมื่อเราเข้าใจวิธีถอดรหัสไฟล์ Draco โดยใช้ WASM แล้ว เราจะใช้มุมมอง 3 มิติแบบเว็บที่ได้รับความนิยมอย่าง 3.js เช่นเดียวกับตัวอย่างก่อนหน้านี้ เราจะเริ่มโดยการคัดลอกและวางส่วนของโค้ดต่อไปนี้ลงในโปรแกรมแก้ไขข้อความ

  1. เริ่มต้นด้วยไฟล์ HTML พื้นฐาน
<!DOCTYPE html>
<html>
<head>
 
<title>Codelab - Draco three.js Render</title>
  1. เพิ่มโค้ดเพื่อโหลดตัวโหลด third.js และ Draco third.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>
  1. ตั้งค่าเส้นทางตัวถอดรหัส 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/');
  1. เพิ่มโค้ดการแสดงผล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 );
   
}
  1. เพิ่มการโหลดและถอดรหัสของ 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 );
     
} );
   
}

  1. เพิ่มโค้ดเพื่อโหลดไฟล์
    window.onload = function() {
      initThreejs
();
      animate
();
      loadDracoMesh
('bunny.drc');
   
}
 
</script>
</
head>
<body>
 
<div id="container"></div>
</body>
</
html>
  1. บันทึกไฟล์นี้เป็น "DracoRender.html"
  2. หากจำเป็น ให้รีสตาร์ทเว็บเซิร์ฟเวอร์
python -m SimpleHTTPServer

  1. เปิด localhost:8000/DracoRender.html ใน Chrome ตอนนี้คุณควรจะเห็นไฟล์ Draco แสดงผลในเบราว์เซอร์

7 ลองใช้พารามิเตอร์การเข้ารหัสอื่นๆ

โปรแกรมเปลี่ยนไฟล์ของ Draco รองรับพารามิเตอร์ต่างๆ จำนวนมากที่ส่งผลต่อขนาดไฟล์ที่บีบอัดและคุณภาพของภาพของโค้ด ลองเรียกใช้คำสั่ง 2-3 คำสั่งถัดไปในบรรทัดคำสั่งและดูผลลัพธ์

  1. คำสั่งต่อไปนี้จะวัดปริมาณตำแหน่งของโมเดลโดยใช้ 12 (ค่าเริ่มต้นคือ 11) บิต
./draco_encoder -i ../testdata/bun_zipper.ply -o out12.drc -qp 12

  1. โปรดสังเกตขนาดของ out12.drc เมื่อเทียบกับไฟล์ bunny.drc ในหัวข้อก่อนหน้า การใช้บิตการวัดขนาดที่มากขึ้นจะทำให้ไฟล์ที่บีบอัดมีขนาดใหญ่ขึ้น

3. คำสั่งต่อไปนี้ใช้วัดตำแหน่งของโมเดลโดยใช้ 6 บิต

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

  1. โปรดสังเกตขนาดของ out6.drc เมื่อเทียบกับไฟล์ bunny.drc ในหัวข้อก่อนหน้า การใช้บิตสัดส่วนที่น้อยลงจะช่วยลดขนาดไฟล์ที่บีบอัดได้
  1. พารามิเตอร์ต่อไปนี้ส่งผลต่อระดับการบีบอัดของโมเดล เมื่อใช้แฟล็ก 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

บันทึกเอาต์พุตจากโปรแกรมเปลี่ยนไฟล์ Draco คุณจะเห็นค่าเผื่อเวลาที่ต้องบีบอัดที่ระดับการบีบอัดสูงสุดเมื่อเทียบกับเวลาที่ประหยัดได้เป็นบิต พารามิเตอร์ที่ถูกต้องสำหรับแอปพลิเคชันจะขึ้นอยู่กับข้อกำหนดด้านเวลาและขนาด ณ เวลาเข้ารหัส

8 ขอแสดงความยินดี

คุณเสร็จสิ้นห้องทดลองโค้ดการบีบอัด Draco Mesh แล้วและได้สำรวจฟีเจอร์สำคัญๆ มากมายของ Draco ด้วย

เราหวังว่าคุณจะเข้าใจชัดเจนว่า Draco สามารถทำให้เนื้อหา 3 มิติของคุณเล็กลงและส่งผ่านอินเทอร์เน็ตได้อย่างมีประสิทธิภาพยิ่งขึ้นได้อย่างไร ดูข้อมูลเพิ่มเติมเกี่ยวกับ Draco และรับไลบรารีล่าสุดจาก github