1. نظرة عامة
تُعد الرسومات الثلاثية الأبعاد جزءًا أساسيًا من العديد من التطبيقات، بما في ذلك الألعاب والتصميم وعرض البيانات. مع استمرار تحسّن معالجات الرسومات وأدوات الإنشاء، ستصبح التصاميم الثلاثية الأبعاد الأكبر حجمًا والأكثر تعقيدًا شائعة وستساعد في تعزيز التطبيقات الجديدة في الواقع الافتراضي (VR) والواقع المعزّز (AR) الغامرَين. ونتيجةً لهذا التعقيد المتزايد في النماذج، يجب أن تتوافق متطلبات التخزين وعرض النطاق الترددي مع الانتشار الكبير لبيانات الثلاثية الأبعاد.
باستخدام Draco، يمكن أن يكون حجم التطبيقات التي تستخدم الرسومات الثلاثية الأبعاد أصغر بكثير بدون التأثير في دقة العرض. بالنسبة إلى المستخدمين، يعني ذلك أنّه يمكن الآن تنزيل التطبيقات بشكل أسرع، ويمكن تحميل الرسومات الثلاثية الأبعاد في المتصفّح بشكل أسرع، ويمكن الآن نقل مَشاهد الواقع الافتراضي والواقع المعزّز باستخدام جزء بسيط من معدل نقل البيانات، وعرضها بسرعة وبشكل رائع.
ما هي عملة Draco؟
Draco هي مكتبة لضغط الشبكات الهندسية الثلاثية الأبعاد والسُحب النقطية وفك ضغطها. وهي تهدف إلى تحسين تخزين الرسومات الثلاثية الأبعاد ونقلها.
تم تصميم Draco وإنشاؤه لتحقيق كفاءة وسرعة في الضغط. يتيح الرمز البرمجي ضغط النقاط ومعلومات الاتصال وإحداثيات الملمس ومعلومات الألوان والمتجهات العمودية وأي سمات عامة أخرى مرتبطة بالأشكال الهندسية. يتم إصدار Draco كرمز مصدر C++ يمكن استخدامه لضغط الرسومات الثلاثية الأبعاد، بالإضافة إلى برامج فك ترميز C++ وJavascript للبيانات المرمّزة.
ما ستتعلمه
- كيفية استخدام Draco لضغط نموذج ثلاثي الأبعاد
- كيفية استخدام نماذج ضغط مختلفة وتأثيرها في جودة النموذج وحجمه
- كيفية عرض تصميم ثلاثي الأبعاد على الويب
المتطلبات
- إصدار حديث من Chrome
- الرمز النموذجي
- محرِّر نصوص
- Python
- cmake
2. الإعداد
استنسِخ مستودع Github باستخدام سطر الأوامر التالي:
git clone https://github.com/google/draco
انتقِل إلى الدليل الجذر لـ Draco.
cd draco
3- إنشاء برنامج الترميز
للبدء في ترميز وفك ترميز Draco، لنبدأ أولاً بإنشاء التطبيقات.
إنشاء برنامج ترميز
- شغِّل cmake من دليل تريد إنشاء ملفات الإصدار فيه، ومرِّر إليه مسار مستودع Draco.
mkdir build
cd build
cmake ../
make
4. ترميز أول مادة عرض ثلاثية الأبعاد
سيقرأ draco_encoder ملفات OBJ أو PLY كمدخلات، ويُخرج ملفات مشفّرة بتنسيق Draco. لقد أدرجنا شبكة Bunny من جامعة ستانفورد للاختبار. يبدو سطر الأوامر الأساسي على النحو التالي:
./draco_encoder -i ../testdata/bun_zipper.ply -o bunny.drc
يمكنك الآن الاطّلاع على حجم ملف الإخراج ومقارنته بملف .ply الأصلي. يجب أن يكون حجم الملف المضغوط أصغر بكثير من حجم الملف الأصلي.
ملاحظة: يمكن أن يختلف حجم الملف المضغوط استنادًا إلى خيارات الضغط.
5- فك ترميز ملف Draco في المتصفّح
في هذه المرحلة، سنبدأ بصفحة ويب أساسية لفك ترميز ملفات Draco. سنبدأ بنسخ أقسام الرمز التالية ولصقها في أداة تعديل النصوص.
- ابدأ بملف HTML أساسي.
<!DOCTYPE html>
<html>
<head>
<title>Codelab - Draco Decoder</title>
- سيحمّل مقتطف الرمز البرمجي التالي برنامج فك ترميز 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>
- بعد ذلك، أضِف هذه الدالة التي ستنشئ وحدة فك ترميز 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);
}
- أضِف الدالة لفك ترميز شبكة مرمّزة باستخدام 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);
}
- بعد إعداد دالة فك ترميز 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);
}
- استدعِ الدالة createDracoDecoderModule لإنشاء وحدة فك ترميز Draco، والتي ستستدعي الدالة downloadEncodedMesh لتنزيل ملف Draco المرمّز، والذي سيستدعي الدالة decodeMesh لفك ترميز شبكة Draco المرمّزة.
// Create the Draco decoder module.
createDracoDecoderModule();
</script>
</head>
<body>
</body>
</html>
- احفظ هذا الملف باسم "DracoDecode.html".
- ابدأ تشغيل خادم الويب Python. في الوحدة الطرفية، اكتب:
python -m SimpleHTTPServer
- افتح localhost:8000/DracoDecode.html في Chrome. من المفترض أن يؤدي ذلك إلى عرض مربّع رسالة تنبيه يتضمّن عدد النقاط (Num points = 34834) التي تم فك ترميزها من النموذج.
6. عرض ملف Draco باستخدام three.js
بعد أن تعرّفنا على كيفية فك ترميز ملف Draco باستخدام WASM، سنستخدم أداة عرض ثلاثية الأبعاد شائعة على الويب، وهي three.js. كما في المثال السابق، سنبدأ بنسخ أقسام الرمز التالية ولصقها في أداة تعديل النصوص.
- البدء بملف HTML أساسي
<!DOCTYPE html>
<html>
<head>
<title>Codelab - Draco three.js Render</title>
- أضِف رمزًا لتحميل three.js وDraco three.js loader.
<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>
- اضبط مسار برنامج فك ترميز 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/');
- أضِف رمز العرض ثلاثي الأبعاد باستخدام 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 );
}
- إضافة رمز تحميل وفك ترميز 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 );
} );
}
- أضِف رمزًا لتحميل الملف.
window.onload = function() {
initThreejs();
animate();
loadDracoMesh('bunny.drc');
}
</script>
</head>
<body>
<div id="container"></div>
</body>
</html>
- احفظ هذا الملف باسم "DracoRender.html".
- إذا لزم الأمر، أعِد تشغيل خادم الويب.
python -m SimpleHTTPServer
- افتح localhost:8000/DracoRender.html في Chrome. من المفترض أن يظهر لك الآن ملف Draco معروضًا في المتصفّح.
7. تجربة مَعلمات ترميز مختلفة
يتيح برنامج الترميز Draco استخدام العديد من المَعلمات المختلفة التي تؤثّر في حجم الملف المضغوط وجودة الرمز المرئية. جرِّب تنفيذ الأوامر القليلة التالية في سطر الأوامر واطّلِع على النتائج.
- يُكمِّم الأمر التالي مواضع النموذج باستخدام 12 بت (القيمة التلقائية هي 11 بت).
./draco_encoder -i ../testdata/bun_zipper.ply -o out12.drc -qp 12
- لاحظ حجم ملف out12.drc مقارنةً بملف bunny.drc في القسم السابق. يمكن أن يؤدي استخدام المزيد من وحدات بت التكميم إلى زيادة حجم الملف المضغوط.
3.يحدد الأمر التالي مواضع النموذج باستخدام 6 بت.
./draco_encoder -i ../testdata/bun_zipper.ply -o out6.drc -qp 6
- لاحظ حجم ملف out6.drc مقارنةً بملف bunny.drc في القسم السابق. يمكن أن يؤدي استخدام عدد أقل من وحدات بت التكميم إلى تقليل حجم الملف المضغوط.
- تؤثّر المَعلمات التالية في مستويات ضغط النموذج. باستخدام العلامة 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 واستكشفت بنجاح العديد من الميزات الرئيسية لـ Draco.
نأمل أن يكون من الواضح لك كيف يمكن أن يساعد Draco في تصغير حجم مواد العرض الثلاثية الأبعاد وجعلها أكثر فعالية في نقلها عبر الويب. يمكنك الاطّلاع على مزيد من المعلومات عن Draco والحصول على أحدث مكتبة من github.