With Fish

Image

The game is currently being made into a full-fledged project at the ENJMIN school of game development with a team of four people. New graphics and full network support are on the menu! We are also looking into other forms of motion controls. Kinect-less footage can be found here.

With Fish is a small asynchronous multiplayer game developed for the Three Thing Game Jam 2012 at The University of Hull.

In a peaceful aquarium, a Mr and Mrs Anglerfish are enjoying the good life. That is, until their owner decides to bring them some new friends to play with. Enter the goldfishes, whose sole reason to live is to make the couple’s life a misery.

One player controlling the two angler fishes using Kinect will have to face the invasion of goldfishes, each being controlled by another player on a touch device.

The aim for the goldfishes to enrage (ie, hit, startle, annoy) the anglerfishes until they -literally- explode. The only way for the Kinect player to win the game is to eat them all before this happens.

With various hazards layered amongst the aquarium (notably changing water level and hiding spots), the game turns into a fast paced pursuit as the many players taunt and manipulate the one player on kinect.

 

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!]

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.

Still Alive.

Besides, the cake isn't even a lie.
No. No portal jokes. Get out.

It has been a while since I last wrote on my blog. Which is not entirely true, since I have been writing posts, which I never got to publish thanks to both the amount of university work and my obsession polishing as much as possible. A blog gives me as much time as I want, which is a nice change from the time constraints of game development and coursework. In any case, not much has been happening since the bulldog switch in March. This post is an attempt at proving to the three people who actually read my blog that despite all the recent events, I am still tending it. In the shadows.

So, here is a summary of the upcoming posts, still in the works, that I will hopefully end up publishing.

A retrospective post about the Three Thing Game, which is several thousand words long, about the design process, and several recommendations I would give to people who take part in the competition. I have been a long time at it, mostly rewriting and rewriting, because it is very, very hard to formulate textual advice without sounding like a total self-obsessed idiot.

A tutorial on using shaders to make a 2D laser. As you might have guessed, this goes through the process of making the light beam in our TTG game. Most people in their third year would be familiar with shaders by now, although this covers the shading language found in the PSSuite, which surprisingly looks more like HLSL than GLSL.

An eulogy of genetic algorithms (GAs), to which I caught a liking. I will be describing their basic principles, as well as some the existing implementations of such algorithms in games. Although I am far form being a professional in the subject (I hardly even coded a GA yet!), the revisions for the NEAT module got me back into GAs, and reminded me how amazing they were.

I also have some various post scraps lying around, which will emerge or stay in the shade as hidden monstrosities.

Christophe and the internet.

It seems having your own personal blog has become something quite fashionable lately. I should blindly follow the trend and start my own rants and reviews.

This will provide me with a way of managing my urge to force random people to play games I really like.

Why, seriously. Why?