Jump to content

  • Log In with Google      Sign In   
  • Create Account





Building An Isometric Game Using Horde3D (Part 2)

Posted by JTippetts, 01 August 2011 · 2,751 views


Since we're not using the lighting model implemented in the sample shaders included with Horde3D, a lot of the stuff in our environment shaders can go away or be simplified. We also need to write the shaders so that alpha blending is performed. I have to dig into the docs a bit to figure this part out. After digging around for a little bit, I construct a first iteration of a pipeline and a shader. First, the shader:

[[FX]]

sampler2D albedoMap = sampler_state
{
	Address=Clamp;
};

context SOLID
{
	VertexShader = compile GLSL VS_GENERAL;
	PixelShader = compile GLSL FS_GENERAL;
}

context TRANSLUCENT
{
	VertexShader = compile GLSL VS_GENERAL;
	PixelShader = compile GLSL FS_GENERAL;
	BlendMode = Blend;
}


[[VS_GENERAL]]

#include "shaders/utilityLib/vertCommon.glsl"

uniform mat4 viewProjMat;
uniform vec3 viewerPos;
attribute vec3 vertPos;
attribute vec2 texCoords0;

varying vec4 pos, vsPos;
varying vec2 texCoords;

void main(void)
{
	pos = calcWorldPos( vec4( vertPos, 1.0 ) );
	texCoords = vec2( texCoords0.s, 1.0-texCoords0.t );
	gl_Position = viewProjMat * pos;
}

[[FS_GENERAL]]

uniform sampler2D albedoMap;
varying vec4 pos, vsPos;
varying vec2 texCoords;

void main(void)
{
	gl_FragColor = texture2D(albedoMap, texCoords);
}



The shader is really very simple. I set the address mode of the texture sampler to Clamp, to avoid the filtering artifacts I got in the earlier render. Then I set up solid and translucent contexts. The vertex and fragment shaders for each context are the same, I merely change the BlendMode to Blend for translucent geometry. The shaders themselves are pretty much the most basic of texture-mapping shaders. The vertex shader transforms the coordinate, inverts the t component of the texture coords (or else the image will be upside down) and passes through the transformed vertex. The fragment shader merely passes on the texture sample. There is no lighting or other complex calculation going on.

Then, I put together a test pipeline:

<!-- Iso Pipeline -->

<Pipeline>
	<CommandQueue>
		<Stage id="Geometry">
			<ClearTarget depthBuf="true" colBuf0="true" />
			<DrawGeometry context="SOLID" class="Ground" />
			<DrawGeometry context="TRANSLUCENT" class="GroundDecal" order="BACK_TO_FRONT" />
			<DrawGeometry context="TRANSLUCENT" class="Wall" order="BACK_TO_FRONT" />
			<DrawGeometry context="TRANSLUCENT" class="WallDecal" order="BACK_TO_FRONT" />
		</Stage>
	</CommandQueue>
</Pipeline>


Here, I set up 4 stages of drawing. The Ground is drawn first, followed by any partially-transparent ground decals. Then walls, and finally wall decals. The stages beyond Ground have the order parameter set to "BACK_TO_FRONT" which, according to the pipeline documentation, should sort the geometry from back to front before drawing the given stage.

I then have to edit the materials for the assets to point to the new shader, and in the main application I load the new pipeline instead of the pipeline from the Horde3D samples. I also add a class attribute to the Material tag of each material, indicating its class, ie Ground, GroundDecal, Wall or WallDecal. Then I fire it up, build a real quick test level, and see what it looks like.

Attached Image

Uh oh. You see that stuff that's going on in the middle? Here, let me zoom in on it for you:

Attached Image

You remember what I said about certain pixels being assholes? You are seeing them, right now, deep in the midst of assholery. This is exactly what I was talking about.

What is going on here is that the geometry actually isn't being properly sorted. Some walls that are in front of others are being drawn first, so that when those behind walls are drawn, the depth values written by the front walls clip the pixels, resulting in "halo" behavior. This is exactly what isn't supposed to happen, if the geometry is properly rendered back-to-front. So either I have misunderstood the function of the order parameter in the pipeline DrawGeometry element, or the actual sorting isn't working correctly. So, I guess it's time to dig into Horde3D once more and see if I can figure out exactly what is going on.

This is the sort of problem that can lead one to just forego using nicely anti-aliased sprites, and accept a certain amount of "jagginess" in their environment graphics. If simple alpha-testing is used, with no partial transparency, then it doesn't matter if the geometry is sorted or not.

If I can't sort this out, it's not a deal-breaker. My hardware is atypically crappy these days, so I can safely assume that most players would have the ability to do some FSAA to smooth things out. However, the ouchie part would be re-rendering all of GC's assets to eliminate the anti-aliased edges. Perhaps I can just write a script tool to iterate the asset directories and manually process out the blending, rather than re-rendering everything.

Anyway, tune in next time as I see what results I get using non-anti-aliased sprites....



Attached Thumbnails

  • Attached Image
  • Attached Image
  • Attached Image
  • Attached Image
  • Attached Image
  • Attached Image
  • Attached Image





Great post :) Everyone hates assholes!

I've decided to sort blended objects in my project and only have blended objects when its really needed (windows, fires etc.). Though my sorting algorithm is rather crapy. I'll look forward to future posts.
Addendum:

The sorting problem has been... uh.... sorted. I'll detail it further in the next post, but basically it has to do with the way I did the isometric camera. Turns out, the sort in the h3d engine uses the fabs() of the distance, so nodes that fell behind the camera eye point weren't sorted correctly. The fix is to offset the camera upward on Y, then correct the position on X and Z in SetPosition accordingly.

Hi O-san! How's Medieval Story coming along?
Tiny steps - a week at a time, difficult to keep it going when you got a full-time job. Other ways its going okay :)

December 2014 »

S M T W T F S
 123456
78910111213
1415161718 19 20
21222324252627
28293031   
PARTNERS