Generating terrain with different textures
Generating terrain with different textures
Hi there,
I would like to build up a terrain from a height map and some textures.
Therefore I´d specify the textures at some heights, let´s say 0, 3, 5. I would say: Water (as ISceneNode*) at 0, gras (just a picture-file) at 3 and snow (just a picture-file) at 5. In the space between I would like to have a smooth transition (I guess that´s hard with the water, so this could be seperated).
All that should be in an ITerrainSceneNode at the end.
Can I do that with Irrlicht? If so, how?
Thanks a lot.
Greetings,
badday
I would like to build up a terrain from a height map and some textures.
Therefore I´d specify the textures at some heights, let´s say 0, 3, 5. I would say: Water (as ISceneNode*) at 0, gras (just a picture-file) at 3 and snow (just a picture-file) at 5. In the space between I would like to have a smooth transition (I guess that´s hard with the water, so this could be seperated).
All that should be in an ITerrainSceneNode at the end.
Can I do that with Irrlicht? If so, how?
Thanks a lot.
Greetings,
badday
yeah you can. the different textures at certain heights can be accomplished with a shader that blends the textures. but integrating a water scenenode into ITerrainSceneNode seams stupid to me bc it doesn't belong there. anyway one drawback is that irrlicht only supports 4 textures currently so you can only have 4 different terrain textures on it. or three when want a detail texture on it as well or two if you want a detail texture for every different underground. another approach would be rendering the terrain several times for every texture once for example.
We're programmers. Programmers are, in their hearts, architects, and the first thing they want to do when they get to a site is to bulldoze the place flat and build something grand. We're not excited by renovation:tinkering,improving,planting flower beds.
-
- Posts: 126
- Joined: Sun Apr 02, 2006 1:21 am
- Location: Canada
Just out of curiosity, if it is so easy to recompile with support for 8 textures (which I think involves changing only the value of a constant?), why do the official builds only support 4?slavik262 wrote:Not if you recompile it. Then it can support up to 8, and recompiling is super easy.Sudi wrote:...irrlicht only supports 4 textures...
Could you just give me an idea how to do that?the different textures at certain heights can be accomplished with a shader that blends the textures
OK, so what I´d like to accomplish is to have water up to a height of x. All over the terrain. So, adding it to the ITerrainSceneNode is out of question, how else could I do that?but integrating a water scenenode into ITerrainSceneNode seams stupid to me
Thanks a lot.
Greetings,
badday
well when the lowest point in your terrain is at Y=0 you just place a water scenenode in theheight you want it.
bc of the shaders. just do some research i am to lazy now to do it for you
bc of the shaders. just do some research i am to lazy now to do it for you
We're programmers. Programmers are, in their hearts, architects, and the first thing they want to do when they get to a site is to bulldoze the place flat and build something grand. We're not excited by renovation:tinkering,improving,planting flower beds.
Well, I did some research before posting, of coure I did. But I just have no idea how to do it (and I don´t know what to look for, shader+irrlicht+multiple+texture wasn´t right). So, first of all, here is how I do the water thing at the moment:
All right, but how can I make water over the hole terrain (at the moment it seems to be just at some positions. I´m really confused how to specify a size, or am I totally wrong?
To the shaders:
I had some look at http://irrlicht.sourceforge.net/docu/example010.html but didn´t get an Idea how to do it. Maybe someone can help me.
Thanks a lot.
Greetings,
badday
Code: Select all
IAnimatedMesh* plane = smgr->addHillPlaneMesh("plane", // Name of mesh
core::dimension2d<f32>(10,10), // Size of a tile of the mesh. (10.0f, 10.0f) would be a good value to start, for example.
core::dimension2d<u32>(100,100), 0, 0, // Specifies how much tiles there will be. If you specifiy for example that a tile has the size (10.0f, 10.0f) and the tileCount is (10,10), than you get a field of 100 tiles which has the dimension 100.0fx100.0f.
core::dimension2d<f32>(0,0), //material
core::dimension2d<f32>(10,10)); //countHills
//mesh, waveheight = 0.5f, wave speed = 350.0f, wave length = 80.0f
ISceneNode* sea = smgr->addWaterSurfaceSceneNode(plane->getMesh(0), 0.5f, 1000.0f, 0.5f);
sea->setMaterialTexture(0, driver->getTexture("../grafik/Planet-Terrain/greysand.png"));
sea->setMaterialTexture(1, driver->getTexture("../grafik/water.png"));
sea->setMaterialFlag(EMF_LIGHTING, true);
sea->setMaterialType(video::EMT_REFLECTION_2_LAYER);
sea->setPosition(core::vector3df(0,2,0));
To the shaders:
I had some look at http://irrlicht.sourceforge.net/docu/example010.html but didn´t get an Idea how to do it. Maybe someone can help me.
Thanks a lot.
Greetings,
badday
ok i guess you want something like this.
this is with hard edges you wanna perform some smothing between the textures. and you probably wanna add lightning...
PS: you will need four textures for it to work.
water.png
grass.png
mud.png
stone.png
screenshot:
this is with hard edges you wanna perform some smothing between the textures. and you probably wanna add lightning...
PS: you will need four textures for it to work.
water.png
grass.png
mud.png
stone.png
screenshot:
Code: Select all
#include "irrlicht.h"
using namespace irr;
class MyShaderCallBack : public video::IShaderConstantSetCallBack
{
public:
virtual void OnSetConstants(video::IMaterialRendererServices* services,
s32 userData)
{
video::IVideoDriver* driver = services->getVideoDriver();
irr::s32 t[] = {0,1,2,3};
services->setVertexShaderConstant("Texture0", (irr::f32*)&t[0], 1);
services->setVertexShaderConstant("Texture1", (irr::f32*)&t[1], 1);
services->setVertexShaderConstant("Texture2", (irr::f32*)&t[2], 1);
services->setVertexShaderConstant("Texture3", (irr::f32*)&t[3], 1);
irr::core::matrix4 mat = driver->getTransform(irr::video::ETS_WORLD);
services->setVertexShaderConstant("WORLD", (irr::f32*)mat.pointer(), 16);
}
};
irr::core::stringc vertexshader = "varying vec4 pos;"
"uniform mat4 WORLD;"
"void main()"
"{"
" gl_TexCoord[0] = gl_MultiTexCoord0;"
" pos = WORLD * gl_Vertex;"
" gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;"
"}"
"";
irr::core::stringc pixelshader = "varying vec4 pos;"
"uniform sampler2D Texture0;"
"uniform sampler2D Texture1;"
"uniform sampler2D Texture2;"
"uniform sampler2D Texture3;"
"void main()"
"{"
" vec4 col0 = texture2D(Texture0, vec2(gl_TexCoord[0]));"
" vec4 col1 = texture2D(Texture1, vec2(gl_TexCoord[0]));"
" vec4 col2 = texture2D(Texture2, vec2(gl_TexCoord[0]));"
" vec4 col3 = texture2D(Texture3, vec2(gl_TexCoord[0]));"
" if (pos.y >= 0 && pos.y < 30)"
" gl_FragColor = col0;"
" else if (pos.y >= 30 && pos.y < 90)"
" gl_FragColor = col1;"
" else if (pos.y >= 90 && pos.y < 160)"
" gl_FragColor = col2;"
" else if (pos.y >= 160)"
" gl_FragColor = col3;"
"}"
"";
int main(void)
{
irr::IrrlichtDevice* device = irr::createDevice(irr::video::EDT_OPENGL);
irr::scene::ISceneManager* smgr = device->getSceneManager();
irr::video::IVideoDriver* driver = device->getVideoDriver();
irr::scene::ICameraSceneNode* cam = smgr->addCameraSceneNodeFPS();
irr::scene::ITerrainSceneNode* terrain = smgr->addTerrainSceneNode("terrain-heightmap.bmp");
irr::s32 Shader = driver->getGPUProgrammingServices()->addHighLevelShaderMaterial(
vertexshader.c_str(), "main", irr::video::EVST_VS_5_0,
pixelshader.c_str(), "main", irr::video::EPST_PS_5_0,
new MyShaderCallBack,
irr::video::EMT_SOLID,
0);
terrain->setMaterialType((irr::video::E_MATERIAL_TYPE)Shader);
terrain->setMaterialTexture(0, driver->getTexture("water.png"));
terrain->setMaterialTexture(1, driver->getTexture("grass.png"));
terrain->setMaterialTexture(2, driver->getTexture("mud.png"));
terrain->setMaterialTexture(3, driver->getTexture("stone.png"));
terrain->setScale(irr::core::vector3df(5,1,5));
printf("Low: %f\n", terrain->getTransformedBoundingBox().MinEdge.Y);
printf("High: %f\n", terrain->getTransformedBoundingBox().MaxEdge.Y);
while (device->run())
{
driver->beginScene();
smgr->drawAll();
driver->endScene();
}
device->drop();
return 0;
}
Last edited by sudi on Sun Sep 05, 2010 5:31 pm, edited 1 time in total.
We're programmers. Programmers are, in their hearts, architects, and the first thing they want to do when they get to a site is to bulldoze the place flat and build something grand. We're not excited by renovation:tinkering,improving,planting flower beds.
Thanks a lot! That was exactly what I was looking for.
There is just one problem: It says that the lowest point is 0.0, the highest one is 255.0. But the height map is used only for the two higest textures.
If I look at the hole thing from the site I can the the following:
2 layers of textures as "stripes" and over them the two higher textures with the height map applied.
Hint: The height map colour range goes from white to black.
I´d be thankful for any advice.
Greetings,
badday
There is just one problem: It says that the lowest point is 0.0, the highest one is 255.0. But the height map is used only for the two higest textures.
If I look at the hole thing from the site I can the the following:
2 layers of textures as "stripes" and over them the two higher textures with the height map applied.
Hint: The height map colour range goes from white to black.
I´d be thankful for any advice.
Greetings,
badday
-
- Posts: 168
- Joined: Sun Feb 04, 2007 3:30 pm
- Location: France
I think you should change something here :
Also please submit a screenshot
Code: Select all
services->setVertexShaderConstant("Texture0", (irr::f32*)&t[0], 1);
services->setVertexShaderConstant("Texture1", (irr::f32*)&t[1], 1);
services->setVertexShaderConstant("Texture2", (irr::f32*)&t[2], 1);
services->setVertexShaderConstant("Texture3", (irr::f32*)&t[3], 1);
I didn´t find a difference with you posted code (?).
Here the screenshot:
Uploaded with ImageShack.us[/img]
Here the screenshot:
Uploaded with ImageShack.us[/img]
-
- Posts: 168
- Joined: Sun Feb 04, 2007 3:30 pm
- Location: France
Sorry I would write "setPixelShaderConstant" instead of setVertexShaderConstant
Looking at you screen shot it seem that one row of edge is undee y=30 and the neighbour one is > 160. So the transition is faster and not smooth enough to remove this strip effect.
Try the heightmap on this webpage for example (http://newbiz.developpez.com/tutoriels/ ... ghtmap.png). And if you can add you heightmap also it's would be easier I think.
Looking at you screen shot it seem that one row of edge is undee y=30 and the neighbour one is > 160. So the transition is faster and not smooth enough to remove this strip effect.
Try the heightmap on this webpage for example (http://newbiz.developpez.com/tutoriels/ ... ghtmap.png). And if you can add you heightmap also it's would be easier I think.
i know of the issues this was just an example how it can be done. and probably only works for my heightmap....
We're programmers. Programmers are, in their hearts, architects, and the first thing they want to do when they get to a site is to bulldoze the place flat and build something grand. We're not excited by renovation:tinkering,improving,planting flower beds.
If there's a way to specify that a variable should be in a particular register in GLSL (which I'm sure there is since it's doable in HLSL), you don't need to do this ever. The textures are automatically set to registers S0 through S7 (the texture registers). Just map your samplers to those registers.Steel Style wrote:I think you should change something here :
Also please submit a screenshotCode: Select all
services->setVertexShaderConstant("Texture0", (irr::f32*)&t[0], 1); services->setVertexShaderConstant("Texture1", (irr::f32*)&t[1], 1); services->setVertexShaderConstant("Texture2", (irr::f32*)&t[2], 1); services->setVertexShaderConstant("Texture3", (irr::f32*)&t[3], 1);