11 poin oleh GN⁺ 2025-11-24 | Belum ada komentar. | Bagikan ke WhatsApp
  • Ringkasan pengalaman mengimplementasikan sendiri engine game kecil yang mencakup dua game demo sambil mempelajari Vulkan selama 3 bulan
  • Berdasarkan pengalaman OpenGL yang sudah ada, kompleksitas Vulkan diatasi secara bertahap, sambil mengimplementasikan fitur inti seperti pemuatan glTF, skinning, dan shadow mapping
  • Engine tersebut adalah EDBR (Elias Daler’s Bikeshed Engine), terdiri dari sekitar 19 ribu baris kode dan memanfaatkan teknik grafis modern seperti bindless descriptor, PVP, dan BDA
  • Tulisan ini membagikan detail implementasi praktis seperti library penting vk-bootstrap, VMA, volk serta pola pipeline, otomatisasi build shader, dan manajemen sinkronisasi
  • Dengan beralih ke Vulkan, penulis memperoleh penghapusan global state, kontrol eksplisit, lingkungan debugging yang lebih baik, dan konsistensi antar-GPU, serta berencana menambahkan render graph, font SDF, dan efek volumetrik

Gambaran umum pembelajaran Vulkan dan pengembangan engine

  • Penulis mulai mempelajari pemrograman grafis secara otodidak dan pernah membuat engine 3D dengan OpenGL sekitar satu setengah tahun lalu
  • Engine berbasis Vulkan ini cocok untuk game kecil berbasis level, dengan fokus utama pada pembelajaran dan eksperimen, bukan efisiensi
  • Pada tahap awal, penulis membuat game 3D sederhana terlebih dahulu lalu memisahkan bagian-bagian yang bisa digunakan ulang menjadi engine
  • Salah satu alasan proyek ini bisa selesai dalam 3 bulan adalah karena cakupannya dibatasi sebagai engine untuk tujuan tertentu, bukan engine serbaguna

Jalur belajar pemrograman grafis

  • Untuk pemula, disarankan memulai dari OpenGL dengan mempelajari hal-hal seperti menampilkan model bertekstur, pencahayaan Blinn-Phong, dan shadow mapping
  • Materi yang direkomendasikan antara lain learnopengl.com, Anton’s OpenGL 4 Tutorials, dan kuliah Thorsten Thormählen
  • Penulis juga menekankan pentingnya memahami aljabar linear (vektor, matriks, kuaternion) bersama materi praktik OpenGL 4.6 terbaru

Saran untuk menghindari bike-shedding

  • Hindari desain dan abstraksi yang berlebihan yang tidak perlu, dan pertahankan prinsip “implementasikan hanya yang dibutuhkan sekarang”
  • Pendekatan “yang penting berfungsi dulu, perbaiki nanti” direkomendasikan
  • Menyelesaikan game kecil lebih efisien daripada langsung mencoba membuat engine serbaguna
  • Jangan meniru begitu saja kode atau struktur rumit milik orang lain; mulailah dari struktur yang sederhana

Alasan memilih Vulkan

  • Untuk game AAA biasanya digunakan DirectX, untuk macOS/iOS digunakan Metal, dan untuk web umumnya WebGPU/WebGL
  • Penulis memilih Vulkan karena menyukai open source dan teknologi standar, serta karena sesuai untuk tujuan membuat game 3D desktop berskala kecil
  • OpenGL tidak lagi berkembang dan telah dihentikan di macOS
  • WebGPU memang lebih ringkas, tetapi masih memiliki keterbatasan seperti stabilitas yang kurang, batasan fitur, serta tidak mendukung bindless dan push constant

Proses belajar Vulkan

  • Pada awalnya terasa sesulit “menulis driver grafis sendiri”,
    tetapi kemunculan dynamic rendering, vk-bootstrap, dan vkguide membuatnya lebih mudah diakses
  • Materi belajar utama:
    • vkguide.dev (berfokus pada praktik dari dasar)
    • TU Wien Vulkan Lecture Series
    • 3D Graphics Rendering Cookbook, Mastering Graphics Programming with Vulkan
  • Dalam bulan pertama, penulis sudah menyelesaikan implementasi pemuatan glTF, compute skinning, frustum culling, dan shadow mapping

Struktur engine EDBR dan pemrosesan frame

  • Kode engine sekitar 19.000 baris, game 3D sekitar 4.600 baris, dan game platformer 2D sekitar 1.200 baris
  • Tahap rendering utama:
    • Compute skinningCascaded Shadow Mapping (4096×4096)geometry shading berbasis PBR
    • Depth ResolvePost FX (kabut berbasis kedalaman)rendering UI
  • Semua sistem grafis ditulis ulang khusus untuk Vulkan, tanpa mencampur dengan kode OpenGL lama

Tips praktis pengembangan Vulkan

Library yang direkomendasikan

  • vk-bootstrap: menyederhanakan inisialisasi dan konfigurasi swapchain
  • Vulkan Memory Allocator (VMA): mengotomatiskan manajemen memori
  • volk: menyederhanakan pemuatan fungsi ekstensi

Abstraksi GfxDevice

  • Mengelola VkDevice, VkQueue, VmaAllocator, dan lain-lain dalam satu objek
  • Bertanggung jawab atas awal/akhir frame, pembuatan image dan buffer, serta manajemen bindless descriptor

Manajemen shader

  • Menggunakan GLSL, dikompilasi lebih dulu ke SPIR-V dengan glslc pada saat build
  • Menggunakan DEPFILE di CMake agar shader dibangun ulang otomatis saat berubah

Pola pipeline

  • Tiap tahap rendering dipisahkan menjadi pipeline per kelas (init, cleanup, draw)
  • Dengan VK_KHR_dynamic_rendering, render pass dan subpass bisa dihilangkan sehingga struktur tetap sederhana

Programmable Vertex Pulling + Buffer Device Address

  • Semua mesh diproses dengan satu struktur Vertex
  • Shader mengakses data langsung melalui buffer_reference, sehingga VAO tidak diperlukan

Bindless Descriptor

  • Menggunakan array tekstur global (textures[], samplers[]) untuk sampling berdasarkan ID tekstur
  • ID tekstur disimpan di struktur material dan dikirim lewat push constant

Upload data dinamis

  • Data dikirim dengan mengganti buffer GPU per frame atau memakai buffer staging CPU
  • Struktur frame in-flight dikelola dengan kelas NBuffer

Pembersihan resource dan sinkronisasi

  • Menggunakan fungsi cleanup eksplisit, dikelola manual alih-alih mengandalkan pembersihan otomatis oleh destructor
  • Sinkronisasi memori antar-pass dilakukan dengan vkCmdPipelineBarrier2
  • Render Graph direncanakan untuk diimplementasikan di masa depan

Contoh detail implementasi

Rendering sprite

  • Dengan bindless texture dan instancing, ribuan sprite dirender sekaligus
  • Struktur SpriteDrawCommand diunggah ke buffer GPU, lalu dipanggil vkCmdDraw(6, N)
  • 10 ribu sprite dirender dalam 315μs

Compute skinning

  • Compute shader melakukan deformasi vertex berdasarkan matriks tulang dan bobot
  • Buffer output dibuat terpisah untuk tiap instance, lalu diproses sama pada tahap rendering berikutnya

Pemisahan game/rendering

  • Logika game menggunakan entt ECS, sementara renderer hanya memproses vektor DrawCommand
  • Perintah render dibuat lewat pemanggilan drawMesh dan drawSkinnedMesh

Pemuatan scene dan prefab

  • Level disusun di Blender lalu diekspor ke glTF, dan prefab di-spawn otomatis berdasarkan aturan nama node
  • Prefab didefinisikan dalam JSON dan mereferensikan glTF eksternal

MSAA, UI, ImGui

  • Menerapkan MSAA x8 berbasis forward rendering
  • Mengimplementasikan sistem layout otomatis yang terinspirasi dari Roblox UI API
  • Menulis backend Vulkan sendiri untuk mengatasi masalah sRGB pada Dear ImGui

Komponen lainnya

  • Menggunakan Jolt Physics untuk fisika, entt untuk ECS, OpenAL-soft untuk audio, dan Tracy sebagai profiler

Manfaat beralih ke Vulkan

  • Penghapusan global state menghasilkan struktur kode yang lebih eksplisit dan modular
  • Validation layer dan debugging dengan RenderDoc memudahkan pelacakan masalah
  • Konsistensi yang lebih baik antar-GPU dan OS, dengan perilaku yang lebih dapat diprediksi dibanding OpenGL
  • Memberi ruang ekspansi ke bahasa shading baru (slang, shady) dan lainnya
  • Abstraksi yang lebih sedikit dan kontrol pipeline yang lebih jelas meningkatkan kemudahan pemeliharaan

Rencana ke depan

  • Direncanakan penambahan font SDF, pemuatan gambar paralel dan pembuatan mipmap, Bloom, kabut volumetrik, animation blending, render graph, dan AO
  • Mempelajari Vulkan memang sulit, tetapi sangat membantu dalam memahami API grafis modern dan meningkatkan kemampuan merancang engine

Belum ada komentar.

Belum ada komentar.