I would really like to get some nice random 2D noise functions on the Arduboy. The most important would be white noise and Perlin. Worley noise would also be nice.
This is different from just using the random() function. This would need to take in x and y coordinates and a seed, and always return the same random result given the same inputs. And it would need to be tiny enough to fit on the Arduboy but robust enough to not produce humanly recognizable repeating patterns.
The limited system resources of the Arduboy make this sort of math especially necessary, since storing level maps is going to severely limit map size, but procedural generation should let you have really big, perhaps psuedo-infinite maps / play spaces.
Ah, you can create an array, or just a page and during a tick, draw the offscreen array (buffer) to screen, or re-seed one page and loop over the buffer copying the page to the image buffer.
Generating a new random byte(integer) value and popping off the bits for that integer to be used in filling the image buffer, 8 pixels at a time, should do the trick.
I will need the image buffer for drawing images. Besides, what if I want more area than the image buffer holds? This really should be something which happens in a math function.
The image buffer is just a chunk of memory holding bytes. Any block of memory can be used to hold an âoffscreenâ image buffer, space allowing of course.
One could also override the library itself to change how the size of the image buffer or add a second buffer into the main Arduboy class.
I have a few implementations of perlin around, it might be fun to just put a demo out with all these drawing techniques, or a demo per technique.
Both might be good. The one demo with every technique would be good to put on oneâs arduboy to get a sense of whatâs possible, but the demos for each technique would be good as educational code because you want code examples to be self contained and easy to interpret so as to distinguish relevant code from other stuff.
But as far as for what I am envisioning however, caching the play space at all would defeat the purpose. The purpose is to enable larger play spaces than storage capacity allows to be held in memory.
I always thought perlin was one of the greatest learning examples out there. Not only is it mathematically interesting, but it can be used to create all sorts of effects quickly.
Yeah for sure, but you will always need memory allocated to start to run your procedural generation. There will always be some overhear associated with generating your new scenery. The trick would be to use that memory cleverly. So when you go to generate a new int, you will be allocating a byte anyway. Simply use that integer byte as your âtempâ buffer and right that straight to the arduboy image buffer.
You can also allocated an array for generation, then quickly deallocate it after you are done processing.
@BenMclean, you can either use Ken Perlinâs implementation (he won an academy award for it) and port it, or try some of the more famous implementations as well. There are a handful of techniques that were published about 10-20 years ago, and they havenât changed much.
The 2 and 3 dimension perlins are probably not needed if you are only doing 1-bit color.
generate a random int, copy 8 bits of the byte to the first byte of the image array. gen new int in same memory space and fill the next 8 pixels. Repeat until image buffer array is filled.
You could optimize this by using bit values multiple places and random spots in the full image buffer array. The Fisher-Yates shuffle is an decent way to randomize a full set.
If you want an algorithm, and not an ad-hoc method, try Gaussian noise. I picked one implementation at random, there will be many out there
I am definitely looking for an algorithm, so I can create the illusion of a much larger space, not just another way of filling a fixed size array that I could have filled with a hand crafted level.
Canât you just do some devision of some input, then convert it to bits? You could even XOR some of the data if you wanted, too.
int x := input( int ) //Input a user's number int y := input( int ) //Input a user's number int z := input( int ) //Input a user's number float bignumber := x á ( y á z ) //Save the output of an equation to a float bool binaryrepresentations[ sizeof( bignumber ) Ă 8 ] //Create an array of booleans for( int index < sizeof( bignumber ) Ă 8 ) { //For each bit in the float... binaryrepresentations[ i ] = ( ( 1 << i ) & bignumber ) â 0 ? 1 : 0 //Save the bit into the array }
You could then grab data from that array⌠Or would this take too much RAM?
Thatâs what Iâve been suggesting as well (I think), except just copy the values as they are generated straight to the image buffer. it makes more sense to just fill 8-bits at a time with a random int. Or just use the Gaussian method, thatâs pretty much as good as it gets, with the exception the Gaussian method uses floating points and generates way more fidelity than is needed for 1-bit images.
Popping bits off though will be slower than just copying the bit values onto the array, there shouldnât be a need for bit wise operations. Every random integer is already 8 random bits.
/* Setup constants */
const static int q = 15;
const static float c1 = (1 << q) - 1;
const static float c2 = ((int)(c1 / 3)) + 1;
const static float c3 = 1.f / c1;
/* random number in range 0 - 1 not including 1 */
float random = 0.f;
/* the white noise */
float noise = 0.f;
for (int i = 0; i < numSamples; i++)
{
random = ((float)rand() / (float)(RAND_MAX + 1));
noise = (2.f * ((random * c2) + (random * c2) + (random * c2)) - 3.f * (c2 - 1.f)) * c3;
}
Yes, there are two methods provided in the post you are replying to that are algorithmic in nature and are procedural approaches to generating noise that only uses the buffer provided by the Arduboy library, and do not use any other arrays. The only memory in use will be the stack for function calls and a byte to hold the 8-bits while being worked.