Posts

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: Notes: * 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-...

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 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 st...

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 r...

Mapping Square Texture to Trapezoid / Quadrilateral

It turns out to be not a straightforward one. If you ever want to render trapezoid but mapped to square texture coordinate, i.e. (0,0) - (1,1), it won't turn out right. Turns out there's an easy way to fix this. Basically, instead of passing in float2 texture coordinates, you need to pass in the third coordinate to do projection on texture coordinates. The solution can be found here  http://stackoverflow.com/questions/15242507/perspective-correct-texturing-of-trapezoid-in-opengl-es-2-0 . Edit: It turns out, there's a more generic solution, i.e. quadrilateral interpolation: http://www.reedbeta.com/blog/2012/05/26/quadrilateral-interpolation-part-1/ Other references that might be useful: http://hacksoflife.blogspot.com/2009/11/perspective-correct-texturing-q.html http://www.xyzw.us/~cass/qcoord/ http://www.gamedev.net/topic/419296-skewedsheared-texture-mapping-in-opengl/

CPU Branch Optimization

Just want to share collection of tricks to optimize branch in CPU. Bounds Checking Checking bounds [0,max) // int i, max; // if (i >= 0 && i < max) {} if ((unsigned int) i < (unsigned int)max) {} Checking bounds[min,max] // int i, min,max; // if (i >= min && i <= max) {} if ((unsigned int)(i - min) <= (unsigned int)(max - min)) {}

Reconstructing Position From Depth

Matt posted an excellent article about reconstructing position from depth. Check out his article here: http://mynameismjp.wordpress.com/2009/03/10/reconstructing-position-from-depth/ He has the following function to reconstruct View Space Position from Post Clip Space Position : // Function for converting depth to view-space position // in deferred pixel shader pass. vTexCoord is a texture // coordinate for a full-screen quad, such that x=0 is the // left of the screen, and y=0 is the top of the screen. float3 VSPositionFromDepth(float2 vTexCoord) { // Get the depth value for this pixel float z = tex2D(DepthSampler, vTexCoord); // Get x/w and y/w from the viewport position float x = vTexCoord.x * 2 - 1; float y = (1 - vTexCoord.y) * 2 - 1; float4 vProjectedPos = float4(x, y, z, 1.0f); // Transform by the inverse projection matrix float4 vPositionVS = mul(vProjectedPos, g_matInvProjection); // Divide by w to get the view-space position ...

C# Integer to String Builder

As many of you know, StringBuilder.Append(int) method creates a garbage. This is bad for XNA games that do this conversion every frame. In this article, I provide one implementation to convert int to string without creating garbage. I tried to be as efficient as possible; if you find better way to do this, please let me know. public static class StringBuilderExtension { private static char[] charToInt = new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' }; public static void Swap(this StringBuilder sb, int startIndex, int endIndex) { // Swap the integers Debug.Assert(endIndex >= startIndex); int count = (endIndex - startIndex + 1) / 2; for (int i = 0; i

World, View and Projection Matrix Internals

Image
This convention below is applicable to Direct3D and XNA matrices World Matrix Given a  position  and basis vectors  right ,  up  and  look  of an  object , a world matrix can be formed by the following arrangement: View Matrix Given a  position  and basis vectors  right ,  up  and  look  of a viewer, a view matrix can be formed by the following arrangement: Projection Matrix Given field of view  FOV ,  aspect ratio , near clip plane  Zn  and far clip plane  Zf , a perspective projection matrix can be formed by the following arrangment:

Minimum Bounding Sphere for Frustum

Image
I was in need to create a minimum bounding sphere for a frustum (truncated pyramid). The easiest way is to find the "center" of this pyramid. I got it by calculating the middle point of "the center of the near plane" and "the center of the far plane". The radius will be the length between this middle point and one of the vertices of the far plane. This works however, this is not an optimal bounding sphere for frustum. I sat down and tried to figure out this problem. It turns out there is a simple way of doing this. Since the frustum is created with perspective projection in mind, this frustum is symmetrical. Furthermore, if we temporarily forget about the aspect ratio, the problem can be reduced into 2D problem: " Given an isosceles trapezoid, find the circumscribed circle ". I got the image from http://mathcentral.uregina.ca/QQ/database/QQ.09.09/h/abby1.html. The first thing to realize is that the center of the enclosing circle is the inters...

Generating Alternating 0 and 1

Once upon a time, a friend of mine gave some of us a challenge. It's not exactly the same but quite similar ;) Anyway, think of ways you can generate alternating 0 and 1. If you have an Update() loop, the first time you call update it will generate 0 and the next time will be 1, and then 0,1,0,1,.. you get the idea. I found 3 ways to do this (assuming initial value of i is 0). Math + Bit i = (i+1) & 1; // You might think of this i = (i+1) % 2. Simple Math i = 1 - i; Bits Operations i = i ^ 1; Can you come up with more ways?

Avoiding Branch in Shader

Depending on which platform and target hardware, it can be a good idea to eliminate branches in shader. Here's two techniques with samples. Lerp Lerp, a.k.a. linear interpolation, is a useful function to select between two things. If you have two vectors v1, v2 and you want to select one of them based on some condition, lerp can be used. Make sure that the result of the condition (conditionMask)  is always 0 or 1.  You can then do this: result = lerp(v1, v2, conditionMask); If your condition is 0, it will return v1. If your condition is 1, it will return v2. Min/Max Min and max is very useful in some cases. For example, let say you want to have one shader to switch between lit and not-lit. Typically, we will multiply the lighting value with color. For instance: light = CalcLighting(); color *= light; So, the condition would be, if there's no lighting return 1; otherwise return the lighting value. We can easily do this with Lerp. light = lerp(1, CalcLighting(), isLi...

Simple XML parsing with Python

There are many ways to read/parse XML with Python.  I found at least 2 methods: DOM and SAX. Document Object Model (DOM) is a cross-language API from W3C for accessing or modifying XML; whereas SAX stands for Simple API for XML. Most of the time, we don't need to understand the whole XML vocabularies; and most of the time we want to parse simple stuff like: <root> <person name="somebody"></person> <person name="otherguy"></person> </root> I think the simplest way to go is to use python minidom implementation that looks like this: from xml.dom import minidom # parse the xml theXml = minidom.parse('data.xml') # iterate through the root rootList = theXml.getElementsByTagName('root') for root in rootList: # you can get the element name by: root.localName # iterate through person personList = root.getElementsByTagName('person') for person in personList: # get the att...

C# BitConverter

Missing the flexibility of C/C++ way in interpreting bits? In C/C++, you can reinterpret the bits by simply casting it. For example if you have an int and you want to reinterpret it as float , you can do the following: int i = 1234; float f = *( (float*) &i ); The question is how can we do this in C#? It turns out there's a class in C# to do this. Meet BitConverter class. int i = 1234; float f = BitConverter.ToSingle( BitConverter.GetBytes(i), 0 ); With this class, you can reinterpret bits from primitive data types. Which should be enough. The only problem is that the class is not suitable to be called every frames. Why? Using Reflector.NET, you can easily tell that BitConverter.GetBytes() is actually allocating memory! public static unsafe byte[] GetBytes(int value) { byte[] buffer = new byte[4]; fixed (byte* numRef = buffer) { *((int*) numRef) = value; } return buffer; } One solution is just to keep in mind not to call this every frame....

BASH: Reading Text File

BASH for C programmers: Read a text file word-by-word in BASH: #!/bin/bash for WORD in `cat filename` do echo $WORD done Read a text file line-by-line in BASH: #!/bin/bash while read LINE do echo $LINE done < filename Looping in BASH: i=0 while [ $i -lt 10 ] do echo $i # next i=$(($i+1)) done Update : another way to loop suggested in the comment.