/************* * DESCRIPTION: Vector-based procedural fBm * INPUT: v position * H fractal increment parameter * lacunarity gap between successive frequencies * octaves number of frequencies in the fBm * r result vector * OUTPUT: - *************/ void VfBm(VECTOR *vec, float omega, float lambda, int octaves, VECTOR *r, short *hashTable) { float l,o; int i; VECTOR p, res; r->x = 0.f; r->y = 0.f; r->z = 0.f; l = 1.f; o = 1.f; p = *vec; for(i=0; i<octaves; i++) { p.x *= l; p.y *= l; p.z *= l; DNoise(&p, &res, hashTable); r->x += res.x * o; r->y += res.y * o; r->z += res.z * o; l *= lambda; o *= omega; } }
void BrickMaterial::normal_texture (Vector3D& v) { float a = 30*scale, b = 0.3f, // frequency and intensity of the bumps h = hypot(v.x,v.y,v.z); // normalization of normal vector if (h) { a /= h; b *= h; } float px = a*v.x, py = 3*a*v.y, pz = a*v.z; DNoise(px,py,pz); v.x += b*px; v.y += b*py; v.z += b*pz; }
static void bumps (const Vector3d& EPoint, const TNORMAL *Tnormal, Vector3d& normal) { Vector3d bump_turb; /* Get normal displacement value. */ DNoise (bump_turb, EPoint); /* Displace "normal". */ normal += (DBL)Tnormal->Amount * bump_turb; }
static void bumps (const VECTOR EPoint, const TNORMAL *Tnormal, VECTOR normal) { VECTOR bump_turb; /* Get normal displacement value. */ DNoise (bump_turb, EPoint); /* Displace "normal". */ VAddScaledEq(normal, Tnormal->Amount, bump_turb); }
static void dents (const Vector3d& EPoint, const TNORMAL *Tnormal, Vector3d& normal, const TraceThreadData *Thread) { DBL noise; Vector3d stucco_turb; noise = Noise (EPoint, GetNoiseGen(Tnormal, Thread)); noise = noise * noise * noise * Tnormal->Amount; /* Get normal displacement value. */ DNoise(stucco_turb, EPoint); /* Displace "normal". */ normal += noise * stucco_turb; }
static void dents (const VECTOR EPoint, const TNORMAL *Tnormal, VECTOR normal, const TraceThreadData *Thread) { DBL noise; VECTOR stucco_turb; noise = Noise (EPoint, GetNoiseGen((TPATTERN*)Tnormal, Thread)); noise = noise * noise * noise * Tnormal->Amount; /* Get normal displacement value. */ DNoise(stucco_turb, EPoint); /* Displace "normal". */ VAddScaledEq(normal, noise, stucco_turb); }
/************* * DESCRIPTION: Noise function * INPUT: v noise position * OUTPUT: noise *************/ float VLNoise(VECTOR *v, short *hashTable) { VECTOR offset, r; offset.x = v->x + 0.5f; /* misregister domain */ offset.y = v->y + 0.5f; offset.z = v->z + 0.5f; DNoise( &offset, &r, hashTable); /* get a random vector */ /* ``point'' is the domain; distort domain by adding ``offset'' */ r.x += v->x; r.y += v->y; r.z += v->z; return Noise(&r, hashTable); /* distorted-domain noise */ }
static void wrinkles (const Vector3d& EPoint, const TNORMAL *Tnormal, Vector3d& normal) { register int i; register DBL scale = 1.0; Vector3d result, value, value2; result = Vector3d(0.0, 0.0, 0.0); for (i = 0; i < 10; scale *= 2.0, i++) { value2 = EPoint * scale; DNoise(value, value2); result[X] += fabs(value[X] / scale); result[Y] += fabs(value[Y] / scale); result[Z] += fabs(value[Z] / scale); } /* Displace "normal". */ normal += (DBL)Tnormal->Amount * result; }
static void wrinkles (const VECTOR EPoint, const TNORMAL *Tnormal, VECTOR normal) { register int i; register DBL scale = 1.0; VECTOR result, value, value2; Make_Vector(result, 0.0, 0.0, 0.0); for (i = 0; i < 10; scale *= 2.0, i++) { VScale(value2,EPoint,scale); DNoise(value, value2); result[X] += fabs(value[X] / scale); result[Y] += fabs(value[Y] / scale); result[Z] += fabs(value[Z] / scale); } /* Displace "normal". */ VAddScaledEq(normal, Tnormal->Amount, result); }
static void facets (const Vector3d& EPoint, const TNORMAL *Tnormal, Vector3d& normal, TraceThreadData *Thread) { int i; int thisseed; DBL sum, minsum; Vector3d sv, tv, dv, t1, add, newnormal, pert; DBL scale; int UseSquare; int UseUnity; DBL Metric; Vector3d *cv = Thread->Facets_Cube; Metric = dynamic_cast<FacetsPattern*>(Tnormal->pattern.get())->facetsMetric; UseSquare = (Metric == 2 ); UseUnity = (Metric == 1 ); normal.normalize(); if ( dynamic_cast<FacetsPattern*>(Tnormal->pattern.get())->facetsCoords ) { tv = EPoint; } else { tv = normal; } if ( dynamic_cast<FacetsPattern*>(Tnormal->pattern.get())->facetsSize < 1e-6 ) { scale = 1e6; } else { scale = 1. / dynamic_cast<FacetsPattern*>(Tnormal->pattern.get())->facetsSize; } tv *= scale; /* * Check to see if the input point is in the same unit cube as the last * call to this function, to use cache of cubelets for speed. */ thisseed = PickInCube(tv, t1); if (thisseed != Thread->Facets_Last_Seed) { /* * No, not same unit cube. Calculate the random points for this new * cube and its 80 neighbours which differ in any axis by 1 or 2. * Why distance of 2? If there is 1 point in each cube, located * randomly, it is possible for the closest random point to be in the * cube 2 over, or the one two over and one up. It is NOT possible * for it to be two over and two up. Picture a 3x3x3 cube with 9 more * cubes glued onto each face. */ /* Now store a points for this cube and each of the 80 neighbour cubes. */ int cvc = 0; for (add[X] = -2.0; add[X] < 2.5; add[X] +=1.0) { for (add[Y] = -2.0; add[Y] < 2.5; add[Y] += 1.0) { for (add[Z] = -2.0; add[Z] < 2.5; add[Z] += 1.0) { /* For each cubelet in a 5x5 cube. */ if ((fabs(add[X])>1.5)+(fabs(add[Y])>1.5)+(fabs(add[Z])>1.5) <= 1.0) { /* Yes, it's within a 3d knight move away. */ sv = tv + add; PickInCube(sv, t1); cv[cvc] = t1; cvc++; } } } } Thread->Facets_Last_Seed = thisseed; Thread->Facets_CVC = cvc; } /* * Find the point with the shortest distance from the input point. */ dv = cv[0] - tv; if ( UseSquare ) { minsum = dv.lengthSqr(); } else if ( UseUnity ) { minsum = dv[X]+dv[Y]+dv[Z]; } else { minsum = pow(fabs(dv[X]), Metric)+ pow(fabs(dv[Y]), Metric)+ pow(fabs(dv[Z]), Metric); } newnormal = cv[0]; /* Loop for the 81 cubelets to find closest. */ for (i = 1; i < Thread->Facets_CVC; i++) { dv = cv[i] - tv; if ( UseSquare ) { sum = dv.lengthSqr(); } else { if ( UseUnity ) { sum = dv[X]+dv[Y]+dv[Z]; } else { sum = pow(fabs(dv[X]), Metric)+ pow(fabs(dv[Y]), Metric)+ pow(fabs(dv[Z]), Metric); } } if (sum < minsum) { minsum = sum; newnormal = cv[i]; } } if ( dynamic_cast<FacetsPattern*>(Tnormal->pattern.get())->facetsCoords ) { DNoise( pert, newnormal ); sum = dot(pert, normal); newnormal = normal * sum; pert -= newnormal; normal += dynamic_cast<FacetsPattern*>(Tnormal->pattern.get())->facetsCoords * pert; } else { normal = newnormal; } }
static void facets (const VECTOR EPoint, const TNORMAL *Tnormal, VECTOR normal, TraceThreadData *Thread) { int i; int thisseed; DBL sum, minsum; VECTOR sv, tv, dv, t1, add, newnormal, pert; DBL scale; int UseSquare; int UseUnity; DBL Metric; VECTOR *cv = Thread->Facets_Cube; Metric = Tnormal->Vals.Facets.Metric; UseSquare = (Metric == 2 ); UseUnity = (Metric == 1 ); VNormalize( normal, normal ); if ( Tnormal->Vals.Facets.UseCoords ) { Assign_Vector(tv,EPoint); } else { Assign_Vector(tv,normal); } if ( Tnormal->Vals.Facets.Size < 1e-6 ) { scale = 1e6; } else { scale = 1. / Tnormal->Vals.Facets.Size; } VScaleEq( tv, scale ); /* * Check to see if the input point is in the same unit cube as the last * call to this function, to use cache of cubelets for speed. */ thisseed = PickInCube(tv, t1); if (thisseed != Thread->Facets_Last_Seed) { /* * No, not same unit cube. Calculate the random points for this new * cube and its 80 neighbours which differ in any axis by 1 or 2. * Why distance of 2? If there is 1 point in each cube, located * randomly, it is possible for the closest random point to be in the * cube 2 over, or the one two over and one up. It is NOT possible * for it to be two over and two up. Picture a 3x3x3 cube with 9 more * cubes glued onto each face. */ /* Now store a points for this cube and each of the 80 neighbour cubes. */ int cvc = 0; for (add[X] = -2.0; add[X] < 2.5; add[X] +=1.0) { for (add[Y] = -2.0; add[Y] < 2.5; add[Y] += 1.0) { for (add[Z] = -2.0; add[Z] < 2.5; add[Z] += 1.0) { /* For each cubelet in a 5x5 cube. */ if ((fabs(add[X])>1.5)+(fabs(add[Y])>1.5)+(fabs(add[Z])>1.5) <= 1.0) { /* Yes, it's within a 3d knight move away. */ VAdd(sv, tv, add); PickInCube(sv, t1); cv[cvc][X] = t1[X]; cv[cvc][Y] = t1[Y]; cv[cvc][Z] = t1[Z]; cvc++; } } } } Thread->Facets_Last_Seed = thisseed; Thread->Facets_CVC = cvc; } /* * Find the point with the shortest distance from the input point. */ VSub(dv, cv[0], tv); if ( UseSquare ) { minsum = VSumSqr(dv); } else if ( UseUnity ) { minsum = dv[X]+dv[Y]+dv[Z]; } else { minsum = pow(fabs(dv[X]), Metric)+ pow(fabs(dv[Y]), Metric)+ pow(fabs(dv[Z]), Metric); } Assign_Vector( newnormal, cv[0] ); /* Loop for the 81 cubelets to find closest. */ for (i = 1; i < Thread->Facets_CVC; i++) { VSub(dv, cv[i], tv); if ( UseSquare ) { sum = VSumSqr(dv); } else { if ( UseUnity ) { sum = dv[X]+dv[Y]+dv[Z]; } else { sum = pow(fabs(dv[X]), Metric)+ pow(fabs(dv[Y]), Metric)+ pow(fabs(dv[Z]), Metric); } } if (sum < minsum) { minsum = sum; Assign_Vector( newnormal, cv[i] ); } } if ( Tnormal->Vals.Facets.UseCoords ) { DNoise( pert, newnormal ); VDot( sum, pert, normal ); VScale( newnormal, normal, sum ); VSubEq( pert, newnormal ); VAddScaledEq( normal, Tnormal->Vals.Facets.UseCoords, pert ); } else { Assign_Vector( normal, newnormal ); } }