U3D Terrain Editor


How did you avoid the repeated texture look for the cliffs?

I found this link. forum.unity3d.com/threads/improv … ng.116509/

I’m not sure if something like that can be implemented.


I didn’t do anything in particular to avoid repetition; the repetition is there if you look closely enough.

Something like what the link you posted is definitely possible, if you’re okay with the additional texture sampling and instruction count. I’m not sure I would advocate the exact method they use, though, of multiplying the detail texture against a larger version of itself. That tends to over-saturate the texture, as in this shot:

Instead, I would think that a simple 50/50 blend (sum them together and multiply by 0.5) would be more appropriate, as it would at least conserve the overall coloration of the texture:

And, of course, the results would vary depending on the texture itself. For instance, that rock texture doesn’t really work that well, but a more “natural” stone texture would probably look pretty good.


So in the interest of procrastinating all of the boring TODO items delineated above, today I went ahead and took a stab at an experiment to implement the texture packing detailed here. My thinking was “if 4 terrain types is the bare minimum I need, then surely 8 types would be even better!” So I wrote a shader (HLSL only for now, I’ll do a GLSL in a little while). This shader implements both the ability to use 8 types (drawn from 2 composite textures each containing 2x2 types) as well as the extra-detail tiling reduction from earlier. It’s a first stab which simply scales the fractional part by 0.5 and adds 0.5 offsets depending on type, so it does nothing to eliminate the 1 pixel wide “border” at texture seams caused by bilinear sampling. That fix should be relatively easy to make, though, and I just wanted to get this going as a proof of concept.

Ideally, I’d like the user to be able to specify which terrain blending scheme they would like to use: 3 types, 4 types or 8 types. I could do a 12 types version (the 8 types actually reduces the number of detail textures by 2, freeing up 2 slots that I could use for another composite texture + blend map) but already it’s getting kind of heavyweight, at least for my modest little machine from Costco. It’s still interactive framerates, though, so I reckon a 12 type shader would be doable at some point. If I find it necessary, that is, because really 8 types is quite a bit and allows for a decent amount of variety.

Anyway, here is a quick screenshot of it in action:


Nice! looks like we have great tool here. 8 or 12 different textures is very much, I wonder if it would be possible to trade of some of the diffuse textures to normal map textures, each one for different type of terrain.


For hughe terrains, 12 textures is not too much. But I would also like to have 12 textures with their corresponding normal maps.


Depending on how many detail textures you want to pack into a single texture, you could probably do 12 detail+normal maps. (AFAIK, anyway. I don’t know about instruction counts.) But holy shit, that would bring my poor compy to its knees.

I could probably pull off 4 detail+4 normal. 8 detail+normal would be pushing it performance-wise for me (again: Costco computer). I am kind of curious now, though. Let me scrap together some detail textures with normal maps and a shader and see how it goes.


So, I did a quick hack version with 8 detail+normal (Crappy Gimp plug-in produced normals, rather than “real” normals, so pardon the shitty appearance.).

It actually doesn’t bring my compy to its knees nearly as bad as I was expecting. However, that bleeding border problem is kind of a tough one. The UDK article wasn’t really lying when they said that this method was fairly limited in where it should be used. There is always going to be some border bleeding at different mip levels, no matter what kind of offset and shrinking you do. The normal mapping only seems to compound the problem in some instances. I could see maybe using separate textures for the detail color and a packed texture for the normal map, though; at least then you wouldn’t get any color bleeding.


I was working on implementing texture array; it has opengl extension support and has good support. If people don’t have that I was going to let them suffer mip map bleeding. I am also going to implement padding fills on my sprite packer.


The fills will be mirror/reverse/copy nearest pixel. With a generous padding and texture lookup offets I was hoping it would be decent.


This little tangent has served as a reminder of why I don’t usually do (or play) games with heightmapped terrains… Getting a good result is pretty tough.


I am pretending to write an rts right now and havn’t gotten the performance out of tilemaps when the camera tilts and to the horizon and picks up all those drawables. The heightmap performed well but I havn’t gotten anywhere near the quality of art from it I want. I do think there is a lot of value for something like this. A newcomer can make a terrain, add a character controller, start running around, and can take joy in it and make further steps in their gamedeving.


Here is another little experiment:

This one simply implements a whole-terrain colormap and a set of 8 detail normal map textures. Painting with a terrain paints random speckles of color into the colormap and blends in detail from the normal maps. It’s not exactly a photorealistic technique, but I think that with good color selection and better normalmaps than these crappy filter-generated things, it could produce some pretty interesting results.


Alright, that was a fun tangent but back to work. I’ve switched back to the original 4-detail no-normal material, since right now it still looks the best without any cracks or seams.

That actually looks like a map I could have fun exploring, I think.

I’ve encountered some occasional bugs in the road tool, so I need to add that onto the TODO list. I’ll probably just move the quad-strip rasterization into C++ anyway, since any kind of “inner loop” construct that does mass data moving (iterating a buffer and setting pixels, etc…) should probably be streamlined. At some point, I might revisit the method for turning a line list into a quadstrip as well, to see if I can smooth out some of the artifacts.

In the road tool, I’ve been using the Green and Blue channels of the mask image as a scratch-pad of sorts, but I might want to rethink that and use dedicated buffer objects based on float instead. Using image channels forces a conversion to unsigned char, so I lose detail when I rasterize the road strips. After I run the road builder, I have to go back with a smooth brush and polish off the stair-steps and sharp edges. I’d probably get much better performance due (given all of the buffer clearing and iterating the tool does) so that will probably be my project for today until I have to go to work.

I’ve been sketching (on paper, old skewl style!) some ideas for the improved UI. If I decide to support the various kinds of materials I have been tinkering with, then I’ll probably want to figure out a way of handling the various types of terrain paint palettes elegantly. If I support the color+detail normals material, then I’ll probably need to do a color chooser UI widget as well.


I know its a bit early to ask this, but there is going to be a binary release? Im having troubles to compile Lua support and cant test this tool in my PCs.


In order to continue with procrastinating the UI polish, I started work on a river builder tool. It is a slight modification of the road builder, one that limits elevation changes so that they only proceed downhill from the start of the waypoint chain. While tweaking and fiddling with it, I ran up against several instances of bugs in the curve tessellation/quadstrip construction code. The curves use cubic spline interpolation to ensure that the curve passes through the control points, but the result of this can sometimes be a little bit dodgy. And when you combine a dodgily constructed curve with a quadstrip production routine, the result (of course) is dodgy quadstrips that can result in some pretty hideous degenerate faces. So in order that I not hit that Execute button on a road/river filter blindly, I constructed a custom geometry widget that shows a preview of the waypoint curve as an alpha-blended strip overlaid with no depth testing on the scene. This way you can tweak the curve until any degeneracy is gone before hitting Execute on a filter. Some images:

This push, I also started moving the curve tessellation and rasterization into C++ for a quite significant speedup. It’s still a relatively heavy operation, especially on a 2049x2049 heightmap, but is much faster than it was before.

Edit: I also did some minor tweaks to the camera to enable you to better see what the terrain is going to look like from ground level:

You can use the Right mouse button to drag the scene, and while the scene is dragging the looked-at point will follow the surface of the terrain with a small vertical offset. Mouse wheel up will zoom in, and you can zoom all the way in then use Middle mouse button to spin the view around, up and down. Zoom back out to get to editing perspective. (editing is still possible in this ‘first person’ view, but difficult due to the cursor following elevation.)

rogerdv: I don’t really want to encumber the git repo with a binary exe, but maybe I can upload one to google drive and share it with you or something. What is your problem with building Lua support, if I might ask?


Lately I’ve been split between a few different projects: working on a game I had sort of laid aside for awhile, playing Divinity: Original Sin, fixing some long-standing issues in the Accidental Noise Library, and working on porting the noise and terrain editing stuff to AngelScript bindings. It might be more appropriate to build this terrain tool for AngelScript, given that the official editor is AS. I don’t really like AS, though, so it’s been slow going.

A couple hours ago, I stumbled across a thread on gamedev.net that reminded me of this terrain texturing technique. I remember seeing this one some years ago and thinking it looked neat. So this morning I put together a quick shader test to see how it works.

Regular blending:

Using the depth blending technique:

Even with throwaway depth channels in the textures (simple noise fractals of varying frequencies), the result looks pretty okay. With correct depth channels, the results can be very nice, much nicer than generic gradient blends. Of course, this technique complicates the texture creation process somewhat, as you now have to create image-appropriate depth maps for the textures. (Of course, if you own CrazyBump then it’s not that big a deal, I understand. I don’t own it, however… yet.) This afternoon, I’ll try to create some better textures in Blender and see how I like it then.

Ooh, an unanticipated benefit of having the depth map in alpha channel means you can get bump-mapping “for free” (some terms and conditions may apply, see store for details) without having to provide a normal map.

Without bump:


Again, the textures are quickies (heightmap from luminance of texture this time around), but even so the effect is fairly nice.


The new texturing technique looks awesome, it makes the terrain look not repeating


Yeah, good work )
Earlier i was trying to run editor but not understand how it must start running.
Or how i’m must merge it with urho master for running.


The project as it stands isn’t really meant to be merged with Urho3D master. Rather, it is set up as a project that uses Urho3D as an external library. The root CMakeLists.txt expects URHO3D_HOME to be set, and will build a stand-alone .EXE much like the vanilla Urho3DPlayer.exe, with some modifications. The modifications are: 1) The inclusion of the stuff in TerrainEdit.cpp as well as the Lua bindings for it in BindTerrainEdit.cpp that expose these utility functions to Lua, and 2) The inclusion of the VM branch of my noise library along with a set of bindings for Lua to make it accessible. Without these modifications it won’t work, so the vanilla Urho3DPlayer.exe is no longer sufficient to run it. I update my Urho3D to head quite frequently, so you’ll probably need to grab the latest from git to use, rather than building against 1.32. (I haven’t tested a build against 1.32 so it might work, it might not.)

Building is done per the docs. Note that Lua support must be enabled. Once built, change to the root directory (the one with CoreData, Data and TerrainEditorData, of course) and execute TEdit.exe LuaScripts/terraineditor.lua. The .exe accepts all of the default command line parameters.

Once running, the program creates a default terrain 2049x2049 with associated blend texture and mask texture. It sets up a rudimentary UI with a toolbar. Choose from Edit Height (to apply elevation), Smooth Height, 8 different Terrains (only 4 enabled for the currently set shader), Edit Mask and Filter. If you choose a brush tool (Edit Height, Smooth, Terrains, Edit Mask) then you are presented with a widget and sliders allowing you to adjust certain parameters.

For Edit Height, you can set Power (strength of the brush applied per update), radius (size), max (maximum elevation value the brush tends toward) and hardness (the “fuzziness” of the brush). Other brushes have similar options. Left click to apply a brush, “painting” with the current tool. The brushes are applied iteratively each update, with the strength set by Power. A lower power results in a more gradual application of the brush. When you are in Edit Height, you can also CTRL+Left Click on the terrain to select the elevation at the cursor.

Brushes are applied at the floating white fuzzy dot cursor. The mouse cursor is projected against the 0 plane, then the white dot is adjusted to the elevation around the projected location. This is necessary, because if you allow terrain editing at the mouse cursor itself then elevation tends to build or grow toward the viewer, making it difficult to build hills that aren’t long, weird globs extending toward the camera unless you spin the camera to directly overhead.

Anything that is not a brush (waypoint adding, height selecting) is done at the mouse cursor itself.

To move the view (panning) you can either move the cursor near the edges of the screen to pan in that direction, or right-click and hold somewhere on the terrain and drag to move. Note that dragging will cause the camera look-at point to track the surface of the terrain. You can zoom in/out using the mouse wheel. Zooming all the way in will place you at an approximate first-person viewpoint so you can see what things look like from the ground. To spin the view, hold the middle mouse button and move up/down to alter pitch, left/right to spin around the view center. Pitch is constrained to +/-89 degrees to keep weirdness from happening if the camera goes fully vertical. Spin is unlimited.

Click on the Filters button to display a list of filters. Filters are scanned from the Bin/TerrainEditFilters folder as Lua scripts. The scripts take a particular format. They simply return a table that has 4 members: name (the display name for the options window), description (a textual description of the filter), options (a table of options) and execute(the function that executes the filter).

You can use the ‘w’ key to add a waypoint and the ‘q’ key to remove a waypoint. After at least 4 waypoints are created, a translucent blue ribbon will appear linking the waypoints as a representation of the Catmull-Rom spline between the knots. The filters Road Builder v2.0 (use this one, rather than v1.0) and River Builder 1.0 require at least 4 waypoints.

Currently, there are only a small handful of rudimentary filters: Cliffify (scan the terrain testing slopes and applying a cliff terrain to steep areas), Perlin Fractal Terrain Types (iterate the terrain and set grass to areas determined by a noise fractal), Generic Perlin Terrain (iterate the terrain, setting heights from a customizable Perlin noise fractal), Road Builder v2.0 (create a road from a list of waypoints) and River Builder 1.0 (create a river bed from waypoints). The remaining filters can be safely ignored. (Some debug stuff, some useless cruft.) Note that the Filter window is a lying bastard. It has a Close button, but that button does nothing. You have to click Filter- on the toolbar again to close the window.

You can take a screenshot using ‘a’. You can quicksave the current terrain with ‘s’ and the current blend texture with ‘d’. You can quickload a previously saved terrain texture with ‘k’ and blend texture with ‘l’.

All of this stuff is testing code. Nothing here is final. Right now, I’m thrashing around with technical stuff rather than usability, so things can/will change all the time. At some point, I WILL do a UI push to clean things up, add widgets for things that need them, etc… But in the meantime, it’s not really user-friendly.

You can choose the Edit Mask brush to apply mask to areas. Masking works as a gradient from 0 to 1. Some filters can have an option to use the mask for applying the filter, meaning that anyplace that is covered by the mask will not be affected by the filter, or will be affected only to a certain degree based on the strength of the mask. Similarly, the editing brushes can elect to use the mask, meaning that the brush will be applied based on the inverse strength of the mask. Mask areas can be cleared by setting the mask Max to 0 and applying the brush. Future iterations will provide support for generating a mask from a region defined by a set of waypoints, from noise fractals, and so forth.


On a large terrain such as 2049x2049, the individual brushes really aren’t all that useful for large features. The radii of the brushes are maxed small to avoid large performance hits while editing. You could probably tweak the radius values in the UI if you like, but the fact remains that when it comes to creating large terrains, hand brushes are non-optimal. My workflow tends to prefer procedural stuff to fill in the meat of a map, and hand-editing for the details. So when I open up the editor and am faced with a new terrain, my first action is usually to go right to Filters->Generic Perlin Terrain to fill in the map with some stuff. Then I’ll use height editing to smooth out and prepare locations for things I might want to add later: castles, houses, and so forth. My next step is usually to place rivers across the terrain, with an eye toward following valleys for a more natural feel. After that, I’ll add roads. The final stage is the cliffify tool to set cliffs. Since Undo functionality is not supported, save often. Note that there is a glitch in the road builder that causes terrain at the first and last endpoints of the quadstrip to be sunken below grade; I usually have to smooth roads out with the smooth brush anyway, but it’s something I’ll have to track down at some point.

I do plan on allowing you to choose from a range of materials for the editor. The bump-mapped and height-scaled shader in the current iteration is a tad heavy-weight for my poor compy, resulting in an average framerate of about 26. (Mostly due to the bump-mapping, which adds a lot of additional texture samples to the shader.) I probably won’t do any shader finalizing until the rumored upcoming refactor of the shader texture ordering is merged into master.


Thank you for detail instructions )
I got it to run. truth on vc2008 were errors associated with std: isnan; std::isinf ; std::ceil - functions(i guess that vs2008 have this fn in other headers and namespaces). so I had to compile both(engine and then your terrain-editor) under vs2013.
On vs2013 project compiles without problems with the last Urho-master.
I play a bit, it’s very cool! But the generators (filters) are very slow, it’s probably because that they are written in the script ?
I have a small question: how to use the saved landscape in Urho-engine? To do this, perhaps we need something extra copy of shaders, materials or something else from tarrain-editor to urho-master ?


It’s slow mostly because it’s using a single core of the CPU to evaluate a noise function that is a combination of 2 6-octave perlin noises across a domain that is 2049x2049 in size. Noise is an ideal candidate for the massive parallelization that GPUs offer, but that is a rabbit hole I have yet to go down.

The isnan, isinf stuff was debug cruft left in there from a time when I was tracking down a bug. I can take it out.

The saved landscape and blend should be usable in vanilla Urho3D TerrainBlend shader, as long as you don’t use the Terrain 4 layer. The vanilla shader only uses 3 detail textures and the RGB channels of the blend texture. Otherwise, you can copy the shader from the TerrainEditData folder. The currently active iteration uses the TerrainEdit.xml material in TerrainEditData/Materials. This material references the technique TerrainBlend4BumpEdit. This technique references the shader TerrainBlend4EditDetailHeight.hlsl (HLSL version only available right now.) It’s kind of a mess at the moment. Once the shader merge happens in master that cadaver has talked about, then I’ll rewrite the shaders (probably as one or two uber shaders with #ifdefs, rather than the current approach of multiple shaders). If you want to use the shader in-game, you can use the TerrainBlend4Bump technique. In the newly updated github, the shader has been updated with #ifdef constructs for the mask texture sampling and blend, so that by simply not defining USEMASKTEXTURE in the technique you can exclude those parts. Similarly with the bumpmapping. If you don’t want the bump mapping, just remove the BUMPMAP defines from the technique definition. (I know that I get a noticeable speedup when I undef the bumpmapping, since bumpmapping adds another2 samples per terrain layer. Also, I modified the bumpmapping in the current git version to do only 2 extra samples per layer instead of the 4 I had previously; you might want to update.)

I do apologize for the messy state of things. Like I said, I’m thrashing around on technical details and usability is still a more distant goal. As a matter of fact, my project for today (kids allowing) is to revisit the 8+ detail texturing I was experimenting with before, to try to eliminate the seam artifacts. I really, really would like to have more than 4 detail textures available, even if bumpmapping on 8 or 12 or 16 of them would make my poor graphics card cry.