Sign in to follow this  
greenpig83

Soft filtering edge of tilebase Terrain

Recommended Posts

greenpig83    330
Hi , I'm learning about tile base map with elevation(height).
I succeed in render the map with diamonded tile, or using Ortho-isometric View to make square tile become diamonded (There are 2 methods, the first is mostly use 2d tile texture)!

My current test is like this (2nd Method) (The lighting is a bit wrong, but the biggest problem is the edge) :
sc1_zps54009253.png
So I move to the next level with height. I referenced this, and so wonder how can they do it! what is the technique!
59b001bf-567f-4945-a68a-bd04dbaf03ed.jpg

368f69dd-3b47-4e18-95a8-c4813a7be783.jpg

a73e9c6c-4e4b-4cf0-aae6-bc66480f7ab6.jpg

In the old game, I think they dont use texture like this, but draw everything in 2D and add the light shading that make it looked 3d. In this HD version, i think they move all the terrain to full HD, so we can see the wireframe. So what I really want to know is how to achieve this, or what is the technique behind this achievement. I assume that they try to interpolate 1 poly into many small poly for smoothment, but that will reduce the performance, and anyhow i dont know which algrorith let us do this interpolation. Thanks all. Edited by greenpig83

Share this post


Link to post
Share on other sites
phil_t    8084

It doesn't look like there is any LOD here. It's probably just one vertex per point in the height map. Then they triangulate each square along the line between the two vertices that differ least in height.

Share this post


Link to post
Share on other sites
greenpig83    330

LOD you mean Level of Detail. Havent work with LOD before, so I will spend some time research it. So now you mention HeightMap, and I saw many ppl use it for terrain. I will try to make a demo with heightmap. I hope I can get the result I want. I'll post the result right after I finish it . Thanks .

 

FurtherMore, in the note of the game Development Diary. They say the use "Soft filtering and noise for terrain lighting ', but I don't really understand what it means. This is a specific technique ?

Edited by greenpig83

Share this post


Link to post
Share on other sites
phil_t    8084
I only mentioned LOD because you said "I assume that they try to interpolate 1 poly into many small poly for smoothment". For this type of overhead view, you don't need to bother with LOD, since the terrain is all roughly the same distance from the camera.

"Soft filtering and noise for terrain lighting" -> I don't know what this is either. It just sounds like a bunch of buzzwords put in a sentence. It's difficult to say without more context. Do you have a link? Edited by phil_t

Share this post


Link to post
Share on other sites
greenpig83    330

I only mentioned LOD because you said "I assume that they try to interpolate 1 poly into many small poly for smoothment". For this type of overhead view, you don't need to bother with LOD, since the terrain is all roughly the same distance from the camera.

"Soft filtering and noise for terrain lighting" -> I don't know what this is either. It just sounds like a bunch of buzzwords put in a sentence. It's difficult to say without more context. Do you have a link?

Yes , here is the link. Thanks for the answer.  http://www.ageofempires.com/age2.html  (search for noise)

I'm working with the heightMap solution now. Divide each tile into smaller one. assign the height of it.  Render all of them together.

Trying use this : http://www.nfostergames.com/lessons/TerrainSmoothing.htm  for smoothing. But the result is quite different from what I expected. It only smooth surround the elevated tile. Not the tiles surround it. 

Maybe I understand the algorith wrong, or fail to apply!

 

sc2_zps63b63cbc.png

Edited by greenpig83

Share this post


Link to post
Share on other sites
phil_t    8084

Thanks for the link. Addicted to this game currently!

 

The noise they are referring to is probably a perlin noise texture that is used to determine which of two textures to sample from in the pixel shader. If you look at the grass closely it looks "randomly patchy". So it's likely two textures, and a third texture (the perlin noise) is used to determine how much from each of the two source textures is used in the final output. This is usually referred to as multitexturing.

 

The soft filtering, I'm guessing, refers to the smooth transition from grass to dirt (or whatever) along the tile edges. This is yet another level of multi-texturing, probably using another "mask" texture that has different "shapes" in it for the different neighbouring patterns of tiles (instead of the noise texture).

Share this post


Link to post
Share on other sites
phil_t    8084

Trying use this : http://www.nfostergames.com/lessons/TerrainSmoothing.htm  for smoothing. But the result is quite different from what I expected. It only smooth surround the elevated tile. Not the tiles surround it. 

 

It looks like you need to do multiple passes in order to get the smoothing to "spread out" farther.

Share this post


Link to post
Share on other sites
greenpig83    330

sc3_zps409c0a2e.png

 

sc4_zpsaaa61249.png

 

 

Here the result that I work with HeightMap (not really HeightMap, i dont use any gray image for height or anything. But I think it's the same in idea, cause I have a NxM height map )

Searching all day for a good example of B-Sline surface, Bezier surface, CoxDeBoor algorithm, NURBS... Hard to find an an easy example work for this case. Most of them the surface not going through the control point. In this case I want my surface to go through the Points. So I decide to go the no-brain way, draw a curves n*(n*n) curve throught points in the map. And it does work as I expected. However with those triangle, I think it will hit the performance a lot (The demo now run at 44 fps, ofcourse there is no optimize at the moment, but my Comp can run Crysis 3 at 60fps ) . Because I will have to render hundred of tile on screen. 

 

For the curve I use D3DXVec3CatmullRom to create a curve go through 4 control points.

Edited by greenpig83

Share this post


Link to post
Share on other sites
greenpig83    330

Thanks for the link. Addicted to this game currently!

 

The noise they are referring to is probably a perlin noise texture that is used to determine which of two textures to sample from in the pixel shader. If you look at the grass closely it looks "randomly patchy". So it's likely two textures, and a third texture (the perlin noise) is used to determine how much from each of the two source textures is used in the final output. This is usually referred to as multitexturing.

 

The soft filtering, I'm guessing, refers to the smooth transition from grass to dirt (or whatever) along the tile edges. This is yet another level of multi-texturing, probably using another "mask" texture that has different "shapes" in it for the different neighbouring patterns of tiles (instead of the noise texture).

 

I know about perlin noise, it used to create natural thing like cloudy, grass, fire... even generate random Map. So i think it has nothing to do with smooth.

About the smooth transitions between tiles, It's about blending , and there are tons of artile about it, so I thinks it's not very hard. After working with smooth edge, I'll move to the blending issue. I think it will be alot easier than softing this edge. 

 

Anyway, I'm still not sure this is the best approach, I think there will be a better (in performance, or visual quality). So if any one can enlight me, I will really appreciate it. I will post anything that I found here. 

Edited by greenpig83

Share this post


Link to post
Share on other sites
Auskennfuchs    1032

How do you calculate the normals for your quads? Just inside the quad or with corresponding neighbours? Your first screen looks like first option.

When you calculate a normal for one heightmap point by all 4 triangles, which use the same point, you should get a smooth shading.

 

*---*
|\ /|
| P |
|/ \|
*---*

Share this post


Link to post
Share on other sites
phil_t    8084

Auskennfuchs has a good point. The level of triangulation you're doing isn't really necessary to get a smooth looking surface - instead, proper normals and lighting will go a long way towards getting the right look. Here's what my terrain looks like, with a fairly coarse triangulation shown below:

 

 

grid.jpg

 

 

 

If you're interested, I have a bunch of posts on how I do my terrain:

http://mtnphil.wordpress.com/2012/10/15/terrain-triangulation-summary/

(At the end of that article there are links to part 1 through 5).

Share this post


Link to post
Share on other sites
greenpig83    330

How do you calculate the normals for your quads? Just inside the quad or with corresponding neighbours? Your first screen looks like first option.

When you calculate a normal for one heightmap point by all 4 triangles, which use the same point, you should get a smooth shading.

 

*---*
|\ /|
| P |
|/ \|
*---*

First Screen shot the light is wrong at some tile (left corner). I think I have some wrong in the vertex -> so the Normal get wrong. Or maybe there is no Shadow setup, so that tile still get more light ?

Because after Smooth,I still use the same Normal Calculating way ( I use only in side the Quad, multy 2 vector, using neibour call Phong shading ? ) . And most of the quad look right with light.

 

Now I'm trying to recalculate the light factor by Code (To do a lightMap demo, Try to precalculate the Light mask, so I can apply Light without using 3D for low Spec System). Using vector and Light direction.. But Somehow I cant get the same light  with DirectX (Use Normal inside Vertex and enable Light, the LIght now is ...) . Maybe inside DirectX FrameWork they added some thing, not just  like in this Tutorial : http://ogldev.atspace.co.uk/www/tutorial18/tutorial18.html

 

 

Light.Type = D3DLIGHT_DIRECTIONAL;
 
//Light.Position=D3DXVECTOR3(-1232.0f,960.0f,2.0f);
 
Light.Diffuse.r = 1.0f;
Light.Diffuse.g = 1.0f;
Light.Diffuse.b = 1.0f;
 
//0.2f, -0.9f, -0.2f
Light.Direction.x = 1.0f;
Light.Direction.y = 1.0f;
Light.Direction.z = 1.0f;
Edited by greenpig83

Share this post


Link to post
Share on other sites
greenpig83    330

Auskennfuchs has a good point. The level of triangulation you're doing isn't really necessary to get a smooth looking surface - instead, proper normals and lighting will go a long way towards getting the right look. Here's what my terrain looks like, with a fairly coarse triangulation shown below:

 

 

If you're interested, I have a bunch of posts on how I do my terrain:

http://mtnphil.wordpress.com/2012/10/15/terrain-triangulation-summary/

(At the end of that article there are links to part 1 through 5).

Yeah I remember that now. I used to study Phong Shading with Pascal(very long time ago). There no need of too many triangle to make surface look good. The shading can make it somehow. But we still need enough triangle right ! Like in my first ScreenShot, there no way Shading can make it look smooth ? In my smoothed version ScreenShot above. I used LOD=10, I think we can reduce to 3 or 4 and use your shading idea!

Edited by greenpig83

Share this post


Link to post
Share on other sites
phil_t    8084

How are you generating your original terrain? Like, the hill you made - where did that come from? What is your data source? You said you're not using a height map. Did you make it in a modelling program, and now you're trying to smooth it out at runtime? Or is it programmatically generated?

Share this post


Link to post
Share on other sites
Auskennfuchs    1032
I tried to visualize the problem with my poor drawing skills. Your case is the left image. When you combine all 4 normals for the same point the right image should be the result and your terrain gets smooth shading when using N(ormal) x L(ightdirection). Edited by Auskennfuchs

Share this post


Link to post
Share on other sites
greenpig83    330

How are you generating your original terrain? Like, the hill you made - where did that come from? What is your data source? You said you're not using a height map. Did you make it in a modelling program, and now you're trying to smooth it out at runtime? Or is it programmatically generated?

Yeah, in fact I havent thought about the terrain issue yet. Because my purpose is create a tilebase game (just like Age of Empire). because this Simplify a lot of things, like path finding, 2d Sprite Units... So even the terrain is 3D, it's still must look Isometric somehow. If not it's hard to draw your 2d Unit, 2d Building.... So I cant get a free form terrain. It must be tiled and with small elevation like 1->7. If I have 1 tile elevation 7, there muse be 6x6tiles surround it have ele from 1->6.  MoreOver the top of the hill should look flat, 

 

So that in this game, the hill will quite flat, there are some elevation, but not too many. OF couse later when generate Map, we can use perlin noise, or something to create the hill , jungle, lake...  So in my map can be some thing like this 

0 0 1 1 0 0 0

0 1 1 1 1 1 0

0 1 1 0 0 0 0

1 is the elevation, it's like a plateau there, and I just need to smooth the edges!

Sorry for limiting myself to this Platform, because this kind of Game can work with just low spec Comp (no vertext, just draw all 2D sprites). And we can apply beautiful 3d terrain with high spec Comp.

Share this post


Link to post
Share on other sites
Auskennfuchs    1032

Uhm, may be I'm missing something but:

you got your heightmap map[x][y]:

0011000
0111110
0110000

now you can build your normal for every point normal[x][y]

float2 n1 = calcNormal(map[p.x][p.y],map[p.x-1][p.y],map[p.x][p.y-1])
float2 n2 = calcNormal(map[p.x][p.y],map[p.x+1][p.y],map[p.x][p.y-1])
float2 n3 = calcNormal(map[p.x][p.y],map[p.x-1][p.y],map[p.x][p.y+1])
float2 n4 = calcNormal(map[p.x][p.y],map[p.x+1][p.y],map[p.x][p.y+1])

float3 normal[p.x][p.y]=normalize((n1 x n2 x n3 x n4),1.0f)

Now you can build your trianglelist with position and normal and in pixelshader

 

float3 lightVector = -normalize(lightDirection);
float NdL = max(0,dot(normal,lightVector));
float3 diffuseLight = NdL * lightColor.rgb * texColor.rgb;

Edited by Auskennfuchs

Share this post


Link to post
Share on other sites
greenpig83    330

OK here the new test with Vector. It seem you 2 are right. Using Vertext Normal does help smooth the surface a lot!

I havent use any Shader (Cause havent work with it before). I just recalculate the Vextex vector in my Vertext. By Plus all the 4 Normal ( of the 4 surface neighhbour this Vertext). You say multy ??float3 normal[p.x][p.y]=normalize((n1 x n2 x n3 x n4),1.0f)  It seems Plus work right for me. 

Now I still have a Problem, the lighting seem ugly for me, its not bright enough and make good shadow (I means the other side should darker than the side with Light). Even I change the LIght.Direction alot, it's still look very bad. Maybe because of the setting ? I'm using

 

Do you know any setting that look good in this Case, Isometric Ortho projection!  Thanks a lot!

Do you think I need to multy the Vertex Normal with World or Project Matrix ? Right now I just calculate the Normal from original Vertex Position!

 

When I zoom( use world Transform Scale). When I zoom away , it's get lighter a lot. But the portion of Light in each side still the same !

 

g_pd3dDevice->SetRenderState(D3DRS_AMBIENT,RGB(200,100,100));

ZeroMemory(&Light,sizeof(Light));
Light.Type = D3DLIGHT_DIRECTIONAL;
 
//Light.Position=D3DXVECTOR3(-1232.0f,960.0f,2.0f);
 
Light.Diffuse.r = 1.0f;
Light.Diffuse.g = 1.0f;
Light.Diffuse.b = 1.0f;
 
//set light dir
//0.2f, -0.9f, -0.2f
Light.Direction.x = 1.0f;
Light.Direction.y = 0.8f;
Light.Direction.z = 0.0f;
 
//Light.Direction = D3DXVECTOR3(1.0,0.5,0.4);
 
Light.Range = 1000.0f;
 
g_pd3dDevice->SetLight(0,&Light);  //set the light (NEW)
g_pd3dDevice->LightEnable(0,true); //enables the light (NEW)
 
g_pd3dDevice->SetRenderState(D3DRS_LIGHTING, TRUE);
 
g_pd3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
 
g_pd3dDevice->SetRenderState(D3DRS_ZENABLE, FALSE );
 
 
ZeroMemory(&PyramideMaterial,sizeof(PyramideMaterial));
//diffuse color (NEW)
PyramideMaterial.Diffuse.r = 1.0f;
PyramideMaterial.Diffuse.g = 1.0f;
PyramideMaterial.Diffuse.b = 1.0f;
g_pd3dDevice->SetMaterial(&PyramideMaterial); //set light (NEW

 

sc3_zps386ada13.png

 

sc4_zps228f11e0.png

Edited by greenpig83

Share this post


Link to post
Share on other sites
phil_t    8084

Is y up in your world? If so, then your light is coming from beneath the terrain.

Also, you aren't normalizing Light.Direction - is it necessary? (I've never used the FFP, so I'm not sure).

Share this post


Link to post
Share on other sites
greenpig83    330

Is y up in your world? If so, then your light is coming from beneath the terrain.

Also, you aren't normalizing Light.Direction - is it necessary? (I've never used the FFP, so I'm not sure).

No Z is Up. X,Y is the under Surface. I rotate the World arround X pi/4 then around Z pi/3 . To get the isometric screen, square become Diamond tile! It seem DirectX auto normalize the Light direction, I tried 2,0,0 and 1,0,0 it's the same! The Arrow above plane this the Light Vector.

 

I attach the Demo. So if any one see it useful. (The smoothed version with Vertext Normal is bugged, because there are some vector has not been calculated, No optimize applied, may run slow tih high Tesselation or large map ). For those dont know about Directx, you should install Directx9 SDK. and include/lib...

Things I learn from this Demo :

+ Draw mesh (the sphere)

+ Draw vector

+ calculate Normal

+ setup Isometric scene

+ Normal vertex

+ How to divide a rough triangles into smaller one. 

+ Calculate Bezier Surface, NURBS surface , calculate curve go through points.( although all this technique seem not useful at all)

 

W: wireFrame

L : enable Light

I : disable line vector (normal)

Mouse : rotate/zoom/translate

F : default view (isometric)

A : ortho view !

M : smooth (Tesselation)

U : enable Vertex Normal / Quad Normal

Edited by greenpig83

Share this post


Link to post
Share on other sites
Auskennfuchs    1032

For FFP you can have a look at e.g. this site:

http://www.e-reading-lib.org/bookreader.php/143437/Pike_-_DirectX_8_Programming_Tutorial.html

There you can find some example, how to calculate normals and also setup lighting. But today, even with DirectX9 you should give HLSL a try. The FFP is also just emulated by shaders in modern DirectX.

And shading does not depent on view or projection. For directional light it only uses the light direction and the normal for each vertex. The normal is still the same, when you translate or scale the vertex. Just when rotating you have to rotate your normal too.

For a terrain, the position of each vertex shouldn't alter between two frames. So when your shading differs when changing the viewing position you have some influences by transformed vertices.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this