Texture brush for Terrain

You are an experienced programmer and have a problem with the engine, shaders, or advanced effects? Here you'll get answers.
No questions about C++ programming or topics which are answered in the tutorials!
Post Reply
steve81
Posts: 3
Joined: Wed May 23, 2012 8:08 am
Contact:

Texture brush for Terrain

Post by steve81 »

Hello irrlicht world :)

I'm new on this forum and I'm french so... I'm sory for my langage mistakes :/

So, I'm here for a litle problem, I'm actualy on project, I would to make a map editor (Terrain, decoration, unity) and for that I use a Irrlicht and Qt.
After Irrlicht including on a qt windows, and manipulation of heighmap by a brush, I would to use a texture brush on my terain...
After some reshearch on google I have see some suject for this problem but I dont understand how to do^^

I think that I might use shader but if somebody could explain me... he was my hero ^^"

Image

Thank for reading :)
I'm french and I'm sorry for my langage mistakes
http://lescames.atspace.eu/
REDDemon
Developer
Posts: 1044
Joined: Tue Aug 31, 2010 8:06 pm
Location: Genova (Italy)

Re: Texture brush for Terrain

Post by REDDemon »

well. instead of editing hegth you should edit values used for mixing textures (like R,G,B,A). of course you need a shader mixing textures. also fixed pipeline is possible but a little trickie. and we are now in shaders era. Start with some simple tutorials about shaders they' aren't so hard.
Junior Irrlicht Developer.
Real value in social networks is not about "increasing" number of followers, but about getting in touch with Amazing people.
- by Me
Bl00drav3n
Posts: 48
Joined: Sun Apr 22, 2012 11:55 pm
Location: Vienna
Contact:

Re: Texture brush for Terrain

Post by Bl00drav3n »

You could implement texture splatting (http://en.wikipedia.org/wiki/Texture_splatting). With a 4-channel-alphamap you can blend 5 terrain textures together for the final terrain color. In practice you may just use 3 terrain textures because as of Irrlicht 1.7.3 the maximum number of texture units is limited to four (to maintain cross-platform compatibility I guess). In your terraineditor, if you want to paint a grass texture onto a specific location you will just have to change the corresponding alphamap channel's value on that texture coordinate.
When you render the terrain, stretch the alphamap across all vertices and your shader use the alphamap values to blend the terrain-textures together.

Such a shader would look like this (GLSL)

Code: Select all

uniform sampler2D layer0;
uniform sampler2D layer1;
uniform sampler2D layer2;
uniform sampler2D alphamap;
 
void main()
{
        vec4 base = texture2D(layer0, gl_TexCoord[0].st);
        vec4 material1 = texture2D(layer1, gl_TexCoord[0].st);
        vec4 material2 = texture2D(layer2, gl_TexCoord[0].st);
        vec4 blend = texture2D(alphamap, gl_TexCoord[1].st);
 
        gl_FragColor = material2 * blend.g + (1.0-blend.g)*(material1 * blend.r + base * (1.0-blend.r));
}
I am already using this in my current project and it gives nice results:
Image
steve81
Posts: 3
Joined: Wed May 23, 2012 8:08 am
Contact:

Re: Texture brush for Terrain

Post by steve81 »

I'm sorry for the late of my post, but I had exams.
Firstly, Thanks for your help, its very cool :)

ok, so ... I need to learn shader ^^"

@bloodraven: could I see your source code? It look very interresting :)

An other question: It's imposible to use more than 4 textures in same time? That very problematic I guess :/ Do you know if Ogre is better for that?

EDIT:

Ok so If I undersand:

-> here I load the Shader:

Code: Select all

newMaterialType1 = gpu->addHighLevelShaderMaterialFromFiles(
                                vsFileName, "vertexMain", video::EVST_VS_1_1,
                                psFileName, "pixelMain", video::EPST_PS_1_1,
                                mc, video::EMT_SOLID);
-> here I apply the shader:

Code: Select all

node->setMaterialType((video::E_MATERIAL_TYPE)newMaterialType2);
-> but how to apply on a specific area of the terrain?

I think i'm on the bad way, could you explain me how to do?
I'm french and I'm sorry for my langage mistakes
http://lescames.atspace.eu/
Bl00drav3n
Posts: 48
Joined: Sun Apr 22, 2012 11:55 pm
Location: Vienna
Contact:

Re: Texture brush for Terrain

Post by Bl00drav3n »

You should have a look at the solution freetimecoder came up with in this thread: http://irrlicht.sourceforge.net/forum/v ... =9&t=38676
I modified the code a bit (you can see the modifications in my last post). Results look really nice with this. :)

>It's imposible to use more than 4 textures in same time?
Yeah, I think this is because OpenGL/DirectX spec guarantee only a minimum of 4 texture units.

>but how to apply on a specific area of the terrain?
You apply the shader material to the whole of the terrain, you just have to "paint" the alphamaps. That's what you have to code for yourself if you want to use that inside your editor.
steve81
Posts: 3
Joined: Wed May 23, 2012 8:08 am
Contact:

Re: Texture brush for Terrain

Post by steve81 »

Ok!! Thank so much for your source, it would be very useful for me =)

By my side I have made some experimentation, I have try to paint directly on the texture (image) of the terrain and watch the result:

Image
Image

It's a bit disappointing because the texture applyed (the brush) on the map texture have a very low detail ^^
But this code is not lost because I can use it for the painting of the alphamap ! :)

So a big thank for you help blood Raven (diablo?^^)

I just let some function for people who want to deform terrain or drawn on the texture whit a brush:

Code: Select all

 
void QIrrlicht::RaiseTerrainVertex(s32 index, f32 step,int directstep)
{
    scene::IMesh* pMesh = terrain->getMesh();
 
    s32 heightmapWidth = heightmap->getDimension().Width;
    s32 heightmapHeight = heightmap->getDimension().Height;
 
    s32 b;
    for (b=0; b<pMesh->getMeshBufferCount(); ++b){
        scene::IMeshBuffer* pMeshBuffer = pMesh->getMeshBuffer(b);
        // skip mesh buffers that are not the right type
        if (pMeshBuffer->getVertexType() != video::EVT_2TCOORDS) continue;
 
        video::S3DVertex2TCoords* pVertices = (video::S3DVertex2TCoords*)pMeshBuffer->getVertices();
 
        s32 brushWidth = brush->getDimension().Width;
        s32 brushHeight = brush->getDimension().Height;
 
        for(int y = 0; y < brushHeight; y++){
            for(int x = 0; x < brushWidth; x++){
                video::SColor brushPixel = brush->getPixel(x, y);
 
                if((index-(brushWidth/2)-((brushWidth/2)*heightmapWidth) + (x+(y*heightmapWidth))) >= 0)
                {
                    f32 hy = pVertices[index-(brushWidth/2)-((brushWidth/2)*heightmapWidth) + (x+(y*heightmapWidth))].Pos.Y;
                    f32 bp = brushPixel.getRed()/255.0*step;
         
 
                    if(bp > 0 && hy+bp <= 255)
                    {
                        pVertices[index-(brushWidth/2)-((brushWidth/2)*heightmapWidth) + (x+(y*heightmapWidth))].Pos.Y = hy+(bp*directstep);
 
 
                    }
                }
            }
        }
    }
 
    // force terrain render buffer to reload
    terrain->setPosition(terrain->getPosition());
}
 

Code: Select all

void QIrrlicht::textureBrush(s32 x,s32 z,video::IImage* texture)
{
 
 
    s32 brushWidth = brush->getDimension().Width;
    s32 brushHeight = brush->getDimension().Height;
 
    for(int y0 = 0; y0 < brushHeight; y0++){
        for(int x0 = 0; x0 < brushWidth; x0++){
            video::SColor brushPixel = brush->getPixel(x0, y0);
 
 
            f32 bp = brushPixel.getRed()/255.0;
 
 
            if(bp > 0)
            {
                video::SColor brushColor = texture->getPixel(x0,y0);
 
                terrain_texture_0->setPixel(x+x0 -  (brushWidth /2),z+y0 - (brushHeight/2), brushColor);
 
            }
        }
    }
 
 
    // force terrain render
    textuMap = driver->addTexture("terrain_texture_0",terrain_texture_0);
    terrain->setMaterialTexture(0,textuMap);
 
}
I'm french and I'm sorry for my langage mistakes
http://lescames.atspace.eu/
Bl00drav3n
Posts: 48
Joined: Sun Apr 22, 2012 11:55 pm
Location: Vienna
Contact:

Re: Texture brush for Terrain

Post by Bl00drav3n »

Nice, now apply something like a gaussian filter to that brush and it will look awesome. ^^
Glad that I could help - and yes, my nick comes from Diablo 2 ;) (and I know that she's a girl).
Post Reply