• Welcome to World Machine Community. Please login or sign up.
October 16, 2019, 07:30:08 pm


Read the Development Diary for an inside look at World Machine's progress!

Voronoi column heights from heighfield

Started by Beherith, May 11, 2013, 06:15:26 am

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.


I know you are a busy man, but there is one thing that has been bugging me about the voronoi noise generator, And its the fact that I have been tryin to acheive basalt columns ever since WM 1.x, but getting the tops of the columns flat has been impossible.
It would be amazing if Voronoi had another heightfield input, where the heights for each column are sampled from this heightfield, and not assigned at random.

I wish to achieve this basalt effect:

I would happily use the PDK to modify the existing voronoi device code, I just dont wish to recode it from scratch :(
Ive even gone as far as to use an external python script to generate the voronoified heightfields :)


Hi there,

yes, this is something that I"m interested in as well. I will put it on the backlog -- the method you specify is probably the easiest to get up and running and so is a strong candidate. I am particularly interested in the most-general scenario of this effect, which is to say essentially creating soft or hard segmentations of the terrain for further processing or texturing.
-- Stephen Schmitt
- Creator of World Machine


May 12, 2013, 03:57:46 am #2 Last Edit: May 12, 2013, 04:10:35 am by Beherith
Ok, so I took a cell type voronoi and a default perlin hill, and then collected all the pixels that correspond to each segment, and the read the height from the perlin at the geometric center of the segment, then mapped that value onto the whole segment area. Kinda happy :)

Ill share the device once it crashes less :P

EDIT: i think im running into a max stack depth issue when walking around the segments, what can i expect that to be the max?


Ok, nevermind, I set the max stack depth to 2000, cause it was crashing around 4000, and also fixed a but in the stepwise walk algo (no steps backwards) that relies on the assumption that voronoi shapes are convex!


Very nice Beherith!  I'm imagining epic battles taking place on each of those plateaus.  Mini battlefields, each one of them.   :D


If anyone wants to try this, you can download the .dll here:

Please note that it only accepts CONVEX SHAPES (good old voronoi cells are guaranteed to be that, unless you distort them) as a segmentation input.
The primary heightfield input can be anything, and the device is easily maskable as well.

This archive includes the source. The license is the 'do whatever the hell you want with it' license.


Ok, for some reason, if there is a Pillars device in my world machine graph, tiled output does nothing. Any ideas?


Hmm. Does your device work in Layout view?

If not, I suspect you have additional information being carried within the Device class that needs to be copied when a copy of the device is made with doClone().
-- Stephen Schmitt
- Creator of World Machine


Works just superb in layout mode. I just modified the Activate function of the example inverter device in the PDK.
Pastebin Pillars.cpp http://pastebin.com/ftRHmEV9


May 16, 2013, 02:38:14 pm #10 Last Edit: May 16, 2013, 06:20:17 pm by Remnant
Are there any guidelines or prerequisites for preparing a device for tiled builds? Also, could you please move this thread to the plugin subforum? It has grown beyond just a feature request :)


Moved the topic to the plugin forum..

Well, there really shouldn't be any reason why it wouldn't work in a tiled build. I will describe how the tiled build operates which might help:

1) At the start of a tiled build, the DeviceWorld that is the principle container for the instantiated device(s) in question is copied multiple times, with each private copy of the world assigned to a worker thread.

2) The area to be rendered is split up and each builder thread assigned different areas to create -- again, in their own copy of the world.

3) The builders go to work and the results are collected at the outputs and written as temporaries to disk. Your device instances will never be called from more than one thread, but any class-static data or global state must be threadsafe.

4) After all building has finished, the framework combines together the various tiles, doing blending as appropriate to make them mesh together well.

As mentioned this process is very similar to the way the Layout View operates, so if it works in that it should also work in a tiled build. As long as your plugin is well-behaved it should Just Work. (and I didn't see anything in a quick look through your Pillars.cpp that stood out as wrong).

I would double-check that everything is as expected with a simpler plugin device -- for example, double check that the default example Inverter device works as expected in a tiled build, which will quickly start narrowing down possible problem areas.
-- Stephen Schmitt
- Creator of World Machine


Ok, I found the bug; I needed an extra heightfield to store what parts of the input heightfield was already iterated over, and I used RetrieveInput(0,context) twice, hoping that I would get a free heightfield. While this worked fine, it broke tiled building.

Now I added an extra input to the device, but that input is not used, it is only used to mark where the stepwise algo visited already.

How should I use the framework to allocate a heightfield without using new or delete?

HFPointer hf = HF(RetrieveInput(1, context) ); // Use the RetrieveData(),StoreData() pair to get and set your heightfields
HFPointer hf2 = HF(RetrieveInput(0, context) ); // Use the RetrieveData(),StoreData() pair to get and set your heightfields
HFPointer hf3 = HF(RetrieveInput(0, context) ); // WOOHOO FREE HEIGHTFIELD!


May 20, 2013, 06:22:30 pm #13 Last Edit: May 20, 2013, 06:25:41 pm by Remnant
ah -- yes, the Tiled builds operate under memory conservation, so the first RetrieveInput takes permanent posession of the input heightfield so that the second call fails. This would also be the case for a normal build if mem conserv is checked.

To create your own heightfield of the same dimensions as the input, just call:

HFPointer myHF = GetNewHF(context);

or exactly equivalently:

HFPointer myHF = HField::CreateNew(context);

where context is either the BuildContext passed into your Activate function or the PacketContext residing within an existing heightfield (retrieve with hf->getContext()).
-- Stephen Schmitt
- Creator of World Machine



Quote from: Beherith on May 22, 2013, 05:47:22 am
Thanks Remnant, ill post the finished device!

Hi, @Beherith did you finished this device? I'm interested in it.


Quick Reply

With Quick-Reply you can write a post when viewing a topic without loading a new page. You can still use bulletin board code and smileys as you would in a normal post.

Warning: this topic has not been posted in for at least 120 days.
Unless you're sure you want to reply, please consider starting a new topic.

Note: this post will not display until it's been approved by a moderator.

Please leave this box empty:
Type the letters shown in the picture
Listen to the letters / Request another image

Type the letters shown in the picture:

Shortcuts: ALT+S save/post or ALT+P preview