Infection Solver
An infection solver is a dynamic system in Houdini designed to propagate an attribute or variable across neighbouring points based on defined rules. These rules can leverage factors such as proximity, connectivity, or specific attributes like temperature, stress, or custom data fields.
This concept has been widely explored and applied in various creative and technical contexts, such as procedural animation, VFX simulations, and interactive systems. In this guide, we'll cover the foundational mechanics of building an infection solver, providing you with the essential techniques to expand and customize it for more advanced use cases.
Start by creating a base geometry to act as the canvas for the infection. For this example, we'll use the swan-donkey.
Add a scatter to the chosen base geometry and in 2 attribute creates, initialise: @infected (initialized to 0) and @infection_time (initialised to -1).
We also want to have a source for our infection, this can be done manually or randomly, I'll use random for now. This can all be done in a point wrangle.
@infected = 0; // 0: not infected, 1: infected
@infection_time = -1; // -1 indicates no infection yet
if (rand(@ptnum) < 0.01) { // 1% chance
@infected = 1;
@infection_time = 0;
}
Now we have some geometry and attributes to work with we can move into a solver. Create a blank solver and jump inside, we're going to be working within a point wrangle. The base concept is we want the infected points to infect the non-infected points around them.
int infected = @infected;
if (infected == 0) {
// Check neighbours using point cloud
int handle = pcopen(@OpInput1, "P", @P, 1.5, 10); // radius and max points
int pt;
while (pciterate(handle)) {
pcimport(handle, "point.number", pt);
if (point(0, "infected", pt) == 1) {
infected = 1; // Get infected if any neighbour is infected
break;
}
}
}
if (infected == 1 && @infected == 0) {
@infection_time = @Time; // Record the time of infection
}
@infected = infected;
You can customize the infection solver in various ways to make it more dynamic or complex:
Add decay: Implement a decay mechanism where infection subsides after a certain time.
Weighted spread: Use an attribute like temperature or distance to influence the likelihood of infection.
Growth rules: Instead of a simple binary state, use more states (e.g., healthy, infected, recovered).
Here’s an example with a decay mechanism:
float decay_rate = 0.1; // Time to lose infection
if (@infected == 1 && (@Time - @infection_time) > decay_rate) {
@infected = 0; // Recover
}
This basic infection solver lays the foundation for more advanced simulations and artistic effects. Once you a base system has been established, it can extend to work with particles, volumes, or even procedural animations.