Terrain holes

btmorex

26-04-2008 09:20:33

Is there any support for holes in a terrain in ETMv2? Or is there planned support for holes in ETLv3?

By holes, I mean a section of a terrain where the triangles/vertices are just missing. This would allow for caves/building with basements via a separate mesh.

Luth

26-04-2008 10:37:53

I don't think ETM can do that currently.

But can't you set the height at a certain area to 0 and place a separate mesh on top of it? Then you should be able to build something cave-like and the groundmap wouldn't be visible in that area. That still leaves you with the problem to texture your ground- and cave-mesh in a way that you do not see the borders where they meet each other.

CABAListic

26-04-2008 11:11:24

There is no support for this, nor is it planned. It wouldn't work with the geomipmapping approach.

btmorex

28-04-2008 02:29:25

But can't you set the height at a certain area to 0 and place a separate mesh on top of it? Then you should be able to build something cave-like and the groundmap wouldn't be visible in that area.

Yes, that's an alternative. It's sort of ugly though. The other thing that occurs to me is that geomipmapping will likely screw this up as well.

Edit: actually, it occurs to me that this only works in the "basement" case. It wouldn't work for a cave in a hillside for example.

That still leaves you with the problem to texture your ground- and cave-mesh in a way that you do not see the borders where they meet each other.

It's very noticeable, no doubt, but most games with terrain engines seem to do it this way. (once you start looking for it it's everywhere)

There is no support for this, nor is it planned. It wouldn't work with the geomipmapping approach.


I see the problem now... although I'm not convinced that it's impossible. I'm going to have try some things out. At the very least, I guess you'd have to pin the vertices on the edge of your hole so that they aren't removed.

CABAListic

28-04-2008 14:50:53

Yes, and that screws the simplicity of the geomipmapping approach, because you can no longer use shared index buffers (and the individual ones would be VERY tedious to generate). However, I don't really see why setting the affected vertices to zero level is not a sensible solution. After all, they won't be visible either way since you set your cave mesh on top.

btmorex

28-04-2008 15:59:20

Yes, and that screws the simplicity of the geomipmapping approach, because you can no longer use shared index buffers (and the individual ones would be VERY tedious to generate). However, I don't really see why setting the affected vertices to zero level is not a sensible solution. After all, they won't be visible either way since you set your cave mesh on top.

Well, setting them to zero doesn't handle the "cave in hillside" problem because I still want the hill to appear above the cave.

Ignoring that for a moment, I still think the geomipmapping will end up not working with the "basement in a building" scenario. Here's a 2-d image of what I mean:



I think as the vertices near the walls of the structure are removed, there will end up being gaps between the basement walls and terrain where there shouldn't be. Obviously in my picture there are only a few vertices, but assuming the walls of the structure only span 1 or 2 vertices to begin with, these gaps are likely to happen.

CABAListic

28-04-2008 16:20:22

Well, but leaving the two lowered vertices out won't fix that, either.
Might be you could use splatting to render some parts of the terrain transparently, instead? This will likely complicate physics, though.

btmorex

28-04-2008 17:03:46

Well, but leaving the two lowered vertices out won't fix that, either.

Yeah. I mean I realize that the lod geomorphing is going to ultimately end up smoothing any terrain features. On the other hand, setting height to 0 to get these basements is introducing a pretty sharp terrain feature that wouldn't otherwise be there.

Might be you could use splatting to render some parts of the terrain transparently, instead? This will likely complicate physics, though.

That's an interesting idea actually. There won't be any geomipmapping with my physics terrain mesh so I don't think removing a section will be too much of a problem. In fact, I can probably just ignore terrain collisions for the affected area (then I don't have to mess with the actual terrain data at all).

That said, the transparent splatting might end up leaking out (after removing some vertices for lod) unless I can get around that with tricky shader code.

CABAListic

28-04-2008 17:51:21

Well, it will have a transition phase between transparent and non-transparent areas, that's usually the main advantage of splatting. In your case, it would be a matter of making the cave walls thick enough to hide that transition.

SongOfTheWeave

30-04-2008 09:08:34

It's semi-easy to put holes in a PhysX heightmap actor (which is what you'd use for the terrain.)

By semi-easy I mean it's very easy to put them there, but you'd need to save a separate "holes map" (in PhysX holes are implemented via the "material" property, which can be set per vertex iirc. Materials can also be used for things like "ice" spots on your terrain where there is less friction etc.)

So, as long as your cave mesh is a physx actor you could just walk straight in beneath the terrain as long as your hole was positioned properly.

Of course, this means that your "walkmesh" (the set of legal positions an object can walk) is no longer a function; for every (x, z) there is one OR MORE y's. So you have to rely on more complex methods of collision detection than just checking the terrain height.

But, if you're already using PhysX, you already have those methods available.

Note: Don't expect implementing the above to be easy. I find PhysX to be the opposite of user friendly. It's fast, it's fully featured, did I mention it's fast? But it's a bugger to decipher how you're supposed to use some parts of it.

pra

05-12-2008 16:11:50

I wanted to try this now, but i seem not to be able to use a transparent splatting texture. it is just white, not transparent.
Do I have to edit the shaders for that?

Anyway, here is the material my code generated:

material ETTerrainMaterialaaaaa-terrain.zip
{
technique
{
pass
{
lighting off
scene_blend alpha_blend
alpha_rejection greater 150

vertex_program_ref ET/Programs/VSLodMorph2
{
}

fragment_program_ref ET/Programs/Splat_2tex
{
param_named splatScaleX float4 20 0 0 0
param_named splatScaleZ float4 20 0 0 0
}

texture_unit
{
texture ETSplattingaaaaa-terrain.zip0
}

texture_unit
{
texture splatting0.png
}

texture_unit
{
texture transparent.png
}
}

pass
{
scene_blend modulate

vertex_program_ref ET/Programs/VSLodMorph2
{
}

fragment_program_ref ET/Programs/PSLighting
{
}

texture_unit
{
texture ETLightmapaaaaa-terrain.zip
}
}

}

technique
{
pass
{
lighting off
scene_blend alpha_blend
alpha_rejection greater 150

vertex_program_ref ET/Programs/VSLodMorph
{
param_named splatScaleX float4 20 0 0 0
param_named splatScaleZ float4 20 0 0 0
}

fragment_program_ref ET/Programs/FallbackSplat_2tex
{
}

texture_unit
{
texture ETSplattingaaaaa-terrain.zip0
}

texture_unit
{
texture splatting0.png
}

texture_unit
{
texture transparent.png
}
}

pass
{
scene_blend modulate

vertex_program_ref ET/Programs/VSLodMorph
{
param_named splatScaleX float4 20 0 0 0
param_named splatScaleZ float4 20 0 0 0
}

fragment_program_ref ET/Programs/PSLighting
{
}

texture_unit
{
texture ETLightmapaaaaa-terrain.zip
}
}

}

}
(level name is appended on some things to make strings unique)
Splat_2tex is:
void main
(
float2 iTexCoord0 : TEXCOORD0,

out float4 oColor : COLOR,

uniform sampler2D covMap1,
uniform sampler2D splat1,
uniform sampler2D splat2,

uniform float splatScaleX,
uniform float splatScaleZ
)
{
float3 cov1 = tex2D(covMap1, iTexCoord0).rgb;

iTexCoord0.x *= splatScaleX;
iTexCoord0.y *= splatScaleZ;

oColor = tex2D(splat1, iTexCoord0) * cov1.x
+ tex2D(splat2, iTexCoord0) * cov1.y;

}

FallbackSplat_2tex:
void main
(
float2 iTexCoord0 : TEXCOORD0,
float2 iTexCoord1 : TEXCOORD1,
float2 iTexCoord2 : TEXCOORD2,
float2 iTexCoord3 : TEXCOORD3,

out float4 oColor : COLOR,

uniform sampler2D covMap,
uniform sampler2D splat1,
uniform sampler2D splat2
)
{
float3 cov = tex2D(covMap, iTexCoord0).rgb;

oColor = tex2D(splat1, iTexCoord1) * cov.x
+ tex2D(splat2, iTexCoord2) * cov.y;
}


I have an idea how to make newton work with this (i'll make a holemap and leave vertices out according to it while generating the collision), but my understanding of textures and materials is limited

SongOfTheWeave

05-12-2008 19:37:13

The first thing I'd check is that your transparent texture image is actually transparent. In other words, that it has alpha channel values greater than the value you chose as the alpha rejection cutoff which is 150.

pra

05-12-2008 21:01:03

yes, it's absolutely opaque.

I also tried removing the other splatting texture (maybe because it has no alpha channel or stuff, ...), no effect.
My Covmaps have no alpha channels, either, if this could be a problem.

edit: hmm, now it works.... i set alpha rejecion to 1 and made a new transparent texture...

pra

06-12-2008 11:42:16

Almost there, but not quite...
It seems that the coverage map coordinates are different from the terrain vertices:


I modified my ogrenewt code, so that it checks the value in the coverage map of the transparent texture, and adds only one triangle if one vertex of the current tile should be a hole, or nothing if at least two are:
int nrOfHoles = 0;
if(texIndex != -1)//means the transparent texture was found in the splatting textures previously, therefore we have holes
{
//this part retrieves the coverage value of the transparent texture at the 4 corners:
//x and z are terrain vertex coordinates, from two for-loops around this code
//| |
//4---3-
//| \ |
//1---2-
//I tried subtracting 1 from the coordinates here, but that just shifted the entire thing in the other direction
//it seems I should subtract 0.5 somehow...
Real v1val = holesCovmap.getColourAt(x,z,0)[channelNr];
Real v2val = holesCovmap.getColourAt(x+1,z,0)[channelNr];
Real v3val = holesCovmap.getColourAt(x+1,z+1,0)[channelNr];
Real v4val = holesCovmap.getColourAt(x,z+1,0)[channelNr];
Real cmpval = 0.01;

if(v1val > cmpval)
nrOfHoles++;
if(v2val > cmpval)
nrOfHoles++;
if(v3val > cmpval)
nrOfHoles++;
if(v4val > cmpval)
nrOfHoles++;
if(nrOfHoles >= 2)//no triangle with 2 or less vertices
continue;
//now the 4 possible triangles:
if(v1val > cmpval)
{
//| |
//4---3-
//| \x|
// ---2-
poly_verts[2] = v2;
poly_verts[1] = v3;
poly_verts[0] = v4;
col->addPoly( poly_verts, 0 );

}
else if(v2val > cmpval)
{
//| |
//4---3-
//|x/ |
//1--- -
poly_verts[2] = v3;
poly_verts[1] = v4;
poly_verts[0] = v1;
col->addPoly( poly_verts, 0 );

}
else if(v3val > cmpval)
{
//| |
//4--- -
//|x\ |
//1---2-
poly_verts[2] = v2;
poly_verts[1] = v4;
poly_verts[0] = v1;
col->addPoly( poly_verts, 0 );

}
else if(v4val > cmpval)
{
//| |
// ---3-
//| /x|
//1---2-
poly_verts[2] = v3;
poly_verts[1] = v1;
poly_verts[0] = v2;
col->addPoly( poly_verts, 0 );

}
}

CABAListic

06-12-2008 12:12:45

Maybe this will help you: Let's assume your terrain has 129x129 vertices which are addressed from (0,0) to (128,128). The vertex at (0,0) has texture coordinates (0, 0) while the vertex at (128,128) has (1,1).

So, for any vertex (x, y) you can calculate its texture coordinate as (x/128, y/128). You now need to map that coordinate into your image which is probably 128x128 pixels in size. So multiply the texture coordinate by 127. Now you can either round the coordinate you get to the nearest integer and use that for a lookup in the image, or you can do a bilinear interpolation which might give you better results.

pra

06-12-2008 12:33:17

hm yes, that sounds logical^^

but for the moment i decided to use the color at (x,z) to decide whenever the entire tile should have collision or not:

i'll try that later...


but now i noticed another thing: the terrain is transparent, but not invisible:

my alpha rejection is now "greater 1", and the png is 100% alpha

SongOfTheWeave

06-12-2008 13:00:09

Are you using any shadowing technique? If so, which?

If you have shadows, unless you've explicitly dealt with this, it will still be treating the "transparent" section as solid. Here's an overview of how to deal with it:

Stencil shadows - You cannot make stencil shadows respect the "transparent" sections of the terrain via this material based approach. You'd have to actually remove the verticies.

Texture shadows - This is your only option with a material based (transparent splatting texture) solution. You won't be able to use any of the default ogre techniques, but I don't think you can use the provided ogre techniques with ETM anyway. But what you'll have to do is render the shadow map (or depth map) in a way that respects your transparent sections. So... you'll have to splat the transparent textures onto the terrain in the shadow map/depth map generation phase at least on the terrain shadow caster material.

----

If the problem in the 2nd picture above isn't caused by the shadow issues I describe above... nothing else comes to mind atm.

[Edit]
I thought of a few more things to say.

First, that looks like it's going to work nicely once you get the kinks worked out.

Second, what do you expect to see in the first picture in the above post through the transparent hole? Is that picture correct(ish)? Is there only the background black below your terrain?

pra

06-12-2008 13:18:57

no, i'm not using any shadows yet...
and I also noticed another thing: after I saved this level and re-loaded it, it looked like this:

the black parts have the color of the background, i made it green and they also turned green. they seem to be the actual borders of the hole, they move as I paint with transparency.



Second, what do you expect to see in the first picture in the above post through the transparent hole? Is that picture correct(ish)? Is there only the background black below your terrain?
yes, just black background

edit: damn!
1. i set alpha rejection to 150 now. now I have pretty sharp borders, and it looks quite good IMHO
2. this black stuff that is visible on the tunnel entrance IS THE SHADOW OF THE MOUNTAIN!
It's the lightmap that does it. SongOfTheWeave, you was kinda right...
see the other side: