Horde3D
http://horde3d.org/forums/

RenderingOrder (1.0.0_Beta5)
http://horde3d.org/forums/viewtopic.php?f=2&t=1554
Page 1 of 1

Author:  JTippetts [ 01.08.2011, 20:15 ]
Post subject:  RenderingOrder (1.0.0_Beta5)

I'm working on converting an existing isometric, orthographically-rendered game over to Horde3D. The existing engine uses pre-rendered sprites with anti-aliased edges, requiring an alpha blend against the background to draw correctly. The pipeline I am using consists so far of two steps: one step draws meshes with material class "Ground" and the next step draws meshes with material class "Wall".

Code:
<!-- Iso Pipeline -->

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


The shader used is very simple as well:

Code:
[[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 various wall pieces are rigidly-cell based; that is, they are derived from the sides of a unit-sized cube, instanced, and transformed into place in a grid pattern. The camera is a basic isometric (rather, dimetric) camera: 30-degree azimuth, 45-degree around Y axis, orthographic projection. It seems straightforward enough, and is a variant of what I have gotten to work in other 3D engines before. However, I'm having the issue that it doesn't actually seem to be sorting the meshes back-to-front. As evidenced by:

Image

(closeup)

Image

You can clearly see halos, where the front wall pieces are drawn before pieces behind them, leaving behind depth in the zbuffer that prevents the back piece pixels from being drawn. Am I misunderstanding the use of the order attribute of DrawGeometry in the pipeline definition? Is there some other way I should be sorting these primitives instead?

Thanks,
Josh

Author:  marciano [ 01.08.2011, 21:33 ]
Post subject:  Re: RenderingOrder (1.0.0_Beta5)

Hi Josh,

basically your usage should be correct. Horde is sorting meshes by distance based on the closest distance to the AABB. You can easily check the rendering order using GPU PerfStudio. As sorting by distance is not used/tested a lot at the moment, there might be some bug though. Setting a breakpoint in SpatialGraph::updateQueues where the sorting is done might be helpful.

Edit: Quickly checking back-to-front sorting in Chicago worked as expected. Is this a single cell or four? Note that sorting is not done on a per-polygon level but only on a mesh level.

Author:  JTippetts [ 02.08.2011, 00:00 ]
Post subject:  Re: RenderingOrder (1.0.0_Beta5)

Okay, thanks for pointing me to where the sorting is done, marciano. That helped me figure out what I was doing wrong. I had my camera set up like so:

Code:
    h3dSetNodeParamI( self.cam, H3DCamera.OrthoI, 1)
     
    local screennodes_x = config.screenwidth / nodescreensize
    local screennodes_y = config.screenheight / nodescreensize
     
    h3dSetNodeParamF( self.cam, H3DCamera.LeftPlaneF, 0, -screennodes_x/2)
    h3dSetNodeParamF( self.cam, H3DCamera.RightPlaneF, 0, screennodes_x/2)
    h3dSetNodeParamF( self.cam, H3DCamera.BottomPlaneF, 0, -screennodes_y/2)
    h3dSetNodeParamF( self.cam, H3DCamera.TopPlaneF, 0, screennodes_y/2)
    h3dSetNodeParamF( self.cam, H3DCamera.NearPlaneF, 0, -30.0)
    h3dSetNodeParamF( self.cam, H3DCamera.FarPlaneF, 0, 30.0)


Doing it like this is useful, since I can simply set the camera node position to the point in the map I want to be centered on the screen, but the sorting in updateQueues doesn't like it when nodes lie behind the camera, since it uses fabs() when calculating the sort key.

I updated the camera so that it is offset in Y to be greater than the maximum node height, and and add an offset to X and Z calculated from the Y value in order to place the camera at the correct location to center the map view.

Thanks for your help. Love this library, by the way. The handle-based API made it an absolute breeze to bind to Lua, and everything seems clean and functional.

Author:  marciano [ 03.08.2011, 21:09 ]
Post subject:  Re: RenderingOrder (1.0.0_Beta5)

Ah, you used a negative near plane. The camera origin is taken as reference point for the distance computation.

The fabs should not be the root of your problem, it just makes sure that the function returns 0 whenever the point is inside the AABB. An undirected distance can never be negative.

JTippetts wrote:
Thanks for your help. Love this library, by the way. The handle-based API made it an absolute breeze to bind to Lua, and everything seems clean and functional.

Thanks, glad to hear that! :)

Page 1 of 1 All times are UTC + 1 hour
Powered by phpBB® Forum Software © phpBB Group
https://www.phpbb.com/