Simple Grid Scattering with Location, Rotation and Scale Jitter

I made a little grid-based scattering procedure.

It creates a 2D grid on X/Y
then offsets the location, rotation and scale of each vector before placing the asset.

1 Like

Oh thatā€™s lovely. :smiley: So many questions, Iā€™ve like to see the procedures since Iā€™m sure the way you build things (think) is going to be different from me. How are you seeding the randomisation? Could you use the first parameter (frame) to define the area populated, perhaps using the x/y as the spacing instead? Then the bounding rect visualisation would enclose it. Where did you get the lovely trees/grass from? :evergreen_tree: :deciduous_tree:

Itā€™s amazing seeing someone else make stuff with Apparance after all these years of dogfooding it :sob: :heart:

1 Like

Do you have a particular method for sharing Procedures? A repository or something?

I would love to see a library of ā€œcommunity proceduresā€ that people could tap into, and not have to reinvent the wheel every time.

Hereā€™s my step by step:

  1. I generate a list of vectors along the X axis, starting from an origin point

  1. I create I finish the 2D grid, along the Y Axis, using concatenate to output the final list of vectors

3 . I iterate through that list of vectors, placing the Trees, before placing I translate, Rotate and Scale the frame, before placing the object. The random is seeded from the index of the vector on the list.

Back on Starlink we had a function to create a random seed from the world position. I donā€™t quite know what the implementation was though. Would be a good Operator to have, something like (GetSeedFromVector3).

I just notice you canā€™t scale down the procedure area in the graph, after scaling it up.

  1. The final graph that I use in Unreal just puts the Grid Creation and Vector Placement together.

So. Iā€™m very new to this thing and I saw the idea of Frames in the examples map, and I think itā€™s fantastically powerful. But first I wanted to have a look at building things the way I have done in the past.

This is how I would like to take this further.

  1. Rather than using X-Y, use the volume of the frame as the area to be filled with scattered points
  2. Project down and get the normal and material of the landscape, and feedback to the procedure so you can have the objects conform to the landscape, limit placement on high slopes, specific materials, etc.

The trees come from this pack

How about some rocks

1 Like

Sharing procedures, no, the procedure storage is rather monolithic at the moment. It is on the roadmap to support libraries [feature request] that can be shared, referenced, and packed up. Want this for building ā€˜asset packā€™ style procedure collections, e.g. focussed around a particular purpose, e.g. fences, trees, lights, powerlines, wiring, pipework, building facades, cities, etc.

Your technique is really interesting and very different to the way Iā€™d approach it in so many ways :smiley: Again, not wrong, but different. It didnā€™t occur to me that youā€™d use lists at all, and break the process into stages. Iā€™d favour doing everything ā€˜in placeā€™ as you went along, i.e. place each tree at each iteration of the grid. You can use world position for a seed [feature request] by building a proc to mash a vector into a single int, but I favour passing seeds down through the procedures and distributing/manipulating them as you go. This is more stable and gives you a root seed to control everything with too. Iā€™m going to add a basic seed tutorial today actually.

No, you canā€™t shrink the area, I may add a context menu option to do that at some point. [feature request].

Frames are a good way to break up spaces for placement, I should add a tutorial for this [feature request] when I can think of a useful example case that isnā€™t too complex.

Breaking the process into multiple phases (generate positions ā†’ sample heightfield ā†’ place objects) is trickier and would require Blueprint/code interaction to handle the intermediate step. The alternative might be to pass in a grid of samples (as a list) to give the rough shape of the land. Currently, also, the procedures are only able to work in local/object space and have no concept of world location. The Unity plugin currently works with entities only in world space at the moment so this is something Iā€™d like to unify by exposing it as an option on the entity instance [feature request]. There are cases for both, as well as other considerations like; world space entities need to be rebuilt as they are transformed, object space ones donā€™t.

The reason I did in steps and not placing things at each Iteration was so I could reuse the list placement node easily.

In fact, one of the most powerful things I think Apparance has is this ease to reuse procedures for different purposes. So Iā€™d rather favour the modularity of bits of the graph as much as possible.

With a couple of changes (like passing the descriptor as a parameter to the list placement graph) I used the same procedure for the rock placement.

It would have been even more flexible if I could type in the descriptor as a parameter in the object placed in the world.

However when I tried to do it the Editor and Unreal Crashed. Do you want these logs? Would they be useful to you?

Right. In the future I plan to have procedure switching to allow them to selected dynamically, then you could pass in the Tree/Rock whatever parameter you wanted from outside. Similar technique, but passing the procedure (and defaults) instead of the resource descriptors.

Strings work as parameters so Iā€™d be interested in that crash log or crash dump please. Can you zip up the folder for it in projects Saved/Crashes folder and upload it to my one-drive please.

Thanks.

Defaults for inputs would be heavenly.

I have been worried about Inputs that would potentially cause a DIV/0, but I guess the editor does handle that as I have done it with the circle placement

like div 360/NumberOfPoints parameter to get the Angle variation around a circle.

Iā€™m not sure weā€™re talking about the same defaults, this was me talking quite specifics of how the procedure switching would work, not defaults in general.

If you mean defaults for new instances in the scene, you can. Select the inputs list to the left of the procedure and on each input you can expand a metadata section for default value, ranges, etc.

Another alternative is Entity Presets, an additional asset type you can create in your project with a preselected procedure and parameter values. These can be dragged into the scene and live-inherit their preset values. (If you change the entity procedure the link to the preset is broken). Any parameter value can be overridden or reverted to itā€™s default. This applies to Preset values too.

Also worth noting that itā€™s by-design impossible to crash the generation process with procedure graphs, and at worse you just wonā€™t get any output, or perhaps partial output. There are error messages that the synthesis process can produce, but they arenā€™t exposed yet (on the pre-release list).

1 Like

Managed to get something messy working along these lines.

  1. Procedural Entity places a jittered grid of Blueprint Procedural Entities
  2. Each Entity has a construction script that hit tests the ground passes this height to one of itā€™s procedure parameters, which then build with that information passed in.
  3. That procedure places a third blueprinted actor (non-procedural) with some tree mesh parts in it (a hack to make a tree. I could have generated the geometry but wanted to get it to place an actor/bp).

It doesnā€™t update in realtime, but does recalc when you let go of the dragging. This is only because placed BPā€™s donā€™t actually move when their parent moves.

So, this sort of thing is definitely doable, but:

  1. It needs the fix I have for running the construction script
  2. There are some complications with regard to relative positioning and the way placed blueprints currently work that needs looking at.
  3. Itā€™s not very efficient spawning hundreds of BPs as you can imaging.
  4. Not sure how best else to provide landscape shape info to the procedures at the moment

With the exception of the fact that I had to select each individual blueprint entity and update something in its parameters to trigger the Construction Graph Update, this works well.

As I understand Construction Graphs update once when spawned, then each time a parameter on an instance is changed. So I selected each individual blueprint entity placed by the Apparance Entity and ticked/unticked a SnapToGround Bool that the construction graph uses. And bam, they went where they should have been.

Construction Graphs donā€™t run at run-time. So this is only something that can be used to build static environments, and not fully procedurally generated ones.

The Construction Graph is actually doing the placement on the ground and not the procedure.

In my case here each individual rock has a construction graph of its own, but youā€™re right at scale this would probably not be a great solution.

This is what each rock Blueprint Actor placed is doing.

I am curious to look at step 2 in your process

This is the BP, similar hit-test to yours, and feeding into the proc-parameter ā€œGround Heightā€ (you need to set the procedure type and un-tick any inputs you arenā€™t overriding in the node properties)

This has the effect of overriding the actual parameters the entity uses to generate. The construction script is run before generation starts and the overrides are non-destructive. If you do this on a manually placed entity you can see the parameter gets greyed out.

image

Anyway, yes, as you say, this isnā€™t much use at runtime as they donā€™t run so Iā€™m not sure how youā€™d do this with procedurally placed blueprints. Maybe a ā€˜before generationā€™ event that you can use in the Event Graph instead. (there is already an Event called GenerationComplete that you can use to handle script to run after generated content has been instanced).

1 Like

Oh, and Iā€™ve just uploaded a new build (1.1.11) with the construction script fix (and the new input bug fixes). I posted an Itch dev-log too with the release notes so you may get a notification email or something (let me know how this appears as it might be a sensible way to notify people of new versions).

YES!

5s_SparkVideo (1)

1 Like

This next one does a Physical Material Check on the Landscape and updates the Entity Parameters to only allow the object to be placed on a certain surface.

PhysMatCheck_SparkVideo

1 Like

You could pass the surface into the procedure and it could switch whatā€™s placed instead, e.g. type of tree?

Yes. The Type of Surface is an Enum that you configure in Unreal, and you could push it as a string.

2021-11-17_13-31-19-1_SparkVideo

1 Like

\o/

Your Random needs a seed feed. :slight_smile: (In case you hadnā€™t noticed Iā€™ve added a couple of tutorials on iteration and seeds).

I removed the seed just for the gif there. I was using the concatenated X+Y position in the world location as the seed for the placement and it was changing the type of tree every time I moved. Which is desired, but made the video uncomfortable.


Actually I just noticed a bug with the graph above, those Vector numbers need to be absolute values

And this

4s_SparkVideo

I couldnā€™t get the of the ApparanceEntity in the Procedure graph is there a way to do that?

position of the entity? no, at the moment you can only build in object space, if you want the world position you can pass it in. I plan to support world space as an option so a frame passed in is world absolute rather than actor relative (currently the Unity version operates like this). Might be better to work in terms of seeds, then you wonā€™t get all that noise when moving them, the script can assign a seed based on something else, like the entity name or some other id if there is one.