Showing posts from 2014

DirectX11 - Development INF

Welcome to the first Development INF (stands for information)! Basically for each Development INF article, I will be listing the road blocks, gotchas, tips and tricks that I found during development; in this case DirectX11.

1. DirectX11 is part of WindowsSDK For old time DirectX developers, we usually had to install DirectX SDK. However, starting Windows 8, Microsoft has included the SDK to Windows 8 SDK. Consequently, this creates compile issues as some projects are still referencing the old DirectX path.

In Visual Studio, we usually use $(DXSDK_DIR)\Include and $(DXSDK_DIR)\Lib to locate the headers and lib, however, this will be no longer the case. The headers should be in $(WindowsSDK_IncludePath) and lib in $(WindowsSdkDir)\lib\x64.
2. D3DX11 library is deprecated D3DX11 Library is Deprecated, we should no longer include d3dx11.h header and no longer use D3DX11* functions. We need to find the replacement for each function.

3. DirectXMath replaces XNAMath
//#include <xnamath.h> …

Lighting Theory: Radiometry and Photometry

Recent games have been heading towards Physically Based Rendering and this requires a solid understanding on lighting theory more than ever before. This time, I'm posting my note on Radiometry and Photometry.
RadiometryRadiometry is basically ideas + mathematical tools to describe light propagation + reflection. Radiative Transfer is a study of transfer of radiant energy (which operates on geometric optics level - macroscopic properties of light suffice to describe how light interacts with objects much larger than light's wavelength).

Four Radiometric Quantities:

1. Flux (Radiant Flux/Power) - total amount of energy passing through a surface or region of space per unit time (J/s or Watt). Total emission from light sources is generally described in terms of flux.
2. Irradiance (E) - area density of flux arriving at a surface (Watt/m2)
Radiant Exitance (M) - area density of flux leaving a surface (Watt/m2)
3. Radiant Intensity (I)- flux density per solid angle (Watt/sr)
4. Radiance…

D3D11 Compute Shader - Part 2

To understand the concept of Compute Shader, let's start from basic.

Compute Shader (CS) Threads
A thread is basic CS processing element.

1. CPU kicks off CS thread groups.
// Total number of thread groups = nX * nY * nZ pDevice->Dispatch( nX, nY, nZ );
2. Each CS declares the number of threads on the "thread group". // Total number of threads per thread group = X * Y * Z [numthreads(X,Y,Z)] void cs_main(...) { ... }
// CPU pDevice->Dispatch( 3, 2, 1 ); // CS [numthreads(4, 4, 1)] void cs_main(...) { ... } // # of thread groups = 3*2*1 = 6 // # of threads per group = 4*4*1 = 16 // # of total threads = 6 * 16 = 96
N.B: Picture taken from GDC09 Slide "Shader Model 5.0 and Compute Shader"

CS Parameter Input
void cs_main(uint3 groupID : SV_GroupID, uint3 groupThreadID : SV_GroupThreadID, uint3 dispatchThreadID : SV_DispatchThreadID, uint groupIndex : SV_GroupIndex) { ... } // groupID …

Computing Bent Cone

In rendering world, there are several article that discusses about bent cone. For example Bent Normals and Cones in Screen Space and also in GPU Pro 3: Screen-Space Bent Cones: A Practical Approach.

In this post, I wanted to share how I compute bent cone (bent normal and max cone angle). The paper Bent Normals and Cones in Screen Space actually discusses how you compute bent normal and max cone angle (although it's a bit math-y). Here, I want to present how I compute it.
Computing bent normal is quite easy, basically you just shoot rays from your sampling point (pixel/vertex) and average the unoccluded rays (and normalize it).
For max angle, it turns out we can correlate it with AO: Let: A = Half Opening of Cone Angle AO = Ambient Occlusion Value AO = UnoccludedArea / TotalArea Where: TotalArea = Hemisphere Area = 2 * pi * r * r UnoccludedArea = Area covered by Solid Angle 2A = Solid Angle 2A * r * r = 2 * pi * (1 - cosA) * r * r Hen…

Translucent Shadows Part I - Starcraft II

Shadows is an important visual cue for rendering and has been incorporated into recent games via shadow mapping technique. Most shadow mapping technique only concerns about opaque object shadows and there is not a lot of about translucent object shadows.

Translucent Shadows in Starcraft II Review In Starcraft II - Effects & Techniques, Dominic Fillion mentions how they render translucent shadows in Starcraft II. Here's how the rendering works:

* Requires second shadow map and color buffer. Let's name them as translucent shadow map and translucent shadow buffer.

Shadow Maps Rendering
* Opaque Shadow Map: render opaque objects to opaque shadow map
* Translucent Shadow Map: render translucent objects to translucent shadow map (z-write on, z-test on with less equal, no alpha test, records depth of closest transparency)
* Translucent Shadow Buffer: Clear to white, sort translucent objects front-to-back, use Opaque Shadow Map as z-buffer, no z-write off, z-test on with less…

C/C++ Programming Tips and Tricks

Every once in a while I found some C/C++ tips and tricks. This page is going to be the repository of those tips and tricks.

Constexpr specifier declares that it is possible to evaluate the expression at compile time:
1. Constexpr function
2. Constexpr constructor
3. Constexpr variable
Initialization of constexpr MUST happen at compile time (const variable can defer at runtime). Constexpr implies const and const implies static. If constexpr variable is in the header, every translation unit will get its own copy. Since C++17, inline keyword can be added to variables (and constexpr variables) that means there should only be one single copy in all translation units (this also allows to declare non-const variable in header file).

Fast insertion to std::map/std::unordered_map
std::unordered_map > m; auto [iter, succeed] = m.emplace( key, nullptr ); if ( succeed ) iter->second = std::make_unique();
Creating C++ function similar to printf()
template inline std::string StringFor…

D3D11 Compute Shader - Part 1

GPU has become a general purpose processor! or at least becoming more and more general. This is proved by the existence of GPGPU APIs such as DirectCompute, CUDA, OpenCL. It's time to start learning Compute Shader (CS), in this case, DirectCompute from D3D11.

Past GPGPU Coders... Believe it or not GPGPU actually has existed before Compute Shaders arrived. However, you need to structure everything in terms of graphics, i.e. in order to launch GPGPU computation you have to render geometry and you basically use Pixel Shaders to do the computation.
While this style of GPGPU coding can still work today, we can do much better! Compute Shaders allow us to use GPU just like we program a regular code. The first benefit is that you don't need to care about graphics pipeline and such, you just need to dispatch your Compute Shaders and that's it. In addition, Compute Shaders bypass graphics pipeline, i.e. primitive assembly, rasterization, etc2; so you have the potential to run faster …