In-a-Gadda-da-Procgen: Generating Procedural Flowers
The thoughts and opinions expressed are those of the writer and not Gamasutra or its parent company.
(This article was originally posted on my personal blog. )
My current pet project, Bestiarium, might never be finished. That said, its core idea is trying to make the exploration of procedural generation meaningful, and that’s pretty hard. This is why it’s at least a fertile ground for tons of little prototypes and experiments – and in the search of meaning and fun, I end up on weird places like procedural organ generation, which in itself is super fun, but searching for references on google images is not the most pleasant part of the experience. Maybe this is why I ended up going for something lighter this time: flowers.
This prototype would be about chemistry and potions. Plants have been used as medicine since the beginning of mankind, and flowers seemed like an interesting subject for generative prototypes – so I had a pretty good excuse for this one.
First step is always looking for references. Unlike organs and autopsies, I had fun looking at flowers. So many shapes, so many colors, such beautiful kaleidoscopes, so many… possible parameters. Mother Nature really has a knack for genitalia!
When you analyse the references, it’s easy to find something that you’ve never seen (unless you’re a botanist). But games, as in life, are all about cognition: as long as I generated something that can be instantly recognizable as a flower, I’d be good to go.
Let’s make an experiment. Grab a piece of paper and draw a flower. Go ahead, do it.
I’ll consider you did it, and I’d bet money that the drawing consisted of a bunch of petals around a circular core. That’s not only a recognizable symbol, but also pretty easy to generate. That’s what I went for: create a single petal, make Ncopies of it and space them evenly around an axis.
At its simplest abstraction, a petal is pretty much a rectangular plane. But that would give us only 2 dimensions to work with (height and width), which is not really enough. If we subdivide this plane, however, that gives us some more wiggle room.
The most defining feature of a petal is its outer curvature along its length. And for that we have a very good tool in Unity: animation curves. If we deform the outer vertices of the plane based on the curve, we’re getting pretty close to a petal shape.
This is where I started worrying: if these are being rotated around an axis, depending on the amount and width, they might intersect and then there’s going to be a bunch of clipping between them and that’s going to look ugly. For a split second I cringed thinking about all the geometric and/or rendering magic I’d have to do to avoid intersection – so I just decided that I’d limit the ranges to avoid that happening, and the rest would be a problem for future me.
|Weee, a flower! But it’s pretty flat, right? Not saying that there aren’t a bunch of flat-petal flowers, but that’s limiting our possibility space. Even though I wasn’t going for something as complex as a carnation, a little convexity on the petals would make it more natural in some cases.|
|Here’s the same flower, but with a convexity modifier, that allows the generator to “bend” the plane inwards or outwards.||
Looking at something like tulips, it’s pretty much the opposite of a flat surface, and just adjusting petal convexity is not enough for that. So I’ve added a “depth” parameter to the mix that allows the petals to “fold” themselves inwards.
But compare that to a Morning Glory: it’s pretty folded “in” in the base, but very “out” from about half of its length. So I just decided to throw in another curve for controlling that.
So right now we have width, height, a curve for the shape, convexity, “depth” and a curve for it. That can already accomplish a lot! However, because of the approach we took on building the mesh, the tip is always a straight line. The good thing about simple math is that applied to the right places, it can yield very good results: to prevent the hard edge, I simply weighed the length based on the width squared, together with a new parameter I called “tip factor” (and a little magic number for good measure).
This is maybe easier to understand:
float lengthPercent = i / (float)HeightSegments; float absX = Mathf.Abs(vertPos.x); vertPos.y += absX * absX * TipFactor * lengthPercent * 10f;
(this code happens within the iteration for positioning the vertices, that’s where the i comes from)
The tip factor could also turn the whole thing negative, which meant I could also have petals that had 2 tips – I have no idea if this is biologically possible, but hey, it might look cool.
|After realizing I had around 8 parameters to work with, I stopped adding any more. But what are flowers without its colors? Since this was a quick experiment, I just got my old color tint shader from the creature prototype, and tweaked it a bit: instead of using a single texture grayscale and a ramp lookup, I’ve added another texture as a “mask” on top, to create a secondary color. The color palette is generated using Martin Ankerl’s golden ratio conjugate method.|
|Even though this was enough for my current needs, I need to start paying more attention to color and UV: over the past months, I’ve read a ton of places that recommend not using just grayscale for this kind of thing. Also, the UV coordinates are planar, which means there can be some stretching if the shape is too extreme.||
(2 out of the 3 masks are selected at random and used as the masks for the random palette)
Although some are aesthetically pleasing, with fully random curves most of the times petal shapes don’t look very natural
The use of the golden ratio in the palette generator gave me another idea: the random curves for the shapes were… too random. My method for generating the curve was quite naïve: I got the previously generated value and multiplied it by a random factor. So I tweaked it a little bit: instead of randomly picking a factor, I’d randomly select if the width should grow or reduce, and then I’d either multiply or divide the previous by the golden ratio. Turns out that gave it way more natural curves.
Some results from the current generator, using golden ratio for the shape curves
Whenever I do something like this, I spend A LOT of time just watching the thing generate one variation every half a second, to get a visual feel of the results, and adjust the parameter’s min-max values. And even though there’s a bunch of improvements that can be made, I’d sometimes be walking around the street and I’d spot a flower just like something I had generated the day before.
I also realized one thing: my previous worry that the clipping between petals would be a problem was a non-issue. Even more than that, the clipping itself generated interesting shapes and shading. See this flower for example:
This is what its petal looks like:
Which means that the rich, complex, overall visual structure happens not despite of the clipping, but BECAUSE of it. And this is one of my favorite things about procedural generation: with every iteration, lapidating your set of rules gets you new ideas, new directions. You start out knowing what you want and more or less how achieve it – but as in life, where you set out to be is never where you arrive, because the journey changes you. So take some time, and smell the flowers along the way.