Results 1 to 10 of 24

Thread: image processing basics

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Administrator waldronate's Avatar
    Join Date
    Mar 2007
    Location
    The High Desert
    Posts
    3,562

    Default

    If your compiler is a 32-bit compiler, it would likely not be able to generate data much more than 1GB or so in a single allocation (you're breaking between 256MB and 512MB, which might also be a 32-bit compiler limit).

    One efficiency insight is that the scale of each octave varies. Thus, a small power of two array would capture the first octave at adequate resolution, one twice as large for the next octave, and so on. It doesn't necessarily save you any time in the initial generation phase, but as you zoom in you only need to compute the new octaves of data and if you zoom out then you already have much of the data precomputed. Caching can also be very important for certain gradient-based effects such as erosion ( http://dmytry.com/mojoworld/erosion_fractal/home.html has an example ).

    Also, if you're looking for visual effects rather than trying to do fancy processing of the generated data, consider http://mrl.nyu.edu/~perlin/demox/Planet.html for inspiration. It uses a coarse-to-fine scheme for drawing terrain zooms. Users get to see much of what they're interested in very quickly and the software can continue to generate additional detail as the user waits longer. Caching of lower-resolution details and variable numbers of octaves may also be at work here to keep the amount of computation constant from frame to frame.

    And on the Musgrave front, consider that only a short 20 years later, what he described can be done in real-time directly in your browser ( http://codeflow.org/entries/2011/nov...g-and-erosion/ ). A more optimized version would probably run a bit faster, but things are usually memory bandwidth-limited these days. Except for pathological cases like procedural generators, of course.

    And again, simplex noise is somewhat more computationally efficient than the interpolant used in straight Perline noise. And a simple 2D wavelet-type "scale-and-add" operation will always be faster than a volume interpolation. If you can push your basis function texture to the graphic card, it will do the interpolation, scaling, and adding all for you. Plus rotation, too, if you're into that sort of thing.

  2. #2

    Default

    Quote Originally Posted by waldronate View Post
    If your compiler is a 32-bit compiler, it would likely not be able to generate data much more than 1GB or so in a single allocation (you're breaking between 256MB and 512MB, which might also be a 32-bit compiler limit).
    quite right, i was only looking at the indexing not the footprint

    i'm going to have to think about what you've said as i may be going about this in the wrong fashion. my implementation seems very elementary to me without any optimisations between octaves. i'll paste it below in case you feel like (lol) poring through someone else's code..

    simplex noise didn't sink in at all. i'd imagine a year of familiarisation with 2,3d thinking may change that. fortunately, since this is more of an exercise, the only thing i'd really gain by speed improvements is the time spent in development. ty again.


    Code:
    	for (y = 0; y < 2048; y++) {
    		fla = (float)y / 651.580337f;	//	2047/pi
    		fy = cos(fla) * hfbase;	fr = -sin(fla) * hfbase;
    		for (x = 0; x < 4096; x++) {
    			hf[hu][x][y] = 0;
    			flo = (float)x / 651.7394919613114f + adjlong;	//	4095/tau
    			fx = cos(flo) * fr;	fz = sin(flo) * fr;
    			//	fx, fy, and fz mapped to sphere of radius 1 with center at origin if hfbase is removed from above
    
    			float sum = 0.f;
    			for (j = 0; j < woct; j++) {
    				dx = fx * pp2[j];	dy = fy * pp2[j];	dz = fz * pp2[j];
    				if (dx < 0.f) dx += 131072.f;	ix = (int)dx;	dx -= ix;	x1 = ix & 0x1f;
    				if (dy < 0.f) dy += 131072.f;	iy = (int)dy;	dy -= iy;	y1 = iy & 0x1f;
    				if (dz < 0.f) dz += 131072.f;	iz = (int)dz;	dz -= iz;	z1 = iz & 0x1f;
    
    				x0 = x1 - 1;	x2 = x1 + 1;	x3 = x1 + 2;
    				y0 = y1 - 1;	y2 = y1 + 1;	y3 = y1 + 2;
    				z0 = z1 - 1;	z2 = z1 + 1;	z3 = z1 + 2;
    				x0 &= 0x1f;	x2 &= 0x1f;	x3 &= 0x1f;
    				y0 &= 0x1f;	y2 &= 0x1f;	y3 &= 0x1f;
    				z0 &= 0x1f;	z2 &= 0x1f;	z3 &= 0x1f;
    
    				p0 = tricint(dx, perlin[x0][y0][z0], perlin[x1][y0][z0], perlin[x2][y0][z0], perlin[x3][y0][z0]);
    				p1 = tricint(dx, perlin[x0][y1][z0], perlin[x1][y1][z0], perlin[x2][y1][z0], perlin[x3][y1][z0]);
    				p2 = tricint(dx, perlin[x0][y2][z0], perlin[x1][y2][z0], perlin[x2][y2][z0], perlin[x3][y2][z0]);
    				p3 = tricint(dx, perlin[x0][y3][z0], perlin[x1][y3][z0], perlin[x2][y3][z0], perlin[x3][y3][z0]);
    				pa = tricint(dy, p0, p1, p2, p3);
    
    				p0 = tricint(dx, perlin[x0][y0][z1], perlin[x1][y0][z1], perlin[x2][y0][z1], perlin[x3][y0][z1]);
    				p1 = tricint(dx, perlin[x0][y1][z1], perlin[x1][y1][z1], perlin[x2][y1][z1], perlin[x3][y1][z1]);
    				p2 = tricint(dx, perlin[x0][y2][z1], perlin[x1][y2][z1], perlin[x2][y2][z1], perlin[x3][y2][z1]);
    				p3 = tricint(dx, perlin[x0][y3][z1], perlin[x1][y3][z1], perlin[x2][y3][z1], perlin[x3][y3][z1]);
    				pb = tricint(dy, p0, p1, p2, p3);
    
    				p0 = tricint(dx, perlin[x0][y0][z2], perlin[x1][y0][z2], perlin[x2][y0][z2], perlin[x3][y0][z2]);
    				p1 = tricint(dx, perlin[x0][y1][z2], perlin[x1][y1][z2], perlin[x2][y1][z2], perlin[x3][y1][z2]);
    				p2 = tricint(dx, perlin[x0][y2][z2], perlin[x1][y2][z2], perlin[x2][y2][z2], perlin[x3][y2][z2]);
    				p3 = tricint(dx, perlin[x0][y3][z2], perlin[x1][y3][z2], perlin[x2][y3][z2], perlin[x3][y3][z2]);
    				pc = tricint(dy, p0, p1, p2, p3);
    
    				p0 = tricint(dx, perlin[x0][y0][z3], perlin[x1][y0][z3], perlin[x2][y0][z3], perlin[x3][y0][z3]);
    				p1 = tricint(dx, perlin[x0][y1][z3], perlin[x1][y1][z3], perlin[x2][y1][z3], perlin[x3][y1][z3]);
    				p2 = tricint(dx, perlin[x0][y2][z3], perlin[x1][y2][z3], perlin[x2][y2][z3], perlin[x3][y2][z3]);
    				p3 = tricint(dx, perlin[x0][y3][z3], perlin[x1][y3][z3], perlin[x2][y3][z3], perlin[x3][y3][z3]);
    				pd = tricint(dy, p0, p1, p2, p3);
    
    				o = tricint(dz, pa, pb, pc, pd);
    				if (j < 2) {
    					sum += o * pn2[j + 1];
    				}
    				else {
    					if (o > 32767.5f) o = 65535.f - o;
    					sum += o * pn2[j];
    				}
    			}
    			sum *= sumdiv;
    			i = (int)sum;
    			if (i < 0) i = 0;
    			else if (i > 65535) i = 65535;
    			hf[hu][x][y] = i >> 8;
    	}	}
    wow, that gradient b/g makes code a trip :p

    (realsiing that i ought to add latitudinal rotation as well as it only needs to be performed for each pixel, not each octave..)
    Last edited by xoxos; 06-07-2012 at 02:21 PM.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •