Skip to main content
EnglishTool

GRM ProbabilisticFeathers (English)

By March 19, 2025March 22nd, 2025No Comments

Context

When we want to place pre-made feather models on a character, Houdini offers several methods.

One of these methods is to use guidegroom, and manually select the specific feather model we want to use when drawing or placing guides. This method isn’t very procedural, but it allows you to work quickly and relatively accurately.
The main problem with this technique is when we have to place large numbers of feathers while maintaining procedural control over them.

To replace our guides with feather models, we must use the Feather Template Interpolate node. Within this node, there are three methods for performing the replacement:

Groups: In this method, we enter integers to refer to the models entered in input 4 of this node: the template… that is, we enter 0 if we want ONLY the first feather in our template to be used, or 1 for the second model, etc.

Match by Name Attribute: Using the “templatename” attribute in the guides, we can define which feathers we will use in each guide by the name of the feather model. With this method, we can use any model in any guide.

Weight Arrays: To use this method, two array-type attributes are needed in the guides: one corresponding to the names of the feathers we will use, and another with the weight of each model we will use in each guide. That is, we can mix models (interpolate them) by entering different values ​​in this array. We can say, for example, that a feather is 50% of model A, 25% of model B, etc., and the resulting feather will look like a mixture of them depending on the weighting we use. I should note that the same node normalizes these weights; they are not actually percentages. I’ll return to this concept later.

This last method offers the greatest flexibility of all, as it allows you to not only place any variety of models we choose, but we can also create unique feathers resulting from mixing different models.

But creating the weight array (templateweights) is a very technical task; to date, there is no way to generate it beyond manual generation using a wrangle or a noise attribute.

To solve this problem and make our lives a little easier, we have ProbabilisticFeathers. It uses skin attributes to define areas where we want to define the weights of the different feather models.


Percentages vs. Weights

At first glance, the most “artistically friendly” approach would seem to be to define percentages by area, that is, to define the percentage probability we want a feather to appear in a given area.

To give a simplified example, let’s assume that the entire character will have the same probability of each feather appearing: 50% for feather A, 35% for feather B, and 15% for feather C; the total should be 100%.

In that case, we would paint with 0.5 values ​​for A, 0.35 for B, and 0.15 for C.

For this case, I decided to differentiate the models with colors, not shapes, just for simplicity’s sake.

And we would have something like this:

Okay, we’ve done it, haven’t we?

What would happen if now, for whatever reason, we had to add a new model to the system… and we also wanted it to have a certain probability of being drawn?
We run into the problem of having to redistribute the weights again, because they have to add up to 100% in total. In addition to performing new calculations, we would also have to repaint each map, and this is obviously very problematic.

The problem is that we’re thinking of our system as percentages. If instead of using percentages we use said attribute as weights, things change.

What we’re going to define aren’t percentages, but relative weights.

That is, we’re going to paint how much probability weight a feather has of being drawn randomly.

If it’s 1, what we mean is that we want that particular feather to have a high probability of being drawn, the maximum possible among all the feathers competing to be drawn (something we may not know in advance).

And if we choose 0, what we’ll say is that we don’t want (with absolute certainty) for that feather to not be chosen there.

In each guide, what the system does is see what relative probability weight each feather has of being chosen at random in relation to the weights of the other feathers. If they all have a 1, all the feathers have the same probability of being chosen; if one feather has a 0, it’s certain that it won’t be chosen. If one feather has a 1 and another has a 0.5 (which would add up to more than 100%), what the system does is give one feather twice as much probability of being chosen as the other.

In other words, the system takes all the weights into account and gives each one a weighted probability value of appearing.

Let’s take the previous example and add a new model, giving it a value of 0.5, the same as model A… now they would all add up to 150%.

But since we’re not working with percentages, but with weighted values, the entire system is readjusted to the new model… that is, models A and D have much more weight than model B, and model B in turn has more weight than model C.

Both the Red (A)and Blu (D) feathers are drawn approximately the same number of times, followed by the Yellow feather, which has a weight of 0.35, and finally the Green feather, with only 0.15.

This way, we don’t have to calculate the percentage probability of each feather being drawn in advance; instead, we focus solely on the weight or strength with which each feather bids to be drawn in the model assignment lottery. The higher the value, the stronger it is, and vice versa.

As you can see, the difference between percentages and weighted weights lies in how we interpret attributes. These are simply values ​​ranging from 0 to 1.


Attributes and Models

In the previous examples, we’ve painted all the maps with a single value each, but the idea is to distribute the different models in the areas where they most commonly appear.

And so far we’ve used a single attribute or mask per feather, but we can use those attributes for more than one feather.
And distribute multiple models per zone.

Or the same feather can be used multiple times using different attributes. Thus, we’d have the same model appearing in different locations.

Infinite variations can be made by playing with attributes, either because they are used to determine zones or they are used to define where certain types of feathers appear exclusively.


Zero Weights

Now, what happens if no feather in a zone wants to participate in this lottery? That is, what happens if the weights of all the feathers in a zone are 0?

Which feather will be chosen if all the weights add up to zero?

In these cases, probabilisticFeather offers three options (the one the artist prefers):

Do not place any feathers:
Ideal for debugging and seeing if there are areas where we haven’t defined any feather models.

– Random:
All feathers have the same probability of coming out, unlike the previous method, this time we leave no gap.

– 1st Model on the List:
The first feather defined in the list of possible candidates is considered the default or base feather and will be used to fill areas with zero weight.


Parameters

Keep in mind that this system works with guides, storing the weight and template attributes in them. The feathers will only be visible when we apply the Feather Template Interpolate. This is when we’ll see how the system works more clearly. However, we have the option to temporarily “preview” the distribution using random colors:

In the Feather Templates Node parameter we can specify the node that contains the different feather models… this parameter is not mandatory, but it makes the drop-down menu with the feather names work, making it easier for us to enter the name manually and avoiding possible human errors.


Conclusions

The system is currently designed to distribute the feather models we have and randomly assign them according to their weights. In the future, I plan to implement a system that, in addition to what it already does, allows us to weight interpolate the feathers, creating new models based on existing ones.

gerardoc

Leave a Reply