Introduction
You know them all - their names have been familiar since school: π (Pi ≈ 3.14159), φ (Phi, the golden ratio ≈ 1.61803), e (Euler's number ≈ 2.71828). But how many of us have actually used them - not in a math exercise, but in a production pipeline, to build a convincing natural environment?
These three mathematical constants are not academic curiosities - they are algorithms nature itself has used for billions of years to optimize, distribute and structure the living world. Alongside them sits their natural companion, the Fibonacci sequence, and the 3×3 Rule - a method built over years of production work that turns these mathematical principles into a concrete, reproducible workflow in Houdini, Blender, Terragen or Gaea.
None of this requires being a coding expert - even though the examples below use Houdini's VEX Wrangle nodes. The point is a way of thinking about environment creation: in nature, chaos is not random. It is ordered by light, growth, spacing, substrate and moisture. A truly natural environment isn't designed by hand - it's generated. Mathematics as ingredients, nature as the recipe.
π (Pi ≈ 3.14159) - The Number of Cycles and Circles
π shows up everywhere a shape rotates, coils, or is distributed in a ring: tree growth rings, the radial arrangement of petals, ripples on water, craters, vegetation zones around a water source. Anything circular or cyclical carries π's imprint. In Houdini, it comes into play in every degree-to-radian conversion, every sinusoidal terrain curve, and above all in computing the golden angle - the most powerful tool for distributing elements without overlap.
The Golden Angle - π Meets φ
The formula golden_angle = 2π × (1 − 1/φ) ≈ 137.5° is one of the most powerful tools in environment creation. It combines π and φ to produce an angle that, repeated indefinitely, places every point without ever landing on a previous one - exactly what sunflowers, pinecones and pineapples do.
// Point Wrangle - Golden spiral distribution
float PI = 3.14159265358979;
float phi = 1.61803398874989;
float golden_angle = 2.0 * PI * (1.0 - 1.0/phi); // ~2.3999 rad ~137.5deg
int N = 300;
float R = 15.0; // max distribution radius
for (int i = 0; i < N; i++) {
float r = R * sqrt(float(i) / N);
float theta = i * golden_angle;
vector pos = set(r * cos(theta), 0, r * sin(theta));
int pt = addpoint(0, pos);
setpointattrib(0, "pscale", pt, fit(r, 0, R, 0.2, 1.5));
}
Circular Distributions and Concentric Rings
For natural ring formations - vegetation around a water source, rocks around a crater, fairy-ring mushrooms - π lets you position elements precisely on concentric rings with natural variation.
// VEX - Concentric ring distribution (wetland zones)
float PI = 3.14159265358979;
// 3 rings corresponding to the 3 levels of the 3x3 rule
float rings[] = {3.0, 8.0, 13.0}; // Fibonacci radii!
float widths[] = {1.5, 2.5, 4.0};
float dist = length(set(v@P.x, 0, v@P.z)); // distance to center
for (int r = 0; r < 3; r++) {
float inner = rings[r] - widths[r];
float outer = rings[r] + widths[r];
if (dist > inner && dist < outer) {
i@layer = r + 1;
// Angle on the ring - variation with noise
float angle = atan2(v@P.z, v@P.x);
f@ring_density = abs(sin(angle * rings[r])) * 0.5 + 0.5;
}
}
Sine Curves for Terrain and Rivers
sin(π × x) and cos(π × x) generate smooth, natural curves for river meanders, terrain waves, or periodic density variation.
// VEX - Sinusoidal density variation (vegetation wave effect)
float PI = 3.14159265358979;
float freq = 0.08;
// Natural undulation of density
f@density = 0.5 + 0.5 * sin(PI * v@P.x * freq + noise(v@P * 0.3));
// Sinusoidal river
float river_y = 5.0 * sin(PI * v@P.x * 0.05);
float river_dist = abs(v@P.z - river_y);
f@moisture = fit(river_dist, 0, 8, 1, 0); // moisture decreases away from the river
φ (Phi ≈ 1.61803) - The Golden Ratio
φ is the ratio toward which consecutive Fibonacci-term ratios converge - the proportion the human eye perceives as naturally harmonious, likely because it co-evolved with a nature that uses it everywhere: tree branching, leaf arrangement, shell proportions.
| Natural structure | φ mechanism |
|---|---|
| Sunflower / pinecone | Spirals in Fibonacci ratios (13/21, 21/34...) for maximum density |
| Phyllotaxis | Divergence angle ≈ 137.5° (360°/φ²) avoids mutual shading |
| Nautilus shell | Logarithmic spiral with a factor of φ between each revolution |
| Tree branching | Each branch divides in ratios close to φ |
| A4/A3 paper ratio | √φ ≈ 1.272 - the same harmonious-proportion principle |
Procedural Scales Based on φ
// Instance sizes based on phi - harmonious progression
float phi = 1.61803398874989;
int layer = i@layer; // 1, 2 or 3 (3x3 rule)
// Each level is phi times smaller than the previous one
float base_scale = 10.0;
f@pscale = base_scale / pow(phi, layer - 1);
// L1 -> 10.0, L2 -> 6.18, L3 -> 3.82
// Natural variation +/- 20% around the phi value
f@pscale *= fit01(rand(@ptnum), 0.8, 1.2);
LOD Based on φ
// LOD density decreasing by phi with distance
float phi = 1.61803398874989;
float dist = length(v@P - v@Eye);
// Distance thresholds as powers of phi
float d1 = 20.0;
float d2 = d1 * phi; // 32.4m
float d3 = d2 * phi; // 52.4m
float d4 = d3 * phi; // 84.7m
float keep = 1.0;
if (dist > d4) keep = 0.05;
else if (dist > d3) keep = 1.0/pow(phi,3); // ~0.24
else if (dist > d2) keep = 1.0/pow(phi,2); // ~0.38
else if (dist > d1) keep = 1.0/phi; // ~0.62
if (rand(@ptnum) > keep) removepoint(0, @ptnum);
e (Euler ≈ 2.71828) - The Constant of Natural Growth
e is the base of natural growth and decay. Any population, radiation, or diffusion that "grows or decays in proportion to its size" follows a law in eˣ - nature's fundamental law behind dense rainforest at the center of a clearing, vegetation thinning toward rocky areas, or biome density decreasing with altitude. The function f(x) = e⁻ᵏˣ (density falloff) exactly describes how a natural element's density decreases with distance - a large k gives rapid falloff (isolated trees), a small k gives gentle falloff (grass covering the whole terrain).
Distance-Based Density Mask
// VEX - Natural density falloff with e
// k controls the falloff speed
float dist_to_center = length(set(v@P.x, 0, v@P.z));
// Parameters per level (3x3 rule)
float k_L1 = 0.08; // trees - slow falloff
float k_L2 = 0.15; // shrubs - medium falloff
float k_L3 = 0.05; // ground - covers everything
float density_L1 = exp(-k_L1 * dist_to_center);
float density_L2 = exp(-k_L2 * dist_to_center);
float density_L3 = exp(-k_L3 * dist_to_center);
// Add noise to break perfect symmetry
float n = noise(v@P * 0.05);
density_L1 *= fit01(n, 0.7, 1.3);
if (rand(@ptnum) > density_L1) removepoint(0, @ptnum);
Exponential Growth - Vegetation Toward a Water Source
// The closer to the water, the denser the vegetation
float dist_water = f@dist_water; // precomputed attribute
// Inverse exponential growth: dense near water
float moisture = exp(-0.1 * dist_water);
float lush_bonus = exp(-0.05 * dist_water) - 0.3;
// The 3 levels respond differently to moisture
float prob_tree = moisture * 0.8;
float prob_bush = moisture * 1.2; // shrubs very sensitive
float prob_grass = clamp(lush_bonus, 0, 1);
float r = rand(@ptnum);
if (r < prob_tree) i@layer = 1;
else if (r < prob_bush) i@layer = 2;
else if (r < prob_grass) i@layer = 3;
else removepoint(0, @ptnum);
The Fibonacci Sequence
Popularized in Europe by Leonardo Pisano (c. 1170-1250) in his Liber Abaci, the sequence already existed in India as early as the 6th century, defined by a simple recurrence: F(0)=0, F(1)=1, F(n)=F(n-1)+F(n-2) → 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144... Consecutive ratios converge to φ: 5/3 = 1.667, 8/5 = 1.600, 13/8 = 1.625, 21/13 = 1.615, 34/21 = 1.619, 55/34 ≈ 1.618. This connection was explicitly noted by Johannes Kepler in the 17th century; Binet's formula formalizes it as Fₙ = (φⁿ − (−φ)⁻ⁿ) / √5.
Terrain Applications - Fibonacci Octaves
Rather than regular octaves (1, 2, 4, 8...), using Fibonacci values for noise frequencies creates irregularities mimicking real geological formations, with amplitude decreasing by 1/φ at each octave - exactly as in nature.
// VEX inside a Heightfield Noise - Fibonacci octaves
float fib[] = {1, 1, 2, 3, 5, 8, 13, 21, 34};
float phi = 1.61803398874989;
float height = 0;
float amplitude = 1.0;
for (int i = 0; i < len(fib); i++) {
float freq = fib[i] * 0.018;
height += noise(v@P * freq) * amplitude;
amplitude /= phi; // falloff by 1/phi
}
// Add a low-frequency base with e for the overall falloff
float base = exp(-0.002 * length(set(v@P.x, 0, v@P.z)));
f@height = height * base * 120.0; // 120m max height
Fibonacci Spacing for LOD
// LOD density by distance - Fibonacci thresholds
float fib[] = {1,1,2,3,5,8,13,21,34,55};
float unit = 8.0; // meters per Fibonacci unit
float dist = length(v@P - v@Eye);
int lod_idx = clamp(int(dist / (unit * 3)), 0, 9);
// Probability inversely proportional to Fibonacci
float keep_prob = 1.0 / fib[lod_idx];
if (rand(@ptnum) > keep_prob)
removepoint(0, @ptnum);
// Result: density 1/1, 1/2, 1/3, 1/5, 1/8, 1/13... with distance
The 3×3 Rule - An Original Method
After years of creating procedural environments in real production, one thing becomes clear: visual richness doesn't come from the number of assets, but from their strategic organization. Multiplying plant species, rock types or ground variants doesn't produce a more realistic environment - it produces visual chaos that overloads the render engine and tires the eye. The 3×3 Rule was born from this observation: a deliberate constraint that forces qualitative choices and guarantees visual consistency at every camera distance, while maintaining optimal performance. (See also the fuller treatment in Heightfield Terrains, Biomes and Vegetation.)
| Level | Selection | Examples |
|---|---|---|
| Level 1 - Grand scale | 3 dominant elements | Large trees, massive rocks, imposing structures |
| Level 2 - Medium scale | 3 intermediate elements | Shrubs, tall grass, small rocks, bushes |
| Level 3 - Ground level | 3 ground elements | Moss, pebbles, low plants, leaf litter, ferns |
The rule is software-independent and applies identically across tools: Houdini (Scatter + Copy to Points, with pscale/orient/Cd/variant attributes), Blender (Geometry Nodes with point distribution and instancing), Terragen (Population Objects with per-level density ramps), Gaea (exporting altitude/slope zone masks to seed each layer), and Unity/Unreal (Foliage Painter with a per-layer density brush).
Complete 3×3 Scatter Integrating All Four Numbers
// VEX - 3x3 scatter integrating PI, phi, e, and Fibonacci
float PI = 3.14159265358979;
float phi = 1.61803398874989;
// Distance and moisture
float dist = length(set(v@P.x, 0, v@P.z));
float moisture = exp(-0.08 * dist); // e - density falloff
float slope = f@slope;
// Noise mask with Fibonacci frequencies
float n1 = noise(v@P * 0.013); // large scale (phi-spaced octaves below)
float n2 = noise(v@P * 0.021); // medium scale (x phi)
float n3 = noise(v@P * 0.034); // fine scale (x phi)
float mask = (n1 + n2*0.618 + n3*0.382) / 2.0;
// Level assignment based on conditions
float prob = mask * moisture;
if (slope < 15.0 && prob > 0.65) {
i@layer = 1; // Grand scale
i@variant = int(rand(@ptnum) * 3); // 3 species
f@pscale = 10.0 / pow(phi, 0); // phi scale L1
}
else if (slope < 30.0 && prob > 0.35) {
i@layer = 2; // Medium scale
i@variant = int(rand(@ptnum+100) * 3);
f@pscale = 10.0 / pow(phi, 1); // phi scale L2 = 6.18
}
else if (prob > 0.1) {
i@layer = 3; // Ground level
i@variant = int(rand(@ptnum+200) * 3);
f@pscale = 10.0 / pow(phi, 2); // phi scale L3 = 3.82
}
else removepoint(0, @ptnum);
// Orient via the golden angle (PI + phi)
float golden_angle = 2.0 * PI * (1.0 - 1.0/phi);
float rot = (@ptnum * golden_angle) + noise(v@P * 0.2) * PI;
p@orient = set(0, sin(rot*0.5), 0, cos(rot*0.5)); // quaternion -> p@, not v@
Distribution Algorithms
Each noise pattern generates a different type of distribution, corresponding to a specific natural phenomenon. Using the wrong algorithm for a given level produces a result that immediately looks "off" to the eye, even without being able to explain why.
Poisson Disk Sampling
The reference algorithm for Level 1 elements that must not overlap. Houdini offers it natively in the Scatter node via the Relax Iterations option; for fine control:
// VEX - Poisson Disk check via spatial neighborhood
float min_dist = 5.0; // minimum distance between trees (meters)
// Look for neighbors within radius min_dist
int neighbors[] = nearpoints(0, v@P, min_dist);
// If a neighbor is closer than min_dist -> remove
if (len(neighbors) > 1)
removepoint(0, @ptnum);
// Tip: run 5+ relax passes for an optimal result
DLA - Diffusion-Limited Aggregation (Moss and Lichen)
DLA simulates growth by diffusion: particles perform a random walk until they meet an existing cluster - the pattern behind moss on rocks, lichen, and coral formations, anything that "grows" outward from a center.
// Simplified VEX - DLA clustering with a Gaussian
vector center = {0, 0, 0}; // starting point (rock, trunk...)
float sigma = 15.0; // spread radius
// Gaussian distance from the center
float d = length(v@P - center);
float density = exp(-(d*d) / (2.0 * sigma * sigma));
// Angular variation for DLA branches
float angle = atan2(v@P.z - center.z, v@P.x - center.x);
float branch = abs(sin(angle * 5.0)) * 0.4; // 5 branches
float keep = density + branch * density;
if (rand(@ptnum) > keep) removepoint(0, @ptnum);
Complete Pipeline and Checklist
The five mathematical tools integrate naturally into a cross-software environment pipeline: Gaea generates a heightmap with Fibonacci octaves plus exported altitude/slope zone masks; Houdini imports the heightmap and runs the 3×3 scatter (Poisson for L1, blue noise for L2, DLA for L3), applies e-based density falloff and φ-based orientation; Terragen handles photoreal rendering, with Population Objects driven by φ ramps and volumetric atmosphere.
| Metric | Result with the method |
|---|---|
| Asset loading reduction | 60% vs. an unstructured approach |
| Distribution computation speed | 90% faster (Poisson vs. raw random) |
| Setup time per biome | 2-4h vs. 1-2 days (non-mathematical approach) |
| Consistency across sessions | Reproducible, parametric, editable pipeline |
| Visual quality | Maintained - the 3×3 constraint forces better choices |
Production checklist:
- Define the 9 assets (3×3) before any scatter
- Choose the noise algorithm suited to each level
- Use Fibonacci frequencies for terrain octaves
- Apply the golden angle (2π × (1−1/φ)) for all on-surface vegetation placement
- Implement e⁻ᵏˣ density falloff with a different k per level
- LOD with φ or Fibonacci thresholds based on camera distance
- Validate: 9 assets max per biome, unlimited procedural variation
π, φ, e and Fibonacci aren't abstractions reserved for mathematicians - they're concrete, production-tested tools that make it possible to generate convincing natural environments with remarkable efficiency. They work because nature already optimized them; the job is simply to encode them in Houdini. The 3×3 Rule translates these principles into an actionable workflow: 9 well-chosen assets, distributed by the right algorithms, varying according to natural constants, produce rich, believable biomes that hold up under the most demanding scrutiny.