Wednesday, November 11, 2015

Realtime Heightmap Generation using Mandlebrot Set.

Something I read in a Fractal textbook. It had an example of Fractal compression of a photo. Output was similar to jpeg but the compression ratio was off scale.

To generate the Mandlebrot set only 3 numbers are needed. The x and y position for the centre of the output. And a depth or zoom value that magnifies the set.

As you have seen an image 1024x1024 which is 1048576 numbers can be created from 3 numbers. So far the Mandlebrot set is only good at producing dendrites. But dendrites exist in most natural structures so it's still a handy tool.

This is the best place to find dendrites.
Here is a couple of the billions there would be.


Monday, November 9, 2015

Realtime Heightmap Generation using Sandsim 3D

Was playing sugar sugar 2, a few years ago and at the time wondered if the sand simulation was done by a series of patterns or calculated.
I was able to create some code to simulate sand.

This is the 2D part of the 3D sand simulator. It is very useful for creating landscapes, it has the added benefit of settling around rocks in a natural and realistic looking way. You just need to create a basic rock landscape and the sand falls from the ceiling and covers the landscape. Creates rock cliff faces automatically.
Here is a screenshot of the first basic test to see if it worked in 3D.
 Creates nice looking dirt mounds, and ridges.

*Update: This also can be used as a very useful path finding system. A majority rule space filling CA would be more efficient. 

Saturday, November 7, 2015

Realtime Heightmap Generation using DCT's

OK this one has been the holy grail for me. Compressing data and then uncompressing data in realtime.

Well now I think it maybe possible with simplified DCT's. I am using the definition of DCT-II and DCT-III from Wikipedia. There are more accurate variations out there but this a good start for anyone wanting to know about DCT's

Here is the code:

Do you notice the >>2 at the end of each decoding? This is multiplying the DCT-III by 1 / √2N, in Wikipedia it says this step is optional but clearly it is completely necessary.
  
And here is the output:
I have skipped the quantize step because that is where the optimizations come from.
Notice the outputted values are within 15% of the values from the original. The chances of me guessing a number sequence within 15% of the original sequence is 1 * 10 ^ 18 or 1000000000000000000 to 1!

Here is a graph showing the space from 0 to 255 and the original values (red) vs. the computed values (blue). They are very close indeed.
The DCT is a wonder of the modern world!

By centering the data at 128 (subtracting 128 from each value) the results are amazing.
The results are almost perfect.

OK so k = 0,1,2,3,4,5,6,7. So what would happen if I was to use smaller 0.015625 increments. This turns 8 numbers into 512 numbers. Massive amount of compression.
The output is very impressive exactly what I was hoping for.
So now using this code you can convert Google Earth Elevations into 8 numbers! Exactly what I wanted.

Saturday, October 10, 2015

Chrome Cast + Android = Nintendo Wii


This is a great piece of technology. If you have a wizbang new Smart TV you don't need it. However for non-smart tv's this is an essential piece of hardware. You can watch YouTube in HD on your TV.

However from my tests it is clear that with the accelerometer you can use it to make a light gun or a Nintendo Wii controller. Here is a photo of the VR engine running on my TV.


A very impressive idea by Google. You have to have WiFi for it to work, which could get expensive so a bluetooth option would be a good idea.

Monday, July 27, 2015

Web Workers

OK this will be a big post.
Web workers allow us access to other threads. Threads can be processed by idle processors within the CPU architecture. Multi-processor systems use the same battery power regardless of how many processors are being used, so multi-threading is crucial in battery powered devices.
Lets get to it.

This is from W3SCHOOLS.

First a worker has to exist!
We create a web worker script called "demo_workers.js".


This is the HTML5 code to implement the worker.

The problem is the worker continually processes this code. We need more control over our workers.
This is from HTML5 UNLEASHED.
And here is the workers .JS file.
This is a different usage of web workers. Instead of being continually processed the worker is only called when we need to use it.

OK so lets try and get a worker thread to draw to a canvas.
And here is the workers .JS file.
OK as you can see, A canvas is created then we get a 32-bit Typed Array called dat. I am not passing the array to the worker because this will be the final engine that will render Graph3D.
Instead I am going to pass positionx, positiony,positionz,rotationx,rotationy, and rotationz.
Only 6 numbers are sent to the worker this is very efficient.
The worker .JS file, creates a Typed Array called wdat. The first time the worker runs it creates the array, then it processes the 'message'.

A pixel in the canvas has the format
ALPHA << 24 | BLUE<<16|GREEN<<8|RED.
So the alpha value is the color RED.
The canvas has a BLUE color as it starts:
After the button is clicked the Worker writes the color red to all pixels on the canvas.
This is a good start.

If you enter the code yourself you will notice you have to press the button twice. This is because the message is sent to the worker and the canvas putImageData function draws to the canvas before the worker updates it. To fix this place putImageData in the worker onmessage function like so:
Now when the button is pressed the canvas updates almost instantly. Was worried about how fast it would render, at the moment it is fast enough for my needs.

Works on FireFox and Microsoft Edge, however on Chrome as usual you will get this error.
A possible way to fix this is with the new FILESYSTEM API or buy a domain and set the domain up and get it running just to test a basic scenario. This is a CORS error, use python simple server to serve files to localhost. CORS is a very important internet security system, do not try to circumvent it. Apologies to Google.

OK wrote a version that sends the ImageData to a worker processes it and sends it back. The version I have described is at least 2 times faster. Has a slight problem with synchronization but is much faster. And on my i7 lightening fast.

Have to write a structured cloning version but GC can be expensive, may use the above version.

So now I have FOUR CORES writing to the canvas.
However the UI creates a border around each canvas. The documents body needs a margin of 0.
Also the canvas display needs to be blocked.
Now we have a complete fullscreen written to by FOUR processors.
This will be the final renderer. The most important part is the 3D engine only does 25% of the processing. This will be a massive optimization.

Here is Graph3D with a single processor.
Between 5 FPS - 11 FPS.

And with FOUR processors.
Between 24 FPS - 60 FPS. An immense increase in rendering performance.

** Update **
On an i5 the results are very poor, on an i7 the results are very impressive.


BASE 64

Ok here's another handy way to add image data to your HTML app.
It's the actual JPEG stream, just give it to the IMG tag and...
The textarea will contain the dataURL stream. Just select-all and copy, paste it into IMG tag's SRC propety.

Tuesday, July 21, 2015

Virtual Reality

By placing the accelerometer output directly into graph3d I was able to construct virtual reality instantly.
The accelerometer values of alpha: beta: gamma: are in degrees. Simply multiply the degrees by one radian which is 0.0174532925 to get the radians.

Here is graph3d with the phone looking down at the ground.

Here is graph3d with the phone looking at the roof. Works very well.
I am getting a keyboard for my LG and will be making a virtual reality demo.
Keep you posted.

Sunday, July 12, 2015

3D Rotations

Up until now I have used a 3D camera based on a tripod. Useful for FPS shooters and motor vehicle models. But jet fighter and space ship models require true 3D ZYX rotations. Before I show you the javascript code I have to explain how it works.
This diagram roughly shows the viewport pyramid. The camera or eye is situated at the near plane. At the back plane are three values, tx, rx, and lx. From these three points I can interpolate every co-ordinate within the pyramid. Here is the javascript code.

And here is the output in graph3d. I just made two voxel planes. And did some y and z rotations.

Note the viewing pyramid is 320 x 204 and has 256 slices.

Saturday, July 11, 2015

The Accelerometer

This is the most revolutionary technological advance made in many years. The accelerometer!
Heres the code, remove the title tag or it won't work.
And here it is working on an android phone!
Bare with me, about to show you something amazing.

Saturday, July 4, 2015

Device Camera Pixel Manipulation

This is one of the latest additions to HTML5 and is incredibly useful. Can lead to augmented reality and image recognition.


Here is the code.


Uses most of the elements I have made posts about up until now.
First you will be asked to share the device. Click on share selected device and....

Here it is on FireFox.

Here it is on Microsoft Edge ( very cool ).

The canvas is filled with the devices video. You can then write to dat to add images to the video.
Notice at the top the camera icon? Click this and you can stop the device. That's why the event handlers are there to make sure the canvas isn't written to while video is not streaming.

(Sending video to a domain will allow it to work on Chrome)

Pixel Animation

 *** viewport is used by javascript, use the var name vp instead ***

Was trying to animate the mandelbrot set and it just wouldn't work. Turned on the debugger and found that the var screen was undefined. Replaced it with the word viewport and voila!

Notice I have moved all the canvas variables into global scope. This way the canvas and buffer stays "alive" throughout the life of the application.
After a few seconds the renderer has zoomed in on this.

Thursday, July 2, 2015

Pixel Manipulation

 *** viewport is now used by javascript use the var name vp instead ***

Ok lets have a look at the code.


It's the previous mandelbrot renderer. It has a slight difference. Notice that a new array has been created called dat. It is a typed array of type Int32. It is "attached" to the ImageData object called viewport. Specifically the viewport.data.buffer object. When you write to the new array the viewport array is updated. Also notice that there is less code to write!
Works on FireFox.
Works on Internet Explorer.
Works on Google Chrome.
Works on Android.