Rendering

Rendering analysis - Cyberpunk 2077

(**Spoilers-free post!**) Quite a lot of people I know inside or outside this industry are playing the long-waited “gargantuan maelstrom” now. After a couple few hours immersed around the stunning view (and bugs of course) in the Night City, I was wondering how one frame is rendered in Cyberpunk 2077 (every graphic programmer’s instincts!). So I opened RenderDoc and PIX, luckily REDengine didn’t behave unfriendly like some other triple-that (yes Watch Dogs 2 I mean you), I got a frame capture without…

Read
GameAudio

How expensive it is to create your own AAA-level game audio solution?

[](<>)Don’t be greedy, unless it’s really cheap I’ve been in the game industry for almost 5 years since I broke up with traditional music post-production, and the official direction which I spend every 8\*5 (of course, sometimes more) hours a week and get paid is not surprisingly, game audio. It doesn’t matter how you’re familiar with this domain, more or less you’d hear about some names like FMOD or Wwise recent years, even you’re just coming from a typical gamer’s point of view. Nowadays anybody who…

Read
GameEngine

Reflection in C++... could we nail it now?

Maybe you’ve seen multiple times the symbol of Ouroboros in different movies and games that about a fancy snake who biting its own tail, despite whether it’s painful (just hope those serpents would have a better control when biting themselves!), these kind of self-dependent problems emerging often when we started to consider one of the most desired features in C++ — how could we inspect the information of the language itself in runtime? <img src="https://upload.wikimedia.org/wikipedia/commons/7/71/Serpiente_alquimica.jpg" alt="Ouroboros" width="30%" height="30%" align="middle"> Anybody who has been writing not only <code class="language-text">std::cout &lt;&lt; "hello world!"</code> for a certain amount would know that C++ is a [static, nominative, partially inferred](<>) programming language, a language designed to be written in a human-readable format and then compiled directly into a bunch of CPU-readable instructions. The only information we could get in touch within a runtime environment is those values stored on heap and stack since after an executable file was loaded into main memory and started to execute, the available scope of the program itself is bound by its own virtual mapped memory space. This would be fine for quite a lot usage cases if we’d only expect C++ as a tool to drive the computer to work for our certain computational tasks, then we’d write the human-readable source code with our well-designed logic business model, and later let the compiler translate them into whatever a CPU wants. But when you started to build a framework, a middleware, a tool for tool production, or anything complicated enough to scare people, there would often appear a requirement that you’d want the program to know itself in a human-readable way and feedback the user these pieces of information in runtime. For example, the simplest case is you want to give the user a magic log…

Read
Rendering

Physically Based Rendering - Lighting

As soon as we modeled the surface’s physical properties that covered a certain range of material in real life, we would need to emit light onto them, in order to finally get the outcome radiance from the surface. If you take a look back at the rendering equation, the outcome radiance is just an integral of the income radiance over the semi-sphere around the normal. This gives us a fundamental assumption that with a brutal algorithm such as path tracing we could get a numerical solution for the…

Read
Rendering

Walking through the heap properties in DirectX 12

[](<>)Indifferent to the difference? Back to the old times, you never worried about how the physical memory would be allocated when you’re dealing with OpenGL and DirectX 11, GPU and the video memory were hidden behind the driver so well that you might even not realize they were there. Nowadays we get Vulkan and DirectX 12 (of course Metal, but…nevermind), that the “zero driver-overhead” slogan (not “Make XXX Great Again” sadly) become the reality on desktop platforms. And “ohh I don’t know that we…

Read
Rendering

So many descriptors in Vulkan

[](<>)Brainwash is always somewhere It’s really a mess when I started to port my engine to Vulkan, there are too many new data types that mapped to those came-from-nowhere concepts, which I don’t need to take care about previously. But luckily those concepts are well designed and once after you understand what they are, every pain you occurred would just disappear. The new generation graphics APIs all transport the responsibility of CPU-GPU communication to the user more or less explicitly, now if you…

Read
GameEngine

Welding (THE latest) C++ to Metal, and macOS

[](<>)For what? I’ve previously deployed my game engine to macOS successfully with GLFW and macOS’s “vanilla” version OpenGL 4.1 library, everything was pretty smooth and sweet (and of course naive) at that time, and every few weeks I would port the latest updates from Windows side to macOS in an accumulated way. But as I started to utilize some C++17 new features, yep I mean <code class="language-text">&lt;filesystem></code>, which Apple still didn’t give us a certain answer (I’ve heard that there is something new with Apple Clang in the Xcode 10.…

Read
Rendering

Normal and normal mapping

[](<>)A (not) tedium work Recently I started to port my project to DirectX 11, and it has a lot of interesting differences with OpenGL such like the coordinates and matrix convention, stronger type safety requirement, better shader resources management (I didn’t try OpenGL’s SSBO yet but the constant buffer is really easier to wrap into an elegant layer) and etc. One thing I stuck a little is the normal mapping there since I used the on-the-fly tangent generation in GLSL, it quite confuses me at first…

Read