Tag: pattern

  • Worley noise cellular texturing

    Worley noise cellular texturing

    There are some quite well known procedural content generation algorithms out there: Voronoi, Perlin noise, simplex noise, L-systems, reaction-diffusion systems like Turing pattern, which I’ve presented in my earlier blog post.The specifics of these algorithms are that either generates a large amount of content for a small investment of input data, or one that adds structure to random noise.

    Generally speaking they are categorized by what they generate (map vs sequence generation) and also by the mindset behind their use. This time we’ll discuss the Worley noise pattern, which can be included into the generative map creation category. This means we need a grid system for the representation and visualization of points scattered randomly in 3D or 2D space.

    In it’s visual appearance is almost like a Voronoi diagram, only it’s not as famous like it’s counterpart. Even Wikipedia discuss it very briefly. Worley noise in it’s essence is a noise generation pattern, which means by multiplication/addition of different octaves of the same noise pattern we can produce a variety and completely different outputs. This is the fun part of working with generative patterns.

    Now, after we gain a little theoretical introduction let’s get started with the basics, and try to dissect how can we reproduce those organic shapes and textures found in every living being in nature. (In parentheses being said, in many graphic simulations and parametric applications dealing with textural visualizations this shapes can be found). As a last side note before we go into the technical details, my intention was to implement the algorithm in Javascript mainly because i wished to be accessible by as many users as possible, and at the same time i was curious how far can i stress the limit of the modern web browsers. This is an experiment based 100% on CPU, so WebGL was out of scope, only because i was not playing with this technology until now, but i considering to implement on GPU in a shorter or longer future.

    Feature points

    The basic idea is to spread randomly varying number in space and calculate the distance to these point from every possible location of space. As a complement, Worley suggest to assign to each feature point an unique ID number. This number can be used to generate surface with colored areas or crocodile like textures, cityblock diagrams etc. depending on the algorithm, or coloring function implemented.

    The noise function simply computes a single value for every location in space. We can then use that value in literally thousands of interesting ways, such as perturbing an existing pattern spatially, mapping directly to a density or color or adding multiple scale of noise to make a fractal combination. While there are infinite number of possible functions which provide an infinite number of outputs, noise’s random behavior gives a much more interesting appearance  then simple gradients for example.

    By spreading  feature points randomly through the 3D space we build a scalar function based on the distribution of the points near the sample location. Because an image worth a thousand of words the picture below describes a space with feature points scattered across the plane.

    For a position on the plane (marked with x in the picture above) there is always a closest feature point, a second closest, a third and so on. The algorithm is searching for such feature points, return  their relative distance to the target point, their position and their unique ID number.

    Another key component of the algorithm is the demarcation line which is supposed to be integer in every plane. Each squares (cubes in 3D) are positioned so that their identification numbers can be expressed with some integer values. Let’s suppose we want to obtain the distance to the two feature point closest to the (3.6, 5.7) we start by looking at the integer squares (3, 5) and compare it’s feature points to each other.  It’s obvius that the two feature points in that square aren’t the two closest. One of them is, but the second closest belongs to the integer square (3, 6).

    It’s possible that some feature points are not inside the square where the target point is placed, in this case we extend our analysis to the adjacent squares. We could just test all 26 immediate neighboring cubes, but by checking the closest distance we’ve computed so far (our tentative n-th closest feature distance) we can throw out whole rows of cubes at once by deciding when no point in the neighbor cube could possibly contribute to our list. We don’t know yet what points are in the adjacent cubes marked by “?,” but if we examine a circle of radius F1, we can see that it’s possible that the cubes labeled A, B, and C might contribute a closer feature point, so we have to check them. As resulted from the image below, it’s mostly possible to check 6 facing neighbors of center cube (these are the closest and most likely to have a close feature point), 12 edge cube and 8 corner cubes in 3D. We could start testing more distant cubes, but it’s much more convenient to just use a high enough density to ensure that the central 27 are sufficient.

    The code implementation in Javascript

    For the code implementation i used html5 canvas. I’ve commented the source code, so won’t be too hard to follow for anyone. Because (as i mentioned in the beginning) my WebGL knowledge is quite minimal, for this reason i tried to optimize every single bit of code. For this reason my single option was to use web workers by separating the main core from the computationally heavy and intense pixel manipulation logic. There is a well described article on html5rocks.com about the basic principles of web workers, followed by some very neat examples regarding the implementation of them.

    The main advantage of using web workers is that we can eliminate the bottlenecks caused by computational heavy threads running in the background, separating the implementation interface from the computational logic. This way we can reduce the hangouts caused by intensive calculations which may block the UI or script to handle the user interaction.

    Creating a web worker is quite simple. We define the variables we want to pass to workers, and by calling an event listener using postMessage function we transfer the main tread instructions to the worker (which is running in a separate thread). Because web workers run in isolated threads, the code that they execute needs to be contained in a separate file. But before we do that, the first thing we have to do is create a new Worker object in our main page. The constructor takes the name of the worker script:

    In  a separate script we’ll define wich are the variables we want to listen for. This part is responsible for the heavy weight operations. After the pixel calculations has been done, we pass over the results through the postMessage method to the main thread. This part of code looks like the following:

    As a last option i’ve included the DAT.GUI lightweight graphical interface for a user interaction, where we can select different methods, colors etc. and lastly to offer the possibility for rendering with or without web workers.

    Hopefully you find interesting this experiment, and if you have some remarks, comments, then please use the comments field below, or share through twitter.

  • Organic Turing Pattern

    Organic Turing Pattern

    In this post i will present an experiment which i did a few months earlier, but because lately i was pretty occupied with various job related activities and with setting up this new blog (transferring the old content to the new host – plus a lot of other stuff), i have no time to publish this new experiment. More about below, but until then a few words about the background, inspiration and some of the key challenge i have faced during this process.

    This is an experiment inspired by a thoroughly explained article about the concept behind what is generally known as Turing Pattern. The Turing Patterns has become a key attraction in fact thanks to Jonathan McCabe popular paper Cyclic Symmetric Mutli-Scale Turing Patterns in which he explains the process behind the image generation algorithm like that one below, about what Frederik Vanhoutte know as W:blut wrote on his post:

    Quote leftIf you’ve seen any real­ity zoo/wild-life pro­gram you’ll rec­og­nize this. Five min­utes into the show you’re con­fronted with a wounded, mag­nif­i­cent ani­mal, held in cap­tiv­ity so its care­tak­ers can nur­ture and feed it. And inevitably, after three com­mer­cial breaks, they release it, teary-eyed, back into the wild. It’s a piv­otal moment that turns their leop­ard into anyone’s/no one’s leop­ard.Quote right

    That’s the feeling which emanates when you first see the organic like, somehow obscure (some may go even further and say: macabre or creepy) thing which is known as a Turing pattern. At first moment when you are confronted with it, some kind of emotion (be that fear or amazement or just a sight) is resurfaced. Definitely won’t let you neutral.

    This is the emotion which pushed me to try to implement it in Actionscript. (In parentheses be said this is not the best platform for computation intensive experiments.) Felix Woitzel did an amazing remake adaptation of the original pattern in WebGL. The performance with a good GPU is quite impressive. Maybe in the future i will try to port in WebGL. Anyway, there is another nice article by Jason Rampe, where he explains the algorithm of the Turing Pattern.

    So let’s face directly and dissect the core components of the algorithm.

    The basic concept

    The process is based on a series of different “turing” scales. Each scale has different values for activator, inhibitor, radius, amount and levels. We use a two dimensional grid which will be the basic container for activator, inhibitor and variations, all of them going to be of typed arrays (in our case Vectors.<>). At the first phase we will initialize the grid with random points between -1 and 1. In the next step we have to determine the shape of the pattern. For this case w’ll use a formula defined by the following method:

    for (var i:int = 0; i < levels; i++)
    {
    	var radius:int = int(Math.pow(base, i));
    	_radii[i] = radius;
    	_stepSizes[i] = Math.log(radius) * stepScale + stepOffset;
    }

    During each step of simulation we have to execute the following methods:

    1. Populate the grid with pixels at random locations. I’m gonna use a linked list to store the pixels properties: positions and colors. We will loop through all the pixels, the number of pixels will be defined by the grid with x height dimension.
    2. Average each grid cell location over a circular radius specified by activator, then store the results in the activator array, multiplied by the weight.
    3. Average each grid cell location over a circular radius specified by inhibitor, then store the results in the activator array, multiplied by the weight.
    4. In the next step we need to calculate the absolute difference between the activator and inhibitor using the the following formula: variations = variations + abs(activator[x,y] - inhibitor[x,y])

    Once we have all the activator, inhibitor and variations values calculated for each grid cells we proceed with updating the grids as follows:

    1. Find which grid cell has the lowest variation value
    2. Once we found the lowest variation value we update the grid by the following formula:
    for (var l:Number = 0; l < levels - 1; l++)
    {
    	var radius:int = int(_radii[l]);
    	fastBlur(activator, inhibitor, _blurBuffer, WIDTH, HEIGHT, radius);
    
    	//calculates the absolute difference between activator and inhibitor
    
    	for (var i:int = 0; i < n; i++)
    	{
    		_variations[i] = activator[i] - inhibitor[i];
    		if (_variations[i] < 0)
    		{
    			_variations[i] = -_variations[i];
    		}
    	}
    
    	//if first level then set some initial values for bestLevel and bestVariation 
    	if (l == 0)
    	{
    		for (i = 0; i < n; i++)
    		{
    			_bestVariation[i] = _variations[i];
    			_bestLevel[i] = l;
    			_directions[i] = activator[i] > inhibitor[i];
    		}
    		activator = _diffRight;
    		inhibitor = _diffLeft;
    	}
    	else
    	{
    		for (i = 0; i < n; i++)
    		{
    			if (_variations[i] < _bestVariation[i])
    			{
    				_bestVariation[i] = _variations[i];
    				_bestLevel[i] = l;
    				_directions[i] = activator[i] > inhibitor[i];
    
    			}
    		}
    		var swap:Vector. = activator;
    		activator = inhibitor;
    		inhibitor = swap;
    	}
    }

    As a last step we should average the gap between the levels by performing a blur technique for a nicer transition. We blur the image sequentially in two steps: first we blur the image vertically then horizontally.

    The challenge

    The most challenging part was related to the unknown factor about how well gonna handle the AVM2 the intensive CPU calculation. Well as you may have guessed not too well, especially with very large bitmap dimension and a lot of pixels needed to be manipulated, plus the extra performance loss “gained” after the bluring operation.

    For some kind of compensation benefits (in terms of performance) i decided to populate the BitmapData with a chained loop using single linked list, plus typed arrays as generally known the Vector.<> arrays are much faster compared to the traditional array stacks. After a not too impressive performance, i wondered how can i even more optimize the code for a better overcome. I decided to give it a try to Alchemy, and Joa Ebert’s TDSI, a Java based Actionscript compiler, as by that time was commonly known a better choice over AVM. Unfortunately i didn’t get too many support and helpful articles about the implementation and as a consequence my attempt was a failure, which resulted in a quite buggy and ugly output. After too many attempts without the wishful result, i gave up.

    That’s all in big steps. You can grab the source code from here. Feel free to post your remarks.

    ps: Be prepared this experiment will burn your CPU. 🙂