Jump to content
  • Advertisement

Archived

This topic is now archived and is closed to further replies.

Ilankt

Tiles in 3D?

This topic is 5570 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

well, i got a question, how (in theory) i can make a tiles for an engine like in WC3 or SIMCITY 4? in 2D i know how to do it, but its kind of diffrent in 3D, right? so, any ideas?

Share this post


Link to post
Share on other sites
Advertisement
Ok... it's a bit longer but as I have already done this in a terrain engine (see http://www.sun-a-moon.org/index_proj.htm and there Race Tracks Unlimited)...

first of all you have a regular grid with quads (2 triangles making one quad).
Then you have 2 layer.

The first layer contains the base ground texture for an entire quad. Imagine that you have 4 ground types : sand, rock, grass and mud. You give them an order. ie :

a=rock
b=sand
c=mud
d=grass

your tiles now look like this :


A B C D E
0*---*---*---*---*
| a | b | b | c |
1*---*---*---*---*
| a | c | c | c |
2*---*---*---*---*
| c | c | d | d |
3*---*---*---*---*


As you can see, the grid is regular and there are
always entire tiles with one (1) ground type in it.

Your tiles are then A0->B0->B1->A1 then B0->C0->C1->B1
and so on.

What you need now are the transitions between the different
underground types. It becomes a little bit more complicated
here :

A transition is done from a higher level ground type to a
lower level one. This means that you would draw the transition
from sand to rock but not from rock to sand.

In our example there are a lot of transitions. But let's take
only 2 or 3 :

The first 2 tiles on the upper left side are the tiles A0->B0->B1->A1 then B0->C0->C1->B1 and their contain underground a and
underground b.

Since b is higher level than a, we have to draw a transition in tile A0->B0->B1->A1.

A transition is again done on the entire tile. So we have to draw a tile A0->B0->B1->A1 that encodes the transition. To make a transition, we have to take a look at the corners of the tile and determine whether or not the adjacent tiles influence this one.

The tile is :

A B
*---*
| |
*---*
C D


we have to examine the corner A then B then C then D. We give each corner a bit and encode it into 4 bits : DCBA

We now do following :

Given our tile is at position X, Y we do (for eaxh underground
type != the tile underground) :


count=0
bitfield=0
for each X' = X-1 to X+1
if (X'==0) skip
for each Y' = Y-1 to Y+1
if (Y'==0) skip
if ( count == 0 )
count = 1
else
count << 1

if ( tile(X',Y') != tile underground )
bitfield |=count
end for
end for

in this way we encode for each underground type a bitfield for this type that encodes a value from 0 to 15.

If the value is 0 there is no need to render a tile with that
underground type.

if the value is 15 then the entire tile is covered by that
underground type and you should change the layer 1 underground
type to the current checked one

if the value is != 0 then you have an index to one of 14 textures
(or texture coordinates) that contains the corner GFX. Example


Value 1 :
O---*
| |
*---*

Value 2 :
*---O
| |
*---*

Value 3 :
O---O
| |
*---*

Value 4 :
*---*
| |
*---O

Value 5 :
O---*
| |
*---O

Value 6 :
*---O
| |
*---O

and so on until


Value 14 :
*---O
| |
O---O


You create like this all the tiles you need with the transitions.

I would create 2 textures :

Texture A with the complete tile underground types

Texture B with the transitions encode as mentioned above.

If you use a tiling size of 64x64 pixels then you could create
a Texture A with 512x512 pixels and therefore store 8 different underground types with 8 variations (ie. gras, gras with flower, gras with a stone, etc).

The transition texture would have to be double size (ie. 1024x512) to support the 14 transitions ie along the X Axis and the 8 underground types along the Y Axis.

I hope this helps... don't hesitate to ask if something isn't clear enough...

Metron

[edited by - Metron on June 18, 2003 9:43:23 AM]

Share this post


Link to post
Share on other sites
I think I''ll dig out the source code... that should make it more clear... can''t do it yet... perhaps this evening...

Share this post


Link to post
Share on other sites
I have a question Metron...

What I''m missing from your example is your tiles look like this :


A B C D E
0*---*---*---*---*
| a | b | b | c |
1*---*---*---*---*
| a | c | c | c |
2*---*---*---*---*
| c | c | d | d |
3*---*---*---*---*


If "b" overrides tile "a" in A0,B1, what happens when you get to the "c" that is in B1,C2?

How do you handle cases like for B1,C2 where it is "c" and surrounded by "a", "b" and "d" types? How does the blend work since it seems you have to blend 4 types together to get a smooth transition?

Share this post


Link to post
Share on other sites
Hi again...

I have to make a small correction. It has been some time since I've done it and I took a look at my code and my structures

First of all :

The terrain types aren't stored in the tiles but within the corners of the tile. If a tile is defined like this :


A B
*---*
| |
*---*
D C


then it's only possible to have 4 different terrain underground types per tile.

First some structures :


struct STerrainCorner
{
AR::CMVector3D m_vPosition; // x-y-z position of the corner.
AR::CMVector3D m_vNormal; // normal vector of the corner.
ulong m_uColor; // color of the corner.

ulong m_uTerrainType; // Terrain type of the corner.
};

struct STerrainTile
{
STerrainCorner *m_pCorner[4]; // Maximum 4 corners per tile.
AR::CMVector3D m_vNormal; // normal vector of the tile.
ulong m_uTerrainType; // Dominant type of terrain for this tile.
};


Here now 2 functions. The first one calculates the terrain type dominance for a given tile:



// ----------------------------------------------------------
// Calculate the terrain underground dominance.
void
CTerrain::CalculateTerrainTypeTileDominance(STerrainTile* _pTerrainTile)
{
ASSERT( _pTerrainTile );

ulong uCurCorner;
byte uTerrainType;
byte uDominant = 255;

STerrainCorner** ppCorners = _pTerrainTile->m_pCorner;

// Determine the number of different corners and write them into a list.
for ( uCurCorner=0; uCurCorner<4; uCurCorner++)
{
uTerrainType = ppCorners[uCurCorner]->m_uTerrainType & 0x0f;

if ( uDominant > uTerrainType )
{
uDominant = uTerrainType;
}
}

// Fast case -> All the same.
_pTerrainTile->m_uTerrainType = uDominant;
}


The second one calculates the blending :



// ----------------------------------------------------------
// Calculate the terrain underground dominance.
ARMETHODIMP(ulong)
CTerrain::CalculateTerrainTypeTileBlendings(STerrainTile* pTerrainTile, byte _byTerrainType[4], byte _byBlendIndices[4] )
{
DynArray oDiffTerrains;
byte uTerrainType;
byte uDominant = 255;
ulong uCurCorner, uCurElement;

STerrainCorner** ppCorners = pTerrainTile->m_pCorner;

// Determine the number of different corners and write them into a list.
for ( uCurCorner=0; uCurCorner<4; uCurCorner++)
{
uTerrainType = ppCorners[uCurCorner]->m_uTerrainType & 0x0f;
if ( uDominant > uTerrainType )
{
uDominant = uTerrainType;
}

oDiffTerrains.AddUniqueElement( uTerrainType );
}

// Only 1 then there is no need for blending.
if ( oDiffTerrains.GetNrElements() == 1 )
{
return 0;
}

// Remove the dominant element since this one will not be blendet.
oDiffTerrains.RemoveElement( uDominant );

byte byBlend = 0;
for ( uCurElement=0; uCurElement < oDiffTerrains.GetNrElements(); uCurElement++ )
{
_byBlendIndices[uCurElement] = 0;
for ( uCurCorner=0; uCurCorner<4; uCurCorner++ )
{
byBlend = 1< < uCurCorner;

uTerrainType = ppCorners[uCurCorner]->m_uTerrainType & 0x0f;
if ( uTerrainType == oDiffTerrains[uCurElement] )
{
_byBlendIndices[uCurElement] |= byBlend;
_byTerrainType[uCurElement] = uTerrainType;
}
}

if ( _byBlendIndices[uCurElement] )
_byBlendIndices[uCurElement] -= 1;
}

#pragma todo("Do a dominance sort on the blendings.")

return oDiffTerrains.GetNrElements();
}


I think this also replies to the question Zarmax has. Since the terrain types are defined in the corners and not in the tiles themself the overlapping is done automatically.

But yes, if you have 4 different underground types in one tile then you have multiple blendings (1 normal rendering for the dominant underground (underground with lowest id) and 3 blendings with the other underground types).

Kind regards,
Metron

[edited by - Metron on June 19, 2003 5:07:39 AM]

[edited by - Metron on June 19, 2003 5:08:58 AM]

Share this post


Link to post
Share on other sites
Thanks Metron, good answer.

I was trying something out using mutli-texturing with up to 4 blend stages and driven by a vertex shader to do the blends, you''ve given me a good way to figure out what the blend values need to be. Only problem now is to best figure out how to opimize texture swaps.



Share this post


Link to post
Share on other sites
Well... that can be reduced to 1 swap :

You put all you base underground types and their variation into one texture.
You put all the blending types for the underground types into a second texture.

You then first draw all the complete tiles without blending (using texture #1).
Then you render all the blending tiles with the second texture. Like this you don''t need to swap the texture...

Metron

Share this post


Link to post
Share on other sites
Just wanted to say thanks, you solved a few problems I have been having with texture tiling. I can finally get rid of the one big texture/detail texture method I have been using.

I''ve tried about 4-5 other methods with things like texture splatting, volume textures, multi-texture blends, overlapping textures, etc. I think this tiling method will finally solve the problem.

One enhancement that I was thinking about that would require an additional texture stage would be to use an alpha map for blending instead of vertex blends in that you can do the alpha map at 2 or 3 times the size of the terrain patch and get a smoother blend by adding a little noise to the blend. I may have to try that one out as I already am thinking I need a minimum of three stages for blending, (two tiles + lightmap), so I might as well throw in an alphamap to add a more irregular blend. With a vertex shader I could probably pack the alphamap into the same texture as the lightmap...hmm...

There also might be a nice way to wrap it all up into a vertex shader to cut back on the number of texture coords needed.

Share this post


Link to post
Share on other sites

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!