InputLayout Build-O-Matic – FXO Edition

I'm lacking inspiration for a title picture. Have a platypus.
I’m lacking inspiration for a title picture. Have a platypus.

Or, “How to access the bytecode of a vertex shader in a compiled DirectX Effect file?”

Earlier in the year, looking into symplifying the use of my DirectX library, I have been pointed to a tutorial by Bobby Anguelov, which described in detail how to load your own InputLayout for a shader by using reflection. InputLayouts are usually difficult to implement coherently, without having to hard code them to match each individual shader in the application.

But what this code allows you to do is, in a nutshell, to read the compiled shader bytecode to obtain the input information of the vertex shader. Based on this information, you can automatically set up a suitable InputLayout to bind to the shader.

You can find this tutorial on Bobby’s blog.

This tutorial is indeed very useful, except that my library uses the Effects framework (which Microsoft had the grace of deprecating – FABULOUS!). The Effects framework provides its own implementation of reflection, but nonetheless the process of accessing the shader input is the same as in the tutorial above, using an instance of ID3D11ShaderReflection.

However, what changes is how we obtain the shader bytecode, to create said instance. We need to access it through the framework’s own reflection, by obtaining the description of the pass within the technique we want to build the layout for. From the pass description, we can then obtain the Vertex Shader description, which will provide us with the desired ShaderEffectVariable. Using the ShaderEffectVariable, we create the shader’s description, which contains the shader’s bytecode! 

Here is a snippet which creates an ID3D11ShaderReflection instance from Pass 0 of Technique 0 of an effect. It is probably a lot more demonstrative.


ID3DX11EffectTechnique* currentEffectTechnique = 0;
 D3DX11_PASS_SHADER_DESC passDesc;
 D3DX11_EFFECT_SHADER_DESC shaderDesc;

currentEffectTechnique = m_effect->GetTechniqueByIndex(0);
 currentEffectTechnique->GetPassByIndex(0)->GetVertexShaderDesc(&passDesc);
 passDesc.pShaderVariable->GetShaderDesc(passDesc.ShaderIndex, &shaderDesc);
 ID3D11ShaderReflection* shaderReflection = 0;

if( FAILED(D3DReflect(shaderDesc.pBytecode, shaderDesc.BytecodeLength, IID_ID3D11ShaderReflection, (void**)&shaderReflection)))
 {
 return S_FALSE;
 }

[Although it builds, I haven’t had the chance to test it properly. It should work, but handle with care!]

An Island in a Globe

Where terrible weather IS a feature!
Sometimes, terrible weather can be a feature.

Here it is, the “seasonal island in the globe”. You can see it motion in this video, accompanied by the cheesiest music I had on the top of my mind. I don’t even know why, I’m not even a Final Fantasy fan.

The main (and personal) features include:

  • Entity parenting and transform stacking.
  • Geometry shader particles, with mesh-based generation. Low-poly meshes are used to generate particles, per  around certain areas.
  • Displacement mapping.
  • Multi-pass lighting and shadowing.
  • Mesh reflection (work still in progress).

My initial consideration was a component-based architecture, which I later traded for a more standard, hierarchy-based structure, as many people convinced me it was just overkill. Truth be told,  even without a proper composite pattern, the end result is probably just as much. One feature I dreamt of having was soft particles, but sadly I had to prioritize other aspects for the deadline.

The island follows the cycle of the four seasons, having respectively:

  • Leaves growing in spring.
  • The tree burning in summer.
  • Thick mist masking the island in autumn.
  • Water freezing in winter.
  • A dynamic, directional light used to simulate the sun.
  • Four (optional) spotlights, which show off the multi-pass shadows-lights.

island_1 island_4 island_3 island_2

Okami’d

I just had one of these moments. One of these moments when you think about something, try it out, and it just works. Happy.

As most of you probably know, Okami is one beautiful game, and despite being something else, is one of the late PS2’s finest gems.

If, on the other hand, you do not know Okami, here is a quick refresher.

Pretty.
The game looks like a living, breathing Japanese ink painting.

There are big, dark outlines, billboards, all of it combined with textures which describe their elements using the same black outlines. Adding a few screen-space effects to make the outlines more organic in motion, and you get a jaw-droppingly pretty game.

I recently bought (and played around ten hours) the HD re-release, and I am having a delightful time. But with crisper visuals, some smaller details become more apparent, some small details start being noticeable.

..and this is how I notice Okami’s method of cell-shading. During the PS2 days, there were no shaders, and while there would still be ways to internally displace vertices, there was no such thing as a pixel shader.

An example of the landscape outlines in the game.
An example of the landscape outlines in the game.

Okami’s method of outlining is clever by its simplicity. As I twisted the camera to some angles, I noticed that the large outlines you can see on the cliffs and landscape elements would distort. It is because they are in fact drawn twice. Once as the normal, textured model is drawn, another model, slightly larger, with a fixed colour (in this case, black), is drawn on top of it, with culling faces inversed. What you are seeing as an outline is in fact the inside of another model painted black.

After being intensely in love with this game for many years, this realisation came like a M. Shyamalan plot twist.

But wait, you might ask, pretending to care. Wouldn’t this be very easy to do with shaders? Exactly, and I had a little play with DirectX.

Here is what came out of it (link to video).

As you can probably see in the video, this method causes some visual artefacts when geometry intersects (see below). I cannot think yet of any efficient way around the problem, however it is only a small price to pay for such satisfying results obtained without influence of the pixel shader.

The original model is visible "through" the outlines at intersections.
The original model is visible “through” the outlines at intersections.

However, it is still possible to observe the same kind of artefact in the game itself, when looking at the models carefully.

Kokari's ear goes through the outline.
Kokari’s ear goes through the outline.

But these types of artefacts are not clearly visible in the game, and you would have to pay a lot of attention to spot them. Exception goes to the landscape elements (such as rocks) which do have to intersect with the ground, thus revealing the outlines.

Another thing you might notice from this screenshot is that the outlines are not regular, like in the teapot shader. In fact, in most character models, they are far from being regular. For instance, on Amaterasu’s model, the ear and the stomach outlines are much more prevalent. This goes to show that instead of using vertex displacement for the characters, the team behind Okami might have created its own outline models. It implies more work on modelling, but on the other hand, more artistic liberty in how the outlines look. Namely, the ability to make them larger to emphasize certain parts of a character, or smaller, to hide possible artefacts.

Here is the shader code to render the outlines using a vertex shader. I intentionally left out the texture rendering pass to save some space.


RasterizerState backface {
 FillMode = Solid;
 CullMode = Back;
 FrontCounterClockwise = true;
};

cbuffer OutlineBuffer
{
 float lineLength;
};

VertexPosition Outline3dVS(VertexIn vin) {
 VertexPosition vout;
 float3 position = vin.pos;
 position += vin.normal * lineLength; //Translate the point along its normal
 vout.posH = mul(float4(position, 1.0f), worldViewProj);
 return vout;
}

float4 Outline3dPS(VertexPosition pin) : SV_TARGET
{
 return float4(0,0,0,1); //Black outline
}

technique10 Outline3d {
 pass P1 {
 SetVertexShader( CompileShader( vs_4_0, Outline3dVS() ) );
 SetGeometryShader( NULL );
 SetPixelShader( CompileShader( ps_4_0, Outline3dPS() ) );

 SetRasterizerState( backface );
 SetDepthStencilState(DSSLess, 1);
 SetBlendState(NoBlend, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );
 }
}

Now, many things remain for the render to look really Okami-like, such as distortion of the outline (the outlines are distorted in motion), and screen-space effects, which I hope I will have time to cover at some later time.

Ultimate Garbage Team Space Sheriffs

UGTSS3

Footage of the game can be found here.

This particularly long title stands for a game I developed in my first year for the Imagine Cup.

The game is a side-scrolling shooter featuring a combo mechanic and some mild RPG elements. The player controls a flying recycle bit, exhibiting a proud mustache. Various enemy types will storm from the right, and the player will have to destroy them. When an enemy gets blown into smithereens, it may drop some garbage which the player needs to properly recycle.

The twist is, the player actually controls three separate bins (although just one at once), each with its own unique type of shots. The keys QWE allow to dynamically switch bit and shoot with it.

Collecting garbage with the appropriate type of bin will increase the bin’s experience level, as well as the combo meter. When the experience bar is full, the bin levels up, and its shots become more powerful and varied.

If a bin ever gets hit by enemy fire, it will be incapacitated for a certain period of time, and the combo meter is reset. There is no game over, but this holds an impact on the final score.

At the end of the game, the player gets issued badges for his achievements, based on his score and damage received. One objective of the game is to obtain all badges for all levels.

Main Menu Save Screendamage+ weaponupgrade cheese

Let me show you my reel.

It's quite small, too.
It’s quite small, too.

I have been meaning to do this for more than a year, and it only took a few days of work to get done.

So here they are, the games I made, in glorious 720p. You can watch it at this address, before youtube remove it for the use of a copyrighted song.

Like Rory properly noticed, the 3D pool table is missing. I personally don’t miss it that much.

To make it look like there is more to this article than a link to a youtube video, here are the games and programs appearing on it, in order:

  • It’s Not Safe Outside
  • Logic 0101
  • Pocket Starlight
  • Assault on Glassbraltar
  • Warrior Koalas on Mars
  • Ultimate Garbage Team Space Sheriffs
  • With Fish
  • MazeCraft
  • Globe Island
  • Various personal experiments