Terrain Editor

Announcements and news updates to your projects using Urho3D.
Forum rules
If you have images or videos, you can attach them in the showcase post. Please use small thumbnail as link to original media resources.
When you post in this forum, you have to agree that Urho3D main website as well as the Facebook page have the permission to republish your post with all the related images or videos. The original images must have width larger than 890px for best viewing result in all the supported viewports by main website.

Re: Terrain Editor

PostPosted by JTippetts » 02 Mar 2015, 16:21

Okay, this morning I was able to re-implement the 8-detail texture technique, with bump-mapping, and eliminate the seams. And although there is a noticeable slowdown on my compy, while editing I'm still getting about 26 fps with 2 directional lights. So this is good.

Some years ago, I had bookmarked http://www.gamedev.net/blog/73/entry-16 ... explained/ and ran across it again while browsing my bookmarks a few days ago. It pretty much sums up the method I used today for seam-elimination.

First, I wrote a Lua routine to hand-build the mipmap levels for a composite texture by specifying 4 base textures. I hand build them so that when they are downsampled, I downsample each texture individually then pack them together for the composite, rather than the default behavior of downsampling the packed texture as a whole. This way, when the texture is downsampled it doesn't "bleed" pixels between tile types.

The shader routine described by Ysaneya in the link above then calculates the mip level manually, and adjusts the scaling of the sampled texture area dynamically based on the mip level, rather than fudging it with a constant based on the 0 level pixel size as my previous version was doing. This means that whatever the mip level, the tile area is "shrunk" by one pixel on each border, ensuring that filtering does not occur across tile boundaries. And the seams are gone.

Image

I am quite happy with the result. The one blip I have is that the calculation of blending factors using the local depthmap for each terrain type can sometimes result in "bleeding" of adjacent terrain types into their neighbors. But it is an organic bleeding that looks relatively natural, and is a consequence of the fact that even if a particular terrain type is 0 in the blend map, that terrain type becomes 0+depth in the blend, and if the terrain type's 0+depth is greater than its neighbor's blend+depth then that texture will bleed through. In the shader, I calculate the contribution of a particular detail type as a blend between it and its neighbor, then I calculate the blend between these blended pairs, and yet another blend between these blends of blended pairs (an exponential lerp chain, in other words). So if Type A is first blended with Type B, then anywhere that 0+TypeADepth is greater than TypeBBlend+TypeBDepth will result in a contribution from Type A at that pixel even though TypeABlend was equal to 0. This results in the random-ish scattering of different terrain pixels you can see in the above image, especially at the fringes of a swatch of terrain where its blend value decreases toward 0.

Even with that glitch, though, the terrain looks good to me. I especially like that it gives me no seams now, no matter the view distance.
User avatar
JTippetts
Active user
Active user
 
Posts: 129
Joined: 26 Jan 2014, 23:41
Location: United States

Re: Terrain Editor

PostPosted by JTippetts » 03 Mar 2015, 16:18

I updated the first post to show some of the recent images:

Image
Image
Image

I am really liking that new terrain type blending scheme. Rather than ugly gradual fades from one type to the next you get a nice transition where it seems like stones are covered in grass, grass is growing on dirt, etc... Looks pretty cool, even with these cruddy textures. And it's super nice having 8 terrain types. The scheme could easily be extended to 12 or more, but I'm good with 8 for now.

Did some tweaking on the shader. Turns out, I don't need to manually generate my mipmap levels. The default mip generation works just fine. I've altered the filters to take advantage of the new texturing scheme, and removed some of the cruft. There are still a lot of things I need to do to clean it up, though. But I feel like I am getting to a point where I can start doing that cleanup. I have a pretty good handle on how I want this thing to operate, and I'm pretty happy with this texturing scheme.
User avatar
JTippetts
Active user
Active user
 
Posts: 129
Joined: 26 Jan 2014, 23:41
Location: United States

Re: Terrain Editor

PostPosted by rogerdv » 04 Mar 2015, 20:44

Im getting an error when compilong under linux. I do cmake . and then make:

Code: Select all
roger@gaara ~/projects/U3DTerrainEditor $ make
[ 42%] Built target ANLVM
Scanning dependencies of target TEdit
[ 50%] Building CXX object CMakeFiles/TEdit.dir/bind_anl.cpp.o
In file included from /home/roger/projects/U3DTerrainEditor/bind_anl.cpp:11:0:
/home/roger/projects/Urho3D/include/Urho3D/ThirdParty/toluapp/tolua++.h:45:17: fatal error: lua.h: No such file or directory
 #include "lua.h"
                 ^
compilation terminated.
User avatar
rogerdv
Most active user
Most active user
 
Posts: 251
Joined: 03 Apr 2014, 17:37
Location: Cuba

Re: Terrain Editor

PostPosted by JTippetts » 04 Mar 2015, 21:44

I'm not really the best one to ask for building advice. Especially on Linux, since it's been years since I last used Linux. But for the sake of thoroughness:

1) Make sure URHO3D_HOME is set, and points to the proper location
2) Make sure Lua support is enabled in both this project and the Urho3D library.

Seeing your actual cmake invokation and what defines you specify for both the library and the terrain editor would be a help.
User avatar
JTippetts
Active user
Active user
 
Posts: 129
Joined: 26 Jan 2014, 23:41
Location: United States

Re: Terrain Editor

PostPosted by rogerdv » 04 Mar 2015, 21:54

The variable is set, and Urho3D has Lua support (luajit, actually), the build command is:

Code: Select all
 ~/projects/Urho3D -DURHO3D_64BIT=1 -DURHO3D_SAMPLES=1 -DURHO3D_LUAJIT=1


Do I have to use the Urho build scripts to compile the terrain editor?
User avatar
rogerdv
Most active user
Most active user
 
Posts: 251
Joined: 03 Apr 2014, 17:37
Location: Cuba

Re: Terrain Editor

PostPosted by JTippetts » 05 Mar 2015, 04:24

You need to use the included CMakeLists and pass it the same defines that you pass to build Urho3D.

One note, though, is that I have not yet written any of the shaders for GLSL, so it's not going to work on Linux with OpenGL. That is a project for a future date, I'm afraid.
User avatar
JTippetts
Active user
Active user
 
Posts: 129
Joined: 26 Jan 2014, 23:41
Location: United States

Re: Terrain Editor

PostPosted by devrich » 21 Mar 2015, 15:18

JTippetts wrote:One note, though, is that I have not yet written any of the shaders for GLSL, so it's not going to work on Linux with OpenGL. That is a project for a future date, I'm afraid.


:cry:

Please? *angel smilie goes here *
Don't settle for what someone else made -- upPIC your own [:.:] at: http://DevRich78.com/upPIC
User avatar
devrich
Some active
Some active
 
Posts: 84
Joined: 09 Jan 2015, 07:46
Location: Usa

Re: Terrain Editor

PostPosted by vivienneanthony » 28 Jun 2015, 16:19

Hello,

Does the TerrainBlendEdit xml both hlsl glsl still work for Urho3D 1.40? I at the point where I am mixing the textures to get the cliff texture, etc? The old method isn't working.

This was the old method.


Code: Select all
 /// Set component
    terrainProcedural -> Initialize();
    terrainProcedural -> SetDimensions(DEFAULTSIZE,DEFAULTSIZE);
    terrainProcedural -> SetWorldType(terrainrule.worldtype, terrainrule.subworldtype, terrainrule.sealevel, terrainrule.creationtime);
    terrainProcedural -> SetOctaves(override, octaves,  persistence, octave1,octave2,octave3,octave4,octave5,octave6,octave7,octave8);

    /// Generate Produracel map
    terrain->GenerateProceduralHeightMap(terrainrule);

    Image * producedHeightMapImage = new Image(context_);
    producedHeightMapImage -> SetSize(DEFAULTSIZE+1,DEFAULTSIZE+1, 1, 4);
    producedHeightMapImage -> SetData(terrain->GetData());

    terrain->SetMaterial(cache->GetResource<Material>("Materials/TerrainEdit.xml"));

    /// Get heightmap for texture blend
    Image * terrainHeightMap= new Image(context_);

    terrainHeightMap->SetSize(DEFAULTSIZE+1,DEFAULTSIZE+1,1,4);
    terrainHeightMap ->SetData(terrain -> GetHeightMap () -> GetData());

    terrainHeightMap -> FlipVertical();

    /// Generte image

    /// Define heightmap texture
    int bw=DEFAULTSIZE+1,bh=DEFAULTSIZE+1;

    Texture2D * blendtex=new Texture2D(context_);
    blendtex -> SetNumLevels(1);
    blendtex -> SetSize(0,0,0,TEXTURE_DYNAMIC);
    terrain-> GetMaterial() -> SetTexture(TU_DIFFUSE ,blendtex);

    /// Shared pointer for blend texture
    SharedPtr<Image> blend;
    SharedPtr<Image> blendMap;

    blend = new Image(context_);
    blend -> SetSize(bw,bh,1,4);
    blend -> Clear(Color(1,0,0,0));

    blendMap = new Image(context_);
    blendMap -> SetSize(bw,bh,1,4);
    blendMap -> Clear(Color(0,0,0,0));


    float steep=0.0f;
    float steepforlerp=0.0f;

    /// create blend here
    for(unsigned int x=0; x<bw; x++)
    {
        for(unsigned int y=0; y<bh; y++)
        {

            Color terrainHeightvalue=terrainHeightMap->GetPixel(x,y);

            switch(terrainrule.worldtype)
            {
            case WORLD_DESERT:
            {
                Color currentcolor = blend -> GetPixel(x,y);
                Color resultcolor=currentcolor.Lerp(Color(0.0f,1.0f,0.0f,0.0f), 1.0f);
                blend-> SetPixel(x,y,resultcolor);
            }
            break;
            default:
                /// Compare to sealavel
                if(terrainHeightvalue.r_<terrainrule.sealevel)
                {

                    Color currentcolor = blend -> GetPixel(x,y);

                    //               float mix=1.0f-((float)terrainHeightvalue.r_/terrainrule.sealevel);
                    float mix=(float)terrainHeightvalue.r_/terrainrule.sealevel;

                    float sterpforlerp=cutoff(mix,0.05f,0.040f,false);

                    Color resultcolor=currentcolor.Lerp(Color(0.0f,1.0f,0.0f,0.0f), sterpforlerp);

                    blend-> SetPixel(x,y,resultcolor);

                }
                break;
            }

            /// blend cliff
            Vector2 nworld=Vector2(x/(float)bw, y/(float)bh);
            Vector3 worldvalue=NormalizedToWorld( producedHeightMapImage,terrain,nworld);
            Vector3 normalvalue=terrain->GetNormal(worldvalue);

            steep=1.0f-normalvalue.y_;
            steepforlerp=cutoff(steep,0.05f,0.040f,false);

            Color currentcolor = blend -> GetPixel(x,y);

            int mixfactor=rand()%99;

            float mix=(float)(mixfactor+1)/100;

            // Color resultcolor=currentcolor.Lerp(Color(0,0,mix,1.0f-mix), steepforlerp);
            Color resultcolor=currentcolor.Lerp(Color(0,0,mix,1.0f-mix), steepforlerp);

            blend-> SetPixel(x,y,resultcolor);

        }
    }

    /// Rotate image and assign texture
    blend ->    FlipVertical ();

    environmentbuild_ -> SetTextureMap(blend);

    blendtex ->SetData(blend, true);

    RigidBody* terrainbody = terrainNode->CreateComponent<RigidBody>();

    CollisionShape* terrainshape = terrainNode->CreateComponent<CollisionShape>();

    terrainbody->SetCollisionLayer(1);
    terrainshape->SetTerrain();

    Vector3 position(0.0f,0.0f);
    position.y_ = terrain->GetHeight(position) + 1.0f;

    /// Add node
    manager_->AddGeneratedObject(terrainNode);


    /// Position character
    Node * characternode_ = Existence->scene_->CreateChild("Character");
    characternode_->SetPosition(Vector3(0.0f, position.y_ , 0.0f));

    /// Get the materials
    Material * skyboxMaterial = skybox->GetMaterial();

    /// Change environment
    Existence->GenerateSceneUpdateEnvironment(terrainrule);
    /// Set component
    terrainProcedural -> Initialize();
    terrainProcedural -> SetDimensions(DEFAULTSIZE,DEFAULTSIZE);
    terrainProcedural -> SetWorldType(terrainrule.worldtype, terrainrule.subworldtype, terrainrule.sealevel, terrainrule.creationtime);
    terrainProcedural -> SetOctaves(override, octaves,  persistence, octave1,octave2,octave3,octave4,octave5,octave6,octave7,octave8);

    /// Generate Produracel map
    terrain->GenerateProceduralHeightMap(terrainrule);

    Image * producedHeightMapImage = new Image(context_);
    producedHeightMapImage -> SetSize(DEFAULTSIZE+1,DEFAULTSIZE+1, 1, 4);
    producedHeightMapImage -> SetData(terrain->GetData());

    terrain->SetMaterial(cache->GetResource<Material>("Materials/TerrainEdit.xml"));

    /// Get heightmap for texture blend
    Image * terrainHeightMap= new Image(context_);

    terrainHeightMap->SetSize(DEFAULTSIZE+1,DEFAULTSIZE+1,1,4);
    terrainHeightMap ->SetData(terrain -> GetHeightMap () -> GetData());

    terrainHeightMap -> FlipVertical();

    /// Generte image

    /// Define heightmap texture
    int bw=DEFAULTSIZE+1,bh=DEFAULTSIZE+1;

    Texture2D * blendtex=new Texture2D(context_);
    blendtex -> SetNumLevels(1);
    blendtex -> SetSize(0,0,0,TEXTURE_DYNAMIC);
    terrain-> GetMaterial() -> SetTexture(TU_DIFFUSE ,blendtex);

    /// Shared pointer for blend texture
    SharedPtr<Image> blend;
    SharedPtr<Image> blendMap;

    blend = new Image(context_);
    blend -> SetSize(bw,bh,1,4);
    blend -> Clear(Color(1,0,0,0));

    blendMap = new Image(context_);
    blendMap -> SetSize(bw,bh,1,4);
    blendMap -> Clear(Color(0,0,0,0));


    float steep=0.0f;
    float steepforlerp=0.0f;

    /// create blend here
    for(unsigned int x=0; x<bw; x++)
    {
        for(unsigned int y=0; y<bh; y++)
        {

            Color terrainHeightvalue=terrainHeightMap->GetPixel(x,y);

            switch(terrainrule.worldtype)
            {
            case WORLD_DESERT:
            {
                Color currentcolor = blend -> GetPixel(x,y);
                Color resultcolor=currentcolor.Lerp(Color(0.0f,1.0f,0.0f,0.0f), 1.0f);
                blend-> SetPixel(x,y,resultcolor);
            }
            break;
            default:
                /// Compare to sealavel
                if(terrainHeightvalue.r_<terrainrule.sealevel)
                {

                    Color currentcolor = blend -> GetPixel(x,y);

                    //               float mix=1.0f-((float)terrainHeightvalue.r_/terrainrule.sealevel);
                    float mix=(float)terrainHeightvalue.r_/terrainrule.sealevel;

                    float sterpforlerp=cutoff(mix,0.05f,0.040f,false);

                    Color resultcolor=currentcolor.Lerp(Color(0.0f,1.0f,0.0f,0.0f), sterpforlerp);

                    blend-> SetPixel(x,y,resultcolor);

                }
                break;
            }

            /// blend cliff
            Vector2 nworld=Vector2(x/(float)bw, y/(float)bh);
            Vector3 worldvalue=NormalizedToWorld( producedHeightMapImage,terrain,nworld);
            Vector3 normalvalue=terrain->GetNormal(worldvalue);

            steep=1.0f-normalvalue.y_;
            steepforlerp=cutoff(steep,0.05f,0.040f,false);

            Color currentcolor = blend -> GetPixel(x,y);

            int mixfactor=rand()%99;

            float mix=(float)(mixfactor+1)/100;

            // Color resultcolor=currentcolor.Lerp(Color(0,0,mix,1.0f-mix), steepforlerp);
            Color resultcolor=currentcolor.Lerp(Color(0,0,mix,1.0f-mix), steepforlerp);

            blend-> SetPixel(x,y,resultcolor);

        }
    }

    /// Rotate image and assign texture
    blend ->    FlipVertical ();

    environmentbuild_ -> SetTextureMap(blend);

    blendtex ->SetData(blend, true);

    RigidBody* terrainbody = terrainNode->CreateComponent<RigidBody>();

    CollisionShape* terrainshape = terrainNode->CreateComponent<CollisionShape>();

    terrainbody->SetCollisionLayer(1);
    terrainshape->SetTerrain();

    Vector3 position(0.0f,0.0f);
    position.y_ = terrain->GetHeight(position) + 1.0f;

    /// Add node
    manager_->AddGeneratedObject(terrainNode);


    /// Position character
    Node * characternode_ = Existence->scene_->CreateChild("Character");
    characternode_->SetPosition(Vector3(0.0f, position.y_ , 0.0f));

    /// Get the materials
    Material * skyboxMaterial = skybox->GetMaterial();

    /// Change environment
    Existence->GenerateSceneUpdateEnvironment(terrainrule);
Office Youtube Page -https://www.youtube.com/user/cgprojectsfx
Official Blog -http://cgprojectsfx.wordpress.com/
Official Deviant -http://cgprojectsfx.deviantart.com

Existence Source
https://sourceforge.net/projects/proteusgameengine/files/Existence/
User avatar
vivienneanthony
Have many posts
Have many posts
 
Posts: 546
Joined: 12 May 2014, 13:21
Location: United States

Re: Terrain Editor

PostPosted by Bananaft » 28 Jun 2015, 19:16

whoa, roads looks sexy. Seeing it, I want to drop everything and make another rally game.
User avatar
Bananaft
Active user
Active user
 
Posts: 154
Joined: 26 Nov 2014, 21:53

Re: Terrain Editor

PostPosted by JTippetts » 04 Jul 2015, 16:53

I'm in the process of updating this project (after a long hiatus) to work with the recent updates to Urho3D, including conditionals for D3D11 shaders and GLSL versions of the various terrain shaders.
User avatar
JTippetts
Active user
Active user
 
Posts: 129
Joined: 26 Jan 2014, 23:41
Location: United States

PreviousNext

Return to Showcase

Who is online

Users browsing this forum: No registered users and 1 guest

cron