- 3 महीनों तक Vulkan सीखते हुए दो डेमो गेम्स सहित एक छोटा गेम इंजन खुद इम्प्लीमेंट करने के अनुभव का सार
- पहले के OpenGL अनुभव के आधार पर Vulkan की जटिलता को चरणबद्ध तरीके से पार किया, और glTF लोडिंग, skinning, shadow mapping जैसी मुख्य सुविधाएँ लागू कीं
- इंजन EDBR (Elias Daler’s Bikeshed Engine) है, जो लगभग 19,000 लाइनों के कोड से बना है और bindless descriptor, PVP, BDA जैसी आधुनिक graphics तकनीकों का उपयोग करता है
- लेख में vk-bootstrap, VMA, volk जैसी ज़रूरी लाइब्रेरियों के साथ pipeline pattern, shader build automation, synchronization management जैसे व्यावहारिक implementation विवरण साझा किए गए हैं
- Vulkan पर जाने से global state हटाना, explicit control, बेहतर debugging environment, और GPU के बीच consistency मिली, और आगे render graph, SDF fonts, volumetric effects जोड़ने की योजना है
Vulkan सीखने और इंजन डेवलपमेंट का अवलोकन
- लेखक ने graphics programming की शुरुआत self-study से की थी और डेढ़ साल पहले OpenGL से 3D इंजन लिखने का अनुभव था
- Vulkan आधारित इंजन छोटे level-based गेम्स के लिए उपयुक्त है, और इसका मुख्य उद्देश्य performance से ज़्यादा सीखना और प्रयोग करना था
- शुरुआत में एक साधारण 3D गेम बनाया गया, फिर reusable हिस्सों को अलग करके उसे इंजन का रूप दिया गया
- इसे 3 महीनों में पूरा कर पाने का कारण यह था कि इसे general-purpose engine नहीं बल्कि specific-purpose engine तक सीमित रखा गया
graphics programming सीखने का रास्ता
- शुरुआती लोगों को OpenGL से शुरू करके texture model display, Blinn-Phong lighting, shadow mapping जैसी चीज़ें सीखने की सलाह दी गई है
- सुझाए गए resources में learnopengl.com, Anton’s OpenGL 4 Tutorials, Thorsten Thormählen lectures शामिल हैं
- आधुनिक OpenGL 4.6 अभ्यास सामग्री के साथ linear algebra (vector, matrix, quaternion) की समझ के महत्व पर ज़ोर दिया गया है
bike-shedding से बचने की सलाह
- अनावश्यक over-engineering और abstraction से बचें, और “अभी जो ज़रूरी है वही इम्प्लीमेंट करो” सिद्धांत बनाए रखें
- “पहले इसे काम करने लायक बनाओ, बाद में सुधारो” वाला approach अपनाने की सलाह दी गई है
- general-purpose engine बनाने की बजाय पहले एक छोटा गेम पूरा करना अधिक प्रभावी है
- दूसरों के जटिल code या architecture की सीधी नकल न करें, बल्कि सरल संरचना से शुरुआत करें
Vulkan चुनने के कारण
- AAA गेम्स में प्रायः DirectX, macOS/iOS में Metal, और web पर WebGPU/WebGL इस्तेमाल होते हैं
- लेखक ने open source और standard technologies की पसंद तथा desktop के छोटे 3D गेम डेवलपमेंट के उद्देश्य के कारण Vulkan चुना
- OpenGL अब आगे विकसित नहीं हो रहा और macOS पर deprecated हो चुका है
- WebGPU अधिक संक्षिप्त है, लेकिन उसमें stability की कमी, feature limitations, और bindless तथा push constants का अभाव जैसी सीमाएँ हैं
Vulkan सीखने की प्रक्रिया
- शुरुआत में यह इतना कठिन लगा मानो “graphics driver खुद लिखना” पड़ रहा हो,
लेकिन dynamic rendering, vk-bootstrap, vkguide जैसी चीज़ों के आने से इसे अपनाना आसान हुआ
- मुख्य learning resources:
- vkguide.dev (बुनियाद से practical learning)
- TU Wien Vulkan Lecture Series
- 3D Graphics Rendering Cookbook, Mastering Graphics Programming with Vulkan
- पहले महीने में glTF loading, compute skinning, frustum culling, और shadow mapping का implementation पूरा कर लिया गया
EDBR इंजन संरचना और frame processing
- इंजन कोड लगभग 19,000 lines, 3D गेम 4,600 lines, और 2D platformer गेम 1,200 lines का है
- मुख्य rendering stages:
- Compute skinning → Cascaded Shadow Mapping (4096×4096) → PBR-आधारित geometry shading
- Depth Resolve → Post FX (depth-based fog) → UI rendering
- सभी graphics systems को सिर्फ Vulkan के लिए दोबारा लिखा गया, और पुराने OpenGL code के साथ नहीं मिलाया गया
Vulkan डेवलपमेंट के व्यावहारिक सुझाव
सुझाई गई लाइब्रेरियाँ
- vk-bootstrap: initialization और swapchain setup को सरल बनाता है
- Vulkan Memory Allocator (VMA): memory management को automate करता है
- volk: extension function loading को सरल बनाता है
GfxDevice abstraction
VkDevice, VkQueue, VmaAllocator आदि को एक object में manage किया जाता है
- frame begin/end, image और buffer creation, तथा bindless descriptor management की ज़िम्मेदारी इसी पर होती है
shader management
- GLSL का उपयोग, और build समय पर
glslc से SPIR-V precompile किया जाता है
- CMake
DEPFILE की मदद से shader बदलने पर automatic rebuild होता है
pipeline pattern
- हर rendering stage को class-आधारित pipeline में अलग किया गया (
init, cleanup, draw)
VK_KHR_dynamic_rendering के उपयोग से render pass और subpass हटाकर संरचना को सरल रखा गया
Programmable Vertex Pulling + Buffer Device Address
- सभी meshes को एक ही Vertex struct से संभाला जाता है
- shader में buffer_reference से सीधे access किया जाता है, इसलिए VAO की ज़रूरत नहीं होती
Bindless Descriptor
- global texture arrays (
textures[], samplers[]) का उपयोग करके texture ID आधारित sampling की जाती है
- material struct में texture ID स्टोर की जाती है और push constants के ज़रिए पास की जाती है
dynamic data upload
- हर frame में GPU buffers बदले जाते हैं या CPU staging buffer से data transfer किया जाता है
NBuffer class के जरिए frames-in-flight संरचना को manage किया जाता है
resource cleanup और synchronization
- explicit cleanup functions का उपयोग, destructor-based automatic cleanup की बजाय manual management
vkCmdPipelineBarrier2 से passes के बीच memory synchronization की जाती है
- Render Graph को आगे इम्प्लीमेंट करने की योजना है
implementation के विस्तृत उदाहरण
sprite rendering
- bindless textures और instancing से हज़ारों sprites को एक साथ render किया जाता है
SpriteDrawCommand struct को GPU buffer में upload करके vkCmdDraw(6, N) कॉल किया जाता है
- 10,000 sprites को 315μs में render किया गया
compute skinning
- compute shader में bone matrices और weights आधारित vertex deformation किया जाता है
- हर instance के लिए अलग output buffer बनाया जाता है, फिर rendering stage में उसे समान तरीके से उपयोग किया जाता है
game/renderer separation
- game logic में entt ECS का उपयोग होता है, जबकि renderer केवल DrawCommand vectors को प्रोसेस करता है
drawMesh, drawSkinnedMesh कॉल्स से render commands बनाए जाते हैं
scene loading और prefabs
- Blender से glTF में level तैयार किया जाता है, और node name conventions से prefabs अपने आप spawn होते हैं
- prefabs को JSON में define किया जाता है, और वे external glTF को reference करते हैं
MSAA, UI, ImGui
- forward rendering आधारित MSAA x8 लागू किया गया
- Roblox UI API से प्रेरित automatic layout system बनाया गया
- Dear ImGui sRGB problem हल करने के लिए अपना Vulkan backend लिखा गया
अन्य components
- physics के लिए Jolt Physics, ECS के लिए entt, audio के लिए OpenAL-soft, और profiling के लिए Tracy का उपयोग किया गया
Vulkan पर जाने के फायदे
- global state हटने से अधिक explicit और modular code structure मिला
- validation layers और RenderDoc debugging से समस्याओं को ट्रैक करना आसान हुआ
- GPU और OS के बीच consistency बेहतर हुई, और OpenGL की तुलना में behavior अधिक predictable बना
- नई shading languages (slang, shady) जैसी future extensibility के रास्ते खुले
- कम abstraction और pipeline पर स्पष्ट नियंत्रण से maintainability बेहतर हुई
आगे की योजनाएँ
- SDF fonts, parallel image loading और mipmap generation, Bloom, volumetric fog, animation blending, render graph, AO जोड़ने की योजना है
- Vulkan सीखना कठिन है, लेकिन इससे modern graphics API की समझ और engine design capability को बहुत मज़बूती मिली
1 टिप्पणियां
Hacker News की राय
1 साल पहले लिखी गई मेरी पोस्ट के बाद भी Vulkan के बारे में मेरी राय ज़्यादा नहीं बदली
जो लोग low-level graphics control चाहते हैं, उनके लिए यह दिलचस्प हो सकता है, लेकिन मेरे लिए यह सच में इस्तेमाल करने में बेहद कष्टदायक API था
अपना खुद का game engine बनाने की इच्छा अब भी है, लेकिन Vulkan का शुरुआती setup भी अभी तक डरावना लगता है
मुझे ऐसी चीज़ चाहिए जो 3D के लिए वैसी हो जैसी SDL 2D graphics को संभालता है
SDL में 3D करने के लिए आखिरकार OpenGL तक नीचे जाना पड़ता है, और वह वह स्तर नहीं है जिसकी मुझे तलाश है
शायद WebGPU ऐसा विकल्प हो सकता है जिसके साथ काम करने में मुझे मज़ा आए
मैंने भी उससे एक engine बनाया था, लेकिन आखिर में ज़्यादा control और performance चाहने की वजह से फिर Vulkan-आधारित engine पर लौट गया
फिर भी SDL GPU code से मैंने synchronization patterns सीखे, और उन्होंने मेरे Vulkan engine में बहुत मदद की
wgpu, WebGPU-स्तर की abstraction देने वाला एक बीच का विकल्प हैयह OpenGL से ज़्यादा शक्तिशाली है, लेकिन resource barriers या layout transitions जैसी details को सीधे संभालने की ज़रूरत नहीं पड़ती
runtime कुछ bookkeeping खुद कर देता है, और single queue support जैसी सीमाएँ भी हैं
Vulkan कठिन है, लेकिन बड़े vendors द्वारा समर्थित extensions इस्तेमाल करने पर यह काफ़ी बेहतर हो जाता है
फिर भी drivers जिन settings को नज़रअंदाज़ कर देते हैं, उनके लिए भी details माँगने जैसी अनावश्यक जटिलता अब भी मौजूद है
अभी high-level game engines और low-level Vulkan/Metal के बीच की मध्य-स्तर API लगभग गायब हो चुकी है
अगर शुरुआती लोगों को 3D graphics सीखना है, तो उन्हें ऐसी सरल API चाहिए जिसमें shader या buffer जैसे concepts जाने बिना “triangle draw करो” स्तर से शुरुआत हो सके
Vulkan का बारीक control बहुत कम engine developers को चाहिए होता है, और ज़्यादातर लोगों के लिए OpenGL-स्तर काफ़ी है
3D में 2D की तुलना में कहीं ज़्यादा composable elements होते हैं, इसलिए सिर्फ़ एक simple graphics API से इसे संभालना मुश्किल है
OpenGL भी मूल रूप से वही लक्ष्य लेकर चला था, लेकिन अंत में वह भी जटिल हो गया
‘bike shedding’ का मतलब है तुच्छ चीज़ों पर अटक कर महत्वपूर्ण हिस्सों को नज़रअंदाज़ करना
मूल लेख में जो वर्णन है, वह दरअसल feature creep या over-engineering के ज़्यादा क़रीब है
इसका मतलब है प्रोजेक्ट की प्रगति रोककर सिर्फ़ अपनी निजी रुचि/मज़े पर ध्यान देना
bike shedding को अक्सर “घर पूरा होने से पहले साइकिल शेड का रंग तय करना” कहकर समझाया जाता है
किसी ने कहा था, “Minecraft multiplayer clone से engine development शुरू करना अच्छा विचार नहीं है,”
लेकिन सच यह है कि बहुत से लोग अपने पहले engine project के रूप में Minecraft-जैसा game बनाते हैं
voxel engine की दुनिया में यह लगभग “Hello, world” जैसा है
(2024) में इस पोस्ट को 625 points और 260 comments मिले थे — मूल लिंक
Vulkan मेरे द्वारा सीखी गई चीज़ों में सबसे कठिन तकनीक थी
यह इतना non-intuitive और repetitive है कि programming का मज़ा ही छीन लेता है
अगर आसान शुरुआत चाहिए, तो OpenGL की सलाह दूँगा, ख़ासकर shader आने से पहले वाले versions
लेकिन industry धीरे-धीरे OpenGL को पीछे कर रही है
tutorial follow करते हुए मैं सिर्फ़ code copy कर रहा था, concepts समझ नहीं पा रहा था
इसलिए मैंने WebGPU(Google Dawn) पर switch किया, और वह Vulkan की तुलना में काफ़ी सरल लगा
WebGPU की सीमाओं की वजह से concepts समझने के बाद जब फिर Vulkan सीखा, तो वह कहीं आसान लगा
WebGPU में push constant नहीं है और pipeline explosion की समस्या है, लेकिन Vulkan में synchronization और memory management ज़्यादा कठिन हैं
SDL_GPU भी लगभग उसी स्तर का API है, इसलिए शुरुआत के लिए अच्छा है
Vulkan एक ज़रूरत से ज़्यादा डिज़ाइन किया गया API है
CUDA में जो GPU memory allocation एक लाइन में हो सकता है, Vulkan में उसके लिए बहुत सारा boilerplate लिखना पड़ता है
नया Vulkan काफ़ी बेहतर हुआ है, लेकिन अभी भी बहुत रास्ता बाकी है
उम्मीद है SDL3 या wgpu ऐसा abstraction layer बनें जो इस जटिलता को कम कर दे
Valve SDL3 को support कर रहा है, इसलिए मुझे वही ज़्यादा संभावित लगता है
सबसे पहले यह सवाल करना चाहिए: “क्या graphics को multithreaded तरीके से प्रोसेस करना ज़रूरी है?”
अगर नहीं, तो Vulkan/DX12 इस्तेमाल करने की कोई खास वजह नहीं है
performance problem आने से पहले तक OpenGL, DX11, या कोई game engine इस्तेमाल करना कहीं बेहतर है
मैं 3D/game programming से बहुत प्रभावित हूँ, और कुछ YouTubers को अक्सर game बनाते हुए देखता हूँ
लेकिन web apps या DevOps की तुलना में यह कहीं ज़्यादा जटिल दुनिया है
इसमें pixel shaders, compute shaders, geometry, linear algebra, और PDE तक आ जाते हैं
TokyoSpliff YouTube चैनल
आजकल शौक़ के तौर पर game engine बनाना एक शानदार काम माना जाता है, यह अच्छी बात है
मैं भी 10 साल से अपना निजी engine बना रहा हूँ, और यह बहुत संतोषजनक अनुभव रहा है
अगर आप graphics programming पहली बार कर रहे हैं, तो OpenGL से शुरू करना बेहतर है
मैंने 23 साल पहले NeHe की OpenGL tutorials पढ़ी थीं, और आज भी मुझे लगता है कि वे सबसे अच्छी तरह व्यवस्थित learning materials में से हैं
जानकारी के लिए, मैं मूल पोस्ट का लेखक नहीं हूँ; मैंने सिर्फ़ शीर्षक वही रखा है