21 ms·
I learned Vulkan and wrote a small game engine with it
- edu 2y agoThe site seems hugged to death, cached: https://web.archive.org/web/20240606103630/https://edw.is/learning-vulkan/ https://web.archive.org/web/20240606103630/https://edw.is/le...
- eliasdaler 2y agoThank you! Also, everything explained in the article is pretty much here: https://github.com/eliasdaler/edbr https://github.com/eliasdaler/edbr
- archermarks 2y agoReally nice article! I have some OpenGL familiarity and tried out Vulkan but bounced off of it due to all of the up-front complexity just getting something running. Might give it another shot now!
- eliasdaler 2y agoThank you. The up-front complexity is still there and it might take quite a few days to see your first triangle. But I promise, everything will get much easier from that point. :)
- mort96 2y agoThe thing I'm most interested in doing when starting a new project is pretty much never to spend a few weeks and writing 10-20k LOC to get a triangle on the screen, I think I'll stick with OpenGL for the time being tbh
- eliasdaler 2y agoYou'll need 1k LOC to draw a single triangle and not 10-20k. Sticking with OpenGL is understandable, but I can recommend learning some Vulkan as a side project (with the help of vkguide) without too much commitment. That's how I started and it turned out to be not as bad as I imagined! Uour mileage may vary, of course.
- jsheard 2y agoIt's not quite as bad as it used to be, various later additions to Vulkan like dynamic rendering have eliminated some of the complexity it originally had. Figuring out which subset you should be using is a challenge in itself though, especially since there's a lot of outdated introductory resources floating around which still promote the ultra-verbose Vulkan 1.0 way of doing things. If a tutorial tells you to use render passes, run away.
- galangalalgol 2y agoInteresting, for a while the guidance for a while was to learn webgpu instead unless you needed all that extra control. Do you think these changes modify that guidance?
- jsheard 2y agoWebGPU (or Metal if you're in Apple land) still has a much gentler learning curve. The simplifications to Vulkan weren't really aimed at making it easier to use, just streamlining parts of the API which turned out to be needlessly complex, so the parts that are complex for a reason are still just as complex.
- galangalalgol 2y agoThanks! Other than a project not running as fast as necessary, do you have any advice on how to know when/if I need to switch to vulkan?
- jsheard 2y agoAside from performance there's also just more hardware features exposed via Vulkan, as a sibling mentioned if you want to do anything with raytracing for example then you will have to graduate to Vulkan in order to take advantage of hardware acceleration.
- exDM69 2y agoWith WebGPU/wgpu you don't get mesh shaders, ray tracing or shader subgroup/wave/warp operations. Its feature set is comparable to Vulkan 1.0, and Vulkan has progressed a lot since. And WebGPU still requires all the RenderPass setup code which is a lot of boilerplate that Vulkan no longer requires.
- eliasdaler 2y agovkguide is a great way to get a feel of modern Vulkan. Maybe it’ll be still to complex for you - then it’s okay to say on OpenGL or learn some WebGPU. I started learning Vulkan as an experiment and it seemed to work out well, so that’s why I wrote this article. :)
- dventimi 2y ago[flagged]
- deleted 2y ago[deleted]
- spicyusername 2y agoLots of good advice in this article. One that stuck out to me: Don’t implement something unless you need it right now This is a constant battle I fight with more junior programmers, who maybe have a few years of experience, but who are still getting there. They are often obsessed with "best-practices" and whatever fancy new tool is trending, but they have trouble starting with the problem they need to solve and focusing on the minimum needed to just solve that problem.
- Hendrikto 2y ago> They are often obsessed with "best-practices" Tell them YAGNI is also a best practice :D
- fuzztester 2y agoYes. So is KISS. https://en.m.wikipedia.org/wiki/KISS_principle https://en.m.wikipedia.org/wiki/KISS_principle
- junon 2y agoYep. I attribute YAGNI to a lot of my quickest prototypes and some of my best code.
- Narhem 2y agoDefinitely agree. But there’s a fine line between implementing things but the difficulty being understanding long term vision and making sure short term improvements don’t actively work against the ‘ideal’. Kind of hard for newer programmers to get a good sense of system design.
- xedrac 2y agoYes, over engineering solutions is a constant thorn in my side. The end result is you get a lot of additional complexity for basically no benefit. In my experience, if new requirements do come down the pipeline at some later time, the generic solution you previously built will be completely inadequate and will need to be redone anyway. Solve the problem in front of you, not some unknown future problem.
- jokoon 2y agoI think vulkan is great, but its only purpose is to take full advantage of advanced GPU features. It also leads to better performance when using advanced GPU features compared to OpenGL. Generally, I feel OpenGL is the recommended route if you don't really aim for advanced rendering techniques. There are plenty 2D /lowpoly/ps1-graphics games right now, and those don't need to use vulkan. Vulkan is an example of how the AAA gaming industry is skewed towards rendering quality and appearance. AAA game studios justify their budget with those very advanced engines and content, but there is a growing market of 2D/low poly game, because players are tired and realized they want gameplay, not graphics. Also if you are a game developer, you don't want to focus on rendering quality, you want to focus on gameplay and features.
- ChadNauseam 2y agoA middle ground is webgpu. It is much less verbose than Vulkan and is guaranteed to run anywhere, including the browser. At the same time, it has access to "modern" features like compute shaders which would not be available in webgl. It also doesn't have much legacy cruft leading to multiple ways of doing the same thing, unlike opengl. The main advantage is that it's new, so there are many fewer tutorials available for it, and that is a very serious disadvantage.
- alexvitkov 2y agoIt's a JavaScript API, it only runs in the browser. It's not real.
- alunchbox 2y agohey just curious, any reason why some of these articles I see from time to time don't apply some simply CSS? I don't mind the raw html, I'm mostly wondering if there's some benefit to it that I might not be aware of.
- PhilipRoman 2y agoThe site definitely has CSS, just not a lot of it.
- eliasdaler 2y agoIndeed. I used as little CSS as I could because I love minimalist websites. And the lack of syntax highlighting was inspired by Go blog, for example. :) Raw HTML definitely looks much uglier, sadly (“Reader mode” in most browsers makes websites without CSS easily readable, though!).
- cristoperb 2y agoYour site looks nice and is quite readable! The thing I most dislike about sites that just use raw HTML is the lack of `max-width` on the text containers (which makes using reader mode necessary), so thanks for including that
- eliasdaler 2y agoThank you! :)
- johnnyanmac 2y agoreminds me a lot of http://bettermotherfuckingwebsite.com/ http://bettermotherfuckingwebsite.com/ pretty much all HTML, with only the bare minimum CSS to make it somewhat responsive. I guess if you want one tiny piece of feedback, based on the above site: >A little less contrast >Black on white? How often do you see that kind of contrast in real life? Tone it down a bit, asshole. I would've even made this site's background a nice #EEEEEE if I wasn't so focused on keeping declarations to a lean 7 fucking lines. I agree with the advice, but I've definitely seen many a heated debate over raw black on raw white amongst designers. So take with a grain of salt and a handful of personal preference.
- rossant 2y agoGreat writeup! I learned Vulkan myself so that I could write a scientific data visualization engine (https://datoviz.org/ https://datoviz.org/ still quite experimental, will release a newer version soon). I had some knowledge of OpenGL before and learning Vulkan was SO hard. The learning resources weren't that great 5 years ago. I took up the challenge and it was so much fun. It took me months to understand the role of the various dozens of abstractions. In the process I wrote a small wrapper around Vulkan (https://datoviz.org/api/vklite/ https://datoviz.org/api/vklite/) to make it a bit less painful to work with (it supports a subset of the features, those that are the most required for scientific visualization purposes).
- atan2 2y agoGreat read! Elias always does great work.
- samiv 2y agoThis might come off as a surprise to some people but getting good performance with Vulkan (compared to say OpenGL) isn't trivial because: the Vulkan driver is missing that ~20k loc of code that OpenGL driver does for you to set up the rendering pipelines, render targets etc. This is all code that already exists in the OpenGL driver and has been optimized for +20 years by the best people in the industry. So when you start putting together the equivalent functionality that you get out of the box with OpenGL on top of Vulkan doing it the naive way doesn't magically give you good perf, but you gotta put in some more work and then the real problems start stacking up such as making sure that you have all right fences etc synchronization primitives in place and so forth. So only when you actually know what you're doing and you're capable of executing your rendering with good parallelism and correct synchronization can you start dreaming about the performance benefits of using Vulkan. So for a hobbyist like myself.. I'm using OpenGL ES3 for the simplicity of it and because it's already good enough for me and I have more pressing things to matter than spend time writing those pesky Vulkan vertex descriptor descriptor descriptors ;-) Btw this is my engine: https://github.com/ensisoft/detonator https://github.com/ensisoft/detonator
- harrison_clarke 2y agothe biggest part for me is the shader compiler. opengl has one built in, vulkan requires me to pull in yet another dependency i've heard that vulkan allows bindless textures now, so the descriptor nonsense is a bit less awful that it used to be vulkan is appealing, but there's a high initial cost that i don't want to pay
- sigmoid10 2y agoVulkan is super appealing if you're in the industry and have the time and resources necessary to profit from its advantages. But if you're a single dev who wants to learn game engine design, you're going to have a bad time. Most people also don't get that game engine design is very far removed from actual game design. You can have a ton of fun learning math, physics and computer science when building an engine, but beware that you'll likely be mentally and physically exhausted long before you actually get to build a fun game.
- OnionBlender 2y agoI've been trying to learn Vulkan on and off for years (I used to know OpenGL ES 2&3 pretty well). One thing I found difficult is understanding how to use things in a real engine rather than a sample. A lot of samples will allocate exactly what they need or allocate hundreds of something so that they're unlikely to run out. When I was trying to learn DirectX, I found Microsoft's MiniEngine helpful because it wasn't overly complex but had things like a DescriptorAllocator that would manage allocating descriptors. Is there something similar for Vulkan? Another thing I struggle with is knowing how to create good abstractions like materials, meshes, and how to decide in what order to render things. Are there any good engines or frameworks I should study in order to move beyond tutorials?
- cmovq 2y agoTake a look at a real engine, something like vkquake is a good reference [1]. [1]: https://github.com/Novum/vkQuake https://github.com/Novum/vkQuake
- gmueckl 2y agoVulkan is quite similar DirectX 12. Done concepts transfer directly. For memory allocation, you can use a library called vma to assst you. It takes care of a few stupid edge cases that the Standard accunulated over the years and is quite powerful. For descriptor set allocation, there is only one pattern that nakes sense to me: expect the pools to be rather short lived and expect to have many of them. Allocate a new one once allocation from the current one fails - don't keep your own counters for alocated descriptors. The standard allows for all kinds of pool behaviors that deviate from strict counting. Discard old pools after the the last command buffer referencing that pool is finished. Pipeline barriers and image layouts are a big pain in the butt. It makes sense to abstract them away in a layer that tracks last usage and lat Format for everything and adds barriers as required. It can get complex, but ot's worthbitnonce you have optional passen or passes that can get reordered or other more complex things going on. About neshes, materials, rendering order: this goes beyond what I can summarize in a single HN post. This depends a lot on the choice of rendering algorithms and I do not consider a very generalized solution to be worth the (enormous) effortto get this right.
- andrewmcwatters 2y agoFor the casual reader who is curious what it takes to write a "Hello, Triangle!" in Vulkan 1.3: https://github.com/Planimeter/game-engine-3d/blob/main/src/graphics_vulkan.cpp https://github.com/Planimeter/game-engine-3d/blob/main/src/g...
- ku1ik 2y ago/o\
- eliasdaler 2y agoIndeed. vk-bootstrap is a bit better with 600 lines of code, though: https://github.com/charles-lunarg/vk-bootstrap/blob/main/example/triangle.cpp https://github.com/charles-lunarg/vk-bootstrap/blob/main/exa... Vulkan initialization and basic swapchain management is very verbose, but things get much better after you do it for the first time and make some handy abstractions around pipeline creation/management later.
- andrewmcwatters 2y agoFor sure. They just move the roughly 300 lines of code elsewhere so you don't have to do it, though. I'd like to see them move nearly all 900-ish lines of SLOC back down into the near 90-ish you'd need to initialize OpenGL. There's so much overlap in basically everyone's graphic usage of Vulkan that you realize after doing it yourself they should have done some simple optimization for the 99% use case, and allowed other people to write the full 900+ lines for GPU compute or other use cases.
- eliasdaler 2y agoI guess libraries like bgfx, sokol and The Forge are kinda like that. But I just feel like it’s either all or nothing if you’re already doing your own game engine. I’m okay with using middleware/3rd party libraries for things which I don’t care too much about (e.g. physics), but graphics is such a core component that I want to handle it myself. In a way, OpenGL drivers were such middleware libraries written for you by GPU vendors (or open source community). But now they stopped doing that and now you’re either writing your own graphics abstraction layer or using someone else’s. In this case, I choose the hard way. And it seemed to have worked out so far. I definitely won’t recommend it to everyone (especially if they want to make a game in less than a year!), but as a learning experience it was fun.
- wudangmonk 2y agoIts great to have more Vulkan resources but unfortunately this one too suffers from the same problem as every other resource I've found on getting something on the screen with Vulkan. They all introduce another layer of abstraction on top of Vulkan even before giving you the simple case without it. Its always use vk-bootstrap, volk, vma or someother library. Is there a single resource anywhere that gives an example of doing the memory management manually because I havent found one, it seems like its either use vma or go figure out the spec are the only choices you are given. Is it too much to ask to just get the most basic example without having to add any libraries other than the Vulkan sdk itself?.
- harrison_clarke 2y agothere's a common gamedev practice of allocating a big chunk of memory up front, and then using a bump allocator inside of it in most games, there are about 3 "lifetimes": - permanent/startup - per-level - per-frame and they're nested. so, you can use a single stack allocator for all of them. at the end of the frame/level, pop back to where it started there are more complicated patterns, but this one will get you pretty far. you can use it on the CPU and the GPU
- greathones 2y agowhere to read more? any books? articles?
- harrison_clarke 2y agogame engine architecture, by jason gregory there's a section on memory allocation patterns i believe casey muratori talks about allocation patterns in the handmade hero video series, too edit: ryan fleury has a talk: https://www.rfleury.com/p/enter-the-arena-talk https://www.rfleury.com/p/enter-the-arena-talk
- andrewmcwatters 2y agoYes. It's too much to ask. Even the "official" examples by documentation do not do it. Reading the Vulkan specifications is an exercise in practicing technical bullshit. When you're corroborating some random person's third-party instructions on initializing Vulkan and comparing those notes to what's done in Khronos Group repositories and reading the Vulkan 1.3 spec and realizing you have to read the specification out-of-order to get anything done, it's clear that they failed. They failed. It's bad work by any other standard. But you'll do the work once and forget about it for the most part, so professionals don't complain too much. Read my other comment in this thread for a portion of source code annotated with the specification chapters and sections. It's a generic implementation that can be used with SDL and others. Edit: As of the time of writing, the standard approach is to use VMA and Volk, both of which are included with the official Vulkan SDK. That should tell you enough about the state of the art.
- wg0 2y agoOff topic kind of - Can an LLM generate such an article? Reading such in depth experiences and consolidating advice makes me think that web is made by humans and every other day,I spot something on the web that is clearly generated from some LLM. Great write up. Inspiring.
- eliasdaler 2y agoThanks a lot, that’s a very touching comment. I try to make my website to feel like “the old Internet” that we seem to be losing and it's great that it’s noticeable. :)
- layer8 2y agoIs this better than learning Klingon? ;)
- Waterluvian 2y agoAre there any examples of an academic attempt at putting as much of a game into the GPU as possible? Like, architecting a game in a way that pretty much everything, including game logic, could be implemented as a shader?
- andrewmcwatters 2y agoShadertoy is your best bet. There are a few people doing it there.
- Cloudef 2y agoPosted this in hn few days ago https://vkguide.dev/docs/gpudriven/gpu_driven_engines/ https://vkguide.dev/docs/gpudriven/gpu_driven_engines/
- eliasdaler 2y agoI know about two games which do very interesting stuff with modern GPU capabilities: * Noita * Teardown They both do their physics on GPU which results in some impressive effects and the level of destruction/world interaction which wasn't seen anywhere before. Here's an interesting Teardown engine overview by its devs: https://www.youtube.com/watch?v=tZP7vQKqrl8 https://www.youtube.com/watch?v=tZP7vQKqrl8
- Animats 2y agoThis minimalism is very effective. I took the opposite approach, and it has cause great pain. I've been writing a metaverse client in Rust. Right now, it's running on another screen, showing an avatar riding a tram through a large steampunk city. I let that run for 12 hours before shipping a new pre-release. This uses Vulkan, but it has WGPU and Rend3 on top. Rend3 offers a very clean API - you create meshes, 2d textures, etc., and "objects", which reference the meshes and textures. Creating an object puts it on screen. Rust reference counting interlocks everything. It's very straightforward to use. All those layers create problems. WGPU tries to support web browsers, Vulkan, Metal, DX11 (recently dropped), DX12, Android, and OpenGL. So it needs a big dev team and changes are hard. WGPU's own API is mostly like Vulkan - you still have to do your own GPU memory allocation and synchronization. WGPU has lowest-common-denominator problems. Some of those platforms can't support some functions. WGPU doesn't support multiple threads updating GPU memory without interference, which Vulkan supports. That's how you get content into the GPU without killing the frame rate. Big-world games and clients need that. Also, having to deal with platforms with different concurrency restrictions results in lock conflicts that can kill performance. Rend3 is supposed to be a modest level of glue code to handle synchronization and allocation. Those are hard to do in a general way. Especially synchronization. Rend3 also does frustum culling (which is a big performance win; you're not rendering what's behind you) and tried to do occlusion culling (which was a performance lose because the compute to do that slowed things down). It also does translucency, which means a depth sort. (Translucent objects are a huge pain. I really need them; I work on worlds with lots of windows, which you can see out of and see in.) The Rust 3D stack people are annoyed with me because I've been pounding on them to fix their stack for three years now. That's all volunteer. Vulkan has money behind it and enough users to keep it maintained. Rend3 was recently abandoned by its creator, so now I have to go inside that and fix it. Few people do anything elaborate on WGPU - mostly it's 2D games you could have done in Flash, or simple static 3D scenes. Commercial projects continue to use Unity or UE5. If I went directly to Vulkan, I'd still have to write synchronization, allocation, frustrum culling, and translucency. So that's a big switch. Incidentally, Vulkano, the wrapper over Vulkan and Metal, has lowest-common-denominator problems too. It doesn't allow concurrent updating of assets in the GPU. Both Vulkan and Metal support that. But, of course, Apple does it differently.
- 2y ago
- brian_herman 2y agoThose kitties are so cute!
- eliasdaler 2y agoThanks! :D
- tombert 2y agoI tried learning Vulkan a little more than a year ago and I have no desire to ever touch it again. It really bothers me that we're deprecating OpenGL and replacing it with something that's ridiculously hard to do anything simple (e.g. doing a spinning cube takes several hundred lines of code). OpenGL was never "easy" but it was at least something a regular person could learn the basics of in a fairly short amount of time. You could go to any big book store, buy some intro to graphics programming book, and get some basic stuff rendering in an afternoon or two. I'm sure Vulkan is better in some regards but is simply not feasible to expect someone to learn it quickly. Like, imagine the newest Intel/ARM/AMD chips came along and instead of being able to write C or C++, you're being told "We are dropping support for higher level languages so you can only write assembly on this now and it'll be faster because you have more control!" It would be correctly labeled as ridiculous.
- edflsafoiewq 2y agoVulkan is for writing OpenGL-type libraries against. It's advantage is largely that much of the library-level code is moved out of opaque and buggy device drivers and into user-space libraries.
- tombert 2y agoNo, I don't think that that's good reasoning. They could, if nothing else, make first-party libraries that have a high-level DSL or something that makes it less horrible to use. As it stands it creates a bunch of crappy libraries on top instead of an officially supported API that could also be standardized across operating systems and platforms. The terrible terrible Vulkan API just kind of feels gatekeepey. They got rid of the only open easy-to-use graphics standard, made NO REPLACEMENT, and then said "oh you should just use this impossible API or let the outside world come up with a fix around it".
- edflsafoiewq 2y agoIt doesn't really make sense to have Khronos maintain nice high-level libraries. There's no evidence they'd be good at it and if you look at their GitHub, they're not particularly good at maintaining actual codebases in the first place. Their commitee/standard-based process works for specs, but I don't think it will work very well for the needs of day-to-day application programmers. Why do you need Khronos to "bless" a particular library anyway? Also they didn't get rid of OpenGL. You can still use it. It will probably be the most widely supported graphics API for a long time.
- uwagar 2y agolife was a pleasure writing programs in IrisGL and then OpengGL :(
- eliasdaler 2y agoYeah. Even though it might seem I’m 100% enjoying Vulkan, I still wish there was something closer to OpenGL and which was supported by GPU manufacturers. Other 3d party graphics frameworks are not bad, but you don’t feel the same confidence in their future in the same way as you did about OpenGL.
- rychco 2y agoI’ve been lurking & following your project for months in the Graphics Programming discord as I work on my own hobby Vulkan engine. It’s been inspiring seeing all the progress you’ve made. I especially admire your willingness to ask questions & share your work-in-progress so openly. Keep up the great work
- eliasdaler 2y agoThanks a lot! Good luck with your engine as well :)
- dynjo 2y agoHighly recommend this guy’s channel, he livestreams building a Vulkan game engine and he has a crazy style too https://youtube.com/@tokyospliff?si=CMF53295xeETykbP https://youtube.com/@tokyospliff?si=CMF53295xeETykbP
- wilkystyle 2y agoThis is great, thanks for sharing! No kidding about the interesting style, too. Very entertaining. For example, his quick sidebar to explain fundamental shader types was great even for me, as someone who is not that familiar with the topic (link goes to 11:20): https://youtube.com/watch?v=azdjSi_9Xyc&t=11m20s https://youtube.com/watch?v=azdjSi_9Xyc&t=11m20s
- eliasdaler 2y agoOh yeah, I enjoy his streams a lot :D I can also recommend Arseny Kapoulkine YouTube channel[1]. It can get a bit too advanced at times, but his channel was one of my motivators of getting into Vulkan programming. [1]: https://www.youtube.com/@zeuxcg https://www.youtube.com/@zeuxcg
- OwenKriz 2y ago[dead]
- animal531 2y agoThe screenshots reflect my experience 10-15 years ago creating my own SDL OpenGL engine+game where lighting is the first really hard thing to get looking good for a beginner to intermediate developer.
- null_point 2y agoRead through this last night. Loved the article! Blending the story of your personal experience with a pseudo, high-level tutorial was really interesting.
- eliasdaler 2y agoGlad you enjoyed it! :)
- koolala 2y agoi learned webgpu and then it couldn't hit 90fps
- amandasystems 2y agoI really appreciate a “here’s how I did this” that also includes hints on how to avoid bikeshedding and essentially getting scared out of doing the thing. In my experience being daunted ans not knowing where to start is a large part of the difficulty in doing difficult things.