Voronoi column heights from heighfield

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 :frowning:
Ive even gone as far as to use an external python script to generate the voronoified heightfields :slight_smile:

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.

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 :slight_smile:

Ill share the device once it crashes less :stuck_out_tongue:

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. :smiley:

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().

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

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 :slight_smile:

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.

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!

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()).

Thanks Remnant, ill post the finished device!

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

Pretty much finished, only source available though: