//This function takes a noise function onto a "nearby" (in terms of function distance) noise function. //Given the noise function, its dimension, its bounds, a uniform distribution of perturbation [-amt, amt], the fraction of points to be perturbed, and the amount of saturation to apply on renormalization. //The exact bound is extremely difficult to calculate, but for saturation = 1, assuming fraction * number of samples is an integer, and assuming no sample is taken out of bounds, the maximum change to the integral over the unit hypercube is fraction * amt. void perturb_noise_sum(noise_sum* n, unsigned dimension, float n0, float n1, float amt, float fraction, float saturation) { assert(n0 <= n1); unsigned ncount = upow(n->n.count, dimension); unsigned perturbCt = uceilf(ncount * fraction + 1.0 - EPSILON); for(unsigned i = 0; i < perturbCt; i++) { unsigned idx = uniformNatural(ncount); //This check should never be violated. However, we may want to be more tolerant in the future: if this is violated for good reasons, we may want to remove the check. assert(n->n.values[idx] >= n0 && n->n.values[idx] <= n1); n->n.values[idx] = n->n.values[idx] + uniformFloatS(amt); } //Apply some blur blur_noise(&n->n, dimension, 0.25); //Convert to 1d noise. unsigned ocount = n->n.count; n->n.count = ncount; //Normalize noise_rescale_out(&n->n, n0, n1); //Saturate noise_saturate(&n->n, saturation); //Convert back to d dimensional noise. n->n.count = ocount; }
//-------------------------------------------------------------------- void image_filter_lut::realloc_lut(real radius) { m_radius = radius; m_diameter = uceilf(radius) * 2; m_start = -int(m_diameter / 2 - 1); unsigned size = m_diameter << image_subpixel_shift; if(size > m_weight_array.size()) { m_weight_array.resize(size); } }