HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
karma_procedurals/grasspatch.vfl
/*%vcc -l grasspatch.otl -O vop % */
cvex
main(
// Inputs given by the vex curves procedurals
int curv_idx = 0;
int num_curves = 0;
// User driven parameters
int seed = 0x13A499;
float radius = 0.2;
float heightscale = 1.0;
// Required curve points output
export vector points[] = {};
// Optional display color attribute to color the grass
export vector displayColor[] = {};
)
{
// Choose the number of points used, from 7 to 12
int num_points = 7 + curv_idx % 5;
// Sample a random postion to root the grass in
vector2 uv = random_brj(0x4AF03^seed, curv_idx);
// Remap it to a gaussian distribution
vector remap = filter_remap(uv, "gauss", radius);
vector2 base = set(remap.x, remap.y);
// Sample a random height value
float w = random_brj(0x72BC9^seed, curv_idx);
float height = 0.1 * w;
height += heightscale * radius * (2 + 2*remap.z);
// Sample a random postion for where the peak of the grass will be
vector2 peak = random_brj(0x390F0^seed, curv_idx);
peak.x = (base.x * fit01(peak.x, 1, 2.5)) + sign(base.x)*0.1;
peak.y = (base.y * fit01(peak.y, 1, 2.5)) + sign(base.y)*0.1;
// Get the direction from the base to the peak
vector dir = set(peak.x - base.x, 0, peak.y - base.y);
float dist = length(dir);
dir = normalize(dir);
// Get the step distance, by setting to 10 some
// curves won't reach a peak while others can overshoot
float step = dist / 10;
// Some math to get the coefficients of the quadratic y = ax - bx^2
float a = 2 * height / dist;
float b = height / (dist * dist);
float x = 0;
// Iterate over each point and set the position and height
for (int i = 0; i < num_points; i++)
{
x += step;
points[i] = set(base.x, 0, base.y);
points[i] += dir * x;
points[i].y = a*x - b*x*x;
// Set the colour of the point, darker at the base
displayColor[i] = set(0.1);
displayColor[i].g = fit(float(i), 0, 12.0, 0.2, 0.85);
}
}