// -*-C++-*- #include #define FPARAM(name, default) float name = params->getFloat(#name, default); float func(float x, float y) { float t = x*10; float u = y*10; return .5 + .3 * sin(x*M_PI*2*4) - .2*(t-floor(t)) + .2*sin(y*M_PI*2) + .2*(u-floor(u)); } float filter(float *data, int w, int h, int c, float x, float y) { int ix0 = (int)floor(x), ix1 = ix0 + 1; int iy0 = (int)floor(y), iy1 = iy0 + 1; float fx = x - ix0; float fy = y - iy0; ix0 &= w - 1; ix1 &= w - 1; iy0 &= h - 1; iy1 &= h - 1; return data[(ix0 + w * iy0) * c] * (1 - fx) * (1 - fy) + data[(ix0 + w * iy1) * c] * (1 - fx) * fy + data[(ix1 + w * iy0) * c] * fx * (1 - fy) + data[(ix1 + w * iy1) * c] * fx * fy; } void GENERATE(TextureParam *params, int width, int height, int depth, int components, float *data) { FPARAM(bias, 0); FPARAM(scale, 1); FPARAM(eps, .25); // Note: radius is specified in texels FPARAM(radius, 2); // Ripple amplitude in texture coordinates FPARAM(ripple_scale, 0.25); if(components != 4) return; if(width != height) return; int ind=0, i, j; float x, y; float xstep = 1.0 / width; float ystep = 1.0 / height; ind = 3; for (j = 0, y = 0; j < height; j++, y += ystep) { for (i = 0, x = 0; i < width; i++, x += xstep) { data[ind] = func(x,y); ind += 4; } } for (int comp = 0; comp < 3; comp++) { float dx = cos(comp * 2*M_PI / 3); float dy = sin(comp * 2*M_PI / 3); ind = 0; for (j = 0, y = 0; j < height; j++, y += ystep) { for (i = 0, x = 0; i < width; i++, x += xstep) { float scale = 1.0 / (width * ripple_scale); float maxh = -1E+10; for (float r = -radius; r <= radius; r += eps) { float h = filter(data + 3, width, height, components, i + dx * r, j + dy * r); h += sqrt(radius * radius - r * r) * scale; //h += radius * scale; if (h > maxh) maxh = h; } data[ind + comp] = maxh; ind += 4; } } } for(int i = 0; i