U3D Terrain Editor


Can you post a sample project using this?


You have to compile the source and replace the file located at “Data/LuaScripts/terraineditUIOriginal.lua”
(don’t forget to update the bind_anl.cpp and BindTerrainEdit.cpp using tolua++ tool)
PS: here’s the new file, i forgot to edit some lines: pastebin.com/V1dcvuDh
PS2: works everithing except the filters, i could not fix the error :confused:

bind_anl.cpp: pastebin.com/JCtXsF0q
BindTerrainEdit.cpp: pastebin.com/73QQ9Hdr


I’ve updated the project to build with the latest head. I’ve also updated to the latest version of the Accidental Noise Library for the filters. I am currently in the process of performing the long-procrastinated UI updates I had started working on, including proper load/save/new dialogs. I’m also re-working the filters system a bit, to make it easier to use. Note that it has been several months since I worked on it, so I’m currently unaware of which parts are horribly broken. If anyone runs across anything, let me know, and I’ll try to fix as I get reacquainted with the codebase.


That’s good news. Thanks in advance.


I’ve pushed some commits that add basic save/load functionality for the heightmap and the 2 blend maps. Right now, they are disconnected bits accessed via a menu in the upper left corner, since there isn’t as yet any kind of unifying project structure for a terrain. Each button opens a FileSelector to complete the selected operation. At some point, I imagine I’ll implement a project structure that can collect a terrain, its material selection and its blend maps into a single data description that can be loaded and saved, rather than forcing the user to load and save each image (heightmap, blend 1 and blend 2) individually as at present.

There are some bugs. Loading a blend map that is a different dimension from the current can cause a little bit of weirdness. I’m not too interested in tracking that down exactly, since the way I’m handling some things is going to change in the near future.


I’ve been fiddling with the terrain textures a little bit today. In the process, I wrote up a journal entry at my devlog about a process I use to create stony-soil dirt textures for terrain: gamedev.net/blog/33/entry-22 … e-systems/

The technique uses Blender particle systems, and Blender Cycles node setups to facilitate baking AO/displacement/normal from a particle system. If anyone is interested, feel free to check it out. Some of the results can be seen in recent commits of the terrain editor, and the devlog entry contains a link to the .blend file used to generate one of the dirt textures.


I’ve been re-working the filters UI. I added a DropDownList option type to allow selecting from a list of options. To demonstrate it, the Generate Noise Heightmap and Generate Noise Blend Layer filters were added (replacing some earlier filters). The new filters use a drop-down list to select a noise function type for generating a heightmap or a blend layer, respectively.

Image of the filter drop-down selection:

I implemented some performance fixes to speed up the process of generating a heightmap or blend layer map from a noise kernel, eliminating some redundancy and taking advantage of the ANL option USETHREAD in order to use multi-threading during kernel mapping.

I’m still working on how I want to handle file handling: save, load, new. Common sense would dictate that I implement a project structure of sorts, and encapsulate all of the various data (heightmap, blend maps, brush settings, material settings, etc…), so I’m working on a design for that. Also working on designs for the tool bar, and a rework of the brush dialog and the terrain layer selection dialog. (Man, I hate UI development. Hate it.)


A shot showing some of the textures I’ve been creating:


I’ve updated the tri-planar 8-type editing shader to use texture arrays. This eliminates the hackish texture-atlas method, with all its drawbacks, and simplifies the specification of terrain tile sets. Sadly, it doesn’t work for D3D9. I’ve kept the D3D9 path in the HLSL shader for now, though currently there is some stuff in LuaScripts/terraineditor.lua that needs to be un-commented in order to make the D3D9 path work again. And… uh… I actually haven’t tested to see if that path works. But anyway…


I’ve also update the terrain brush UI to allow brush selection based on texture swatches. The brush UI provides a preview pane and a grid of terrain layers to choose from. Here is a shot of the new brush UI:


This doesn’t seem to work with the latest engine again… or at least I can’t get it to work. :frowning:


I can’t either. Is this still updated? It should be merged to master, it’s amazing!


Somebody reminded me that this is still a thing of mine, so I’ve done a few updates.

Added the D3D11 shader. Doesn’t support D3D9; I doubt it ever will, to be honest, since I’d have to go back to a texture atlas for that path.

Started work on allowing to swap out texture layers. Made the thumbnails on the terrain brush widget actually accurate. Generates the thumbnails from selected layers. Allows using a file chooser to pick diffuse and normal textures for a layer.

Terrain layer edit UI supports specifying a layer scale factor for the layer, to allow to make the textures larger or smaller on a given layer.

Some (currently nonfunctional) additions to the terrain brush widget to allow controlling material parameters Smooth Blend, Triplanar, and Normal Mapping. These will eventually allow the user to enable/disable these three aspects of the material at run-time.


This is amazing news! Your terrain shader is amazing. Glad to know you are still working on it. Even though i don’t use the editor, i benefit a lot from it by creating custom masks and using tons of textures.

It looks amazing combined with stuff like World Machine.


I had to double check to make sure I ‘liked’ your post @JTippetts haha. Very nice work!


You should setup a Patreon page or a PayPal donation page. I would love to give some beer money back to you.


My wife tells me I should set up a Patreon, too. She thinks I spend way too much time doing this stuff for free. :smiley:

Here is a shot of my current project:

This is something I’ve been wanting to work on for a long time. The terrain editor embeds the Accidental Noise Library for noise generation, and I’ve wanted to build a visual node-based editor for it for several years now. Decided to finally get started on it. It’s working pretty well so far, though I haven’t built node types for all the functions yet. Eventually, it will hook in to a revised filter system so that you can build node chains then have them output to the heightmap or the terrain blend layers or even the mask layers.

The node graph makes use of some custom UI components, notably the connection slots and the spline links. It’s still a work in progress, though, and I have some refinements planned. As always, the current source can be found in the github repo. Currently, you need to press ‘n’ to open the node window and ‘m’ to close it. It creates an Output node for you. Press Spacebar to open the create node menu. Click the buttons in the menu to create a node of the given type. The window is sized to 2x2 screens worth of space, so you can drag nodes around and pan the window with the left mouse button as needed. Click and drag on output links to make connections. When done, press ‘b’ and it will output the node chain to a 256x256 image in the root folder called ‘noise.png’. Like I said, it’s still very much a work in progress. Once all the function types are implemented, I will start work on the public facing UI for handling node groups and hooking them up to the terrain. Also, if you play around with it, watch out for bugs. Much of the code for generating the noise chain hasn’t been fully tested yet.


I’ve implemented preliminary functionality to map output from a node chain to terrain height, layer blends or masks.

Currently, only the Map, New and Edit buttons actually do anything. But you can click new to create a new node group, Edit to edit the node graph, then click Map Output to open a dialog that allows you to choose some options. The drop-down list lets you choose from Terrain, any of the 8 layers, and any of the 3 masks as target. You can also choose the range to re-map the output to, and you can select to use any of the 3 masks to mask off the output. (Mask selections are ignored when writing to a mask layer.) Clicking Make it happen! will perform the operation.

I’ve also written a routine to generate a cavity map from the heightmap. It is still in testing stage in these shots, but I’ll make it a filter with more flexibility after the wife and I get back from lunch today. The cavity mapper works a lot like a SSAO shader, only implemented in software and operating on the heightmap. You specify a radius size, and it samples random samples around each pixel in the heightmap and tests occlusion, building an occlusion factor for the pixel and writing it to an output buffer. This output buffer can then be used for things such as writing layer blend values:

Combined with an erosion filter (in the works) this can create some interesting terrain variation.

I’ve got projects in process for setting up waypoint groups/spline groups for road and river filters, to make that process a little more flexible. Plus, I’m working on revamping the toolbar to use an actual icon toolbar, and working on the terrain and blend resizing/loading/saving stuff to make it a little better. (It’s fully broken right now, due to a refactor.)

Some notes on graph node generation:

One of the more useful graph nodes is the Fractal node. Supply it with a basis function to use for the octave layers, plus some other parameters, and it generates a layered noise fractal useful for generating terrain. The Accidental Noise Library supplies some functionality to help the process generate some interesting effects. Here is a sample node graph using Fractal:

In this image, a Gradient noise basis is passed through an Abs function then through a Rotate Domain function (which applies a rotation of the input coordinates around an axis). This is set as the Layer input for the fractal. The Angle parameter of the Rotate Domain is fed from a Randomizer node; a Randomizer node randomizes a value from a range based on a given seed.

The way Fractal works is, it iterates over numoctaves, and for each layer it re-seeds the Layer input chain with a new random seed. Re-seeding iterates through the source tree, and overwrites a new random seed for every Seed node in the chain. This re-seeds the Gradient basis and the Randomizer for Angle for each layer, causing each fractal octave layer to generate a different pattern, rotated by a different angle around the vertical axis. This rotation prevents grid-aligned artifacts in the input noise from aligning with/amplifying each other, something that is especially useful for ridged or billow noise.

Any of the inputs can be overridden by attaching a node graph link to the input. This makes it possible to perform some pretty complex functions. You can specify the frequency from a node graph chain, for example, to vary the frequency of the noise fractal based on some input pattern. You can specify as complex a node graph for any input as you desire, limited only by how long you want to sit and wait for it to execute.

Also provided is an Expression node, which evaluates a string expression into a node graph:

In the works is a format to allow saving and loading node graphs. Also, I would like to implement some sort of grouping functionality, to provide the ability to create libraries of node graphs that can be imported into a node graph, and used as a sort of ‘black box’ function. ANL provides a Seeder node that performs similarly to how the Fractal re-seeds its input layer parameter. You can attach the output of a node graph module to any number of Seeder modules, to enable re-using the node graph with different seeds for different tasks.


So I’ve been working on this some more.

Mostly, I’m working on the UI. It’s still a pieced-together mess of prototyping code, but it’s getting better. I’ve added a toolbar now, with check buttons for the various tools:

The tools are: Terrain Settings (where you can save/load/clear and change the size and spacing of the heightmap, the size of the blend layers and masks, etc…), Edit Height, Smooth Height, Edit Layers, Edit Masks, Edit Node Graphs, Edit Splines (still mostly unimplemented), Filters, and Help (TODO: Add a help page.)

I’ve compressed the size of the nodes for the Node Graphs screen as well:

Gives you more efficient use of screen real estate. Have also now implemented all relevant ANL kernel functions.

Introduced a simple Erosion filter to the filters page, and cleaned out the filters that have been superseded by the Graph Nodes or other functionality. And of course I am in the process of doing various other cleanup bits.

I’ve also updated the Readme at the Github repo to provide some instructions and an overview of the tools.


Some recent work on the editor:

Preliminary work on letting the user create custom nodes and save them. As an example:

In this shot, I have set up a node chain to create an island heightmap. The node chain uses a fuzzy disk node, passes it’s output through chained Translate nodes. The Translate nodes use a basic noise fractal to modify the input coordinate, applying domain distortion to the fuzzy disk. The output can be seen in the preview window. I created a small number of constant and seed nodes. The Constant and Seed nodes have edit boxes with which the nodes can be renamed. By tweaking the parameters of these constant/seed nodes, the output of the island generator can be modified.

Once the chain is setup, you can enter a name for the node group and hit Store on the output node, next to the Preview button. This will construct a compound node type from the chain, with named input parameters based on the constants I set up in the initial chain:

This Island node now contains all of the functionality of the earlier graph, condensed down into a single tweakable node. Output the result to the terrain, apply a few erosion, cliff and cavity filters, and see how it looks:

I don’t currently have any good means for saving these nodes. I’ll probably need to write another small UI system for it, to allow saving/loading library nodes, etc… (As if I don’t already have enough unfinished UI stuff sitting around in there, right?)

I did get rid of the big ugly menu of node create buttons, in favor of a more menu-like + button with menu categories:

I have a built-in library category for compound functions I find useful. fuzzydisk is one of these I have already made, which uses a radial function, a radius constant and some math to create a fuzzy disk primitive as a base for islands. Anything stashed using the Store button gets placed in the user category, but at the moment it’s not persistent between sessions. I’ll probably want to start implementing some kind of user or project settings to make some stuff persistent between sessions, as it’s likely that users will want to build their own libraries. For that kind of stuff, I’ll probably want to put a little more thought and design into it.


Nice. The terrain has some fuzzy natural feeling in it, without getting too much overdrawn. Go on.


Unreal Engine default terrain use low-frequency noise textures to remove “tiling”. Have you tried this approach?