29a.ch

Entries in the Category “Programming”

Chrome and Safari don't cache html5 audio

Chrome and Safari seem to ignore the http cache headers for html5 audio files. When you are programming a game that can be fatal. First it delays the playback, second you get at least one http request per play(). So what can you do? Write a html5 Cache Manifest!

Also at least chrome seems to have a limit on the number of <audio> elements that can be created. You notice the problem when you call play() on an audio file and nothing happens anymore. My solution to this was to create a pool for audio elements for reuse.

With those two techniques I'm now able recreate the sound of a gatling gun by playing individual bullet shots, yay!

Javascript Galaxy Simulation

This is an older demo I did a while ago but haven't published yet. It's pretty slow unoptimized and hackish and the projection is wrong and I don't feel like fixing it. But it still looks cool! So thought I should publish it anyway.

What does it do? It simulates a spiral galaxy with 5000 stars.

Demo

screenshot

Click the screenshot to start the demo. It's pretty slow in firefox, works well in chrome.

How it works

Doing calculating the gravitational forces for 5000 particles in realtime using javascript is hard, and it would probably be quite hard to get stable spirals. So I cheated a little (a lot actually). To simulate the slowdown of the motion of stars in more dense areas I'm simply using a texture:

skymap

That's pretty much it: Generate a bunch of stars spinning around a center and modulate their speed according to the density map. Feel free to take a look at the source, but remember, I told you that it's a mess and all wrong.

Other Experiments

Be sure to check out my other experiments too.

Demonstrating evolution in 999b

When I saw the JS1K demo contest I knew I had to enter. I first tried to do some GFX demo, but I was lacking an impressive idea. So when I tried to sleep last night at 2 in the morning I had an idea which I needed to implement: Demonstrating evolution by natural selection in 999b/666b gzipped:

x = ('var_a=Math,b=a.random,c=document.g'+
'etElementById("c"),e=c.getContext("2d")'+
',f=[],g=b()*		 16777216<<0,h,i'+
',j,k,l=(g		  &16711680)>>16'+
',m=(g&65		    280)>>8,n=g&'+
'255,o,p		    ;c.width=320'+
';c.height=320;		    e.shadowBlur'+
'=10;for /* */	      (p=   0;p<64;p++)f'+
'.push(b(		    )*16777216<<'+
'0);func		    tion_q(d){fo'+
'r(d=d.t oStr		  ing(16);d.leng'+
'th<6;)			d = " 0"+d;retur'+
'n"#"+		      d } d ocument.body'+
'.sty		     l e .b a c kground='+
'q(g);		    setInterval(function'+
'(){e.		 c l e a r R e c t ( 0 ,'+
'0,320,		3 2 0 ) ; f o r ( p = 0 '+
';p<64;	    p + + ) { h = f [ p ] ; i = '+
'l-((h&	  1 6 7 1 1 6 8 0 ) > > 1 6 ) ;j'+
"=m-((h&65 2 8 0 ) > > 8 ) ; k = n - ( h"+
'&255);o=a.sqrt(i*i+j*j+k*k)/443;if(b()<'+
"o)h=f[p]=(f[b()*64<<0]&16773120|f[b()*6"+
'4<<0]&4095)^1<<(b()*24<<0);e.fillStyle='+
"q(h);e.fillRect(1+p%8<<5,1+p/8<<5,32,32"+
')}},100);e.shadowColor="#000";').replace(
/\s/g,"").replace(/_/g,' ');eval(x);
/*evolution in 999b by 29a.ch**/

+1 if you recognize that guy.

Demo

It's basically a few cells colored cells. The selection criteria is the color difference between the cell and the background. So cells that stand out have a higher chance of getting eaten.

Click me

How it works

You can see the full unminimized sourcecode here evolution.js I'll only explain the meaty stuff.

env = random()*(1<<24)<<0,
...
population.push(random()*(1<<24)<<0)

A random environment and population is initialized. The shift by 0 is a short way to round a number. Both the environment and the genes of the population are random 24 bit integers, that can be viewed as rgb colors.

subject=population[i];
r = r_-((subject&0xff0000)>>16);
g = g_-((subject&0xff00)>>8);
b = b_-(subject&0xff);
distance=M.sqrt(r*r+g*g+b*b)/443;
if(random()<distance){

The fitness for survival is determined by measuring the distance between the color of the individual and the environment. The lower the distance, the higher the chance for survival.

subject = population[i] = (
                // breed
                ((population[random()*popsize<<0]&0xfff000)|
                (population[random()*popsize<<0]&0xfff))
                // Mutate
                ^(1<<(random()*24<<0))
            );

When an individual dies, a new one is bred by sexual reproduction (parthenogenesis and necrophilia are possible as well). The new individual then gets one random mutation. That's pretty much all there is to it.

Mandelbulb

The Mandelbulb is a 3D Version of the Mandelbrot fractal. I have written my own renderer for this a little while back. I don't think the source is of much interest, as you can find better implementations around.

If that caught your interest you can find more information and pictures of the Mandelbulb on the website of Daniel White.

Realtime Raytracing in Javascript!

Yes we can! Thanks to the performance of modern javascript engines like V8 it is now possible to do realtime raytracing in javascript.

Demo

This demo requires a quick modern browser with support for the canvas tag and a fast computer. Google chrome seems to work best. Firefox is too slow. If it doesn't work make sure that your browser is not zooming in (hit ctrl+0 in chrome and firefox).

How it works

cubemap The frames are renderer using a technique called raytracing. The environment is mapped using cube mapping. I store all the values of the cubemap as floats. I increase the definition range by multiplying all values bigger than 0.95 with 2. This makes sure that the bright parts of the image are also very bright in the reflections. You can think of this as faking hdr. I do not calculate any lighting, it is all coming from the environment map. To make the animation look a bit more fluid and hide the aliasing I apply some fake motion blur by blending the current frame with the previous one. Feel free to ask questions if you want to know more.

Source

You can view the sourcecode here: rtrt.js. Feel free to copy from it, but please let me know if you use it for something cool. :) Also beware that the code is pretty hacky and unpolished.

Other Experiments

Be sure to check out my other experiments too. If you like what you saw you should subscribe to my newsfeed or follow me on twitter.

Credits

The environment map was created by Paul Debevec of the ICT Graphics lab. You can find his collection of light probes here. Thanks for letting me use it.

HTTP Ripper 1.1.0 released

logoI have finally made a new HTTP Ripper release. For those who don't know, HTTP Ripper is a tool that acts as http proxy to get (media) files out of websites. It is now translated into 42 languages. That's 40 languages more than I speak! The git repository has been moved over to over to github, play it slowly is now also there. Feel free to fork them.

HTTP Ripper Website

Path tracing a cornell box in Javascript

Last Saturday I have released my little javascript pathtracer that rendered a very simple scene. This time I want to show off some of the more advanced effects that can be simulated nicely using path tracing. I decided to set up a scene similar to the well known Cornell Box to demonstrate effects such as soft shadows, color bleeding, reflection, refraction and caustics. I did not include Depth of Field in this experiment because it didn't fit the scene well in my opinion.

The experiment

cornell box

Click the image to start the rendering. Warning, this experiment is slow. Run it using a fast web browser (google chrome) and be a little bit patient. Opera won't work because it doesn't support web workers.

You might also want to check out my previous path tracing experiment.

Path tracing

Path tracing is a way of solving the rendering equation using monte carlo integration. It is a form of ray tracing. According to wikipedia 'Path tracing is the simplest, most physically-accurate and slowest rendering method'. Sounds like the perfect target for a javascript experiment!

Implementation

The implementation is basically an extended version of the path tracer in my last post. It is using html5 web workers to render the image on up to 4 cores without locking up the page. One of the cool things I came up with is jittering the points on the view plane for each pixel to get rid of aliasing. I also changed the color of the light to that of warm sunlight (~5400k). I probably got the fresnel equations wrong and generally things are quite rough. I'm not an expert in the field of raytracing and I probably did a lot of things in a suboptimal way. But feel free to have a look at the source code (~300 LOC) and ask questions. I think the code should be quite easy to understand.

Please write a comment if you've got anything to say. If you think my experiments are interesting, follow me on twitter or subscribe to my atom feed.

Path tracing in Javascript using web workers

Improved version

An improved version of this path tracer is available here.

The experiment

screenshot

Click to start. If it doesn't work in your browser and it's not IE or Opera, please write a comment. The output of the javascript error console would be very helpful too.

Path tracing

Path tracing is a way of solving the rendering equation using monte carlo integration. It is a form of ray tracing. According to wikipedia 'Path tracing is the simplest, most physically-accurate and slowest rendering method'. Sounds like the perfect target for a javascript experiment!

Implementation

My implementation is currently only calculating the diffuse term of the rendering equation. The only light source is the sky. The big sky speeds up the rendering and convergence quite a lot.

The sourcecode is split up into two files. main.js is the glue for initializing the workers and aggregating the results. worker.js is where you'll find the real meat. I'm spawning four workers right now to take advantage of modern multicore cpus. Feel free to ask questions if something is unclear.

Performance

As you can tell from the sourcecode it is clearly not optimized for performance. What is still interesting though is how various webbrowsers perform. On my Intel Core i7 machine google chrome (4.1) is roughly 26 times faster than firefox (3.6)! Chrome does 13 iterations/s, Firefox does 0.5. Also firefox seems to support only 3 workers, this leaves one core almost idle. The dev version of chrome is even faster at 18.75 iterations/s. My congratulations to the chrome and v8 developers. I hope firefox will catch up soon.

Twitter

On a side note, I created a twitter account for those who prefer it over the rss/atom feeds.
Follow 29a_ch on Twitter

Update

I found a little bug in the code that affected the performance. I'm now getting more than 20.5 iterations/s in chrome dev. I think a faster random function would make it even faster.

Box2Dflash Version 2.0 ported Javascript

Please note that this is experimental code!

Some weeks ago I wrote a script to convert version 2.0.2 of Box2DFlash to Javascript. I hesitated to release it because it is basically one big nasty hack that just happens to work. But as I got a few requests for it so I decided to release it. Please let me know if you do something with it. :)

Demo

Screenshot

You can see a demo of it in action here. You can click to trigger an explosion. On my notebook the demo runs fluidly in chrome. In firefox 3.5 it is pretty slow. In the current nightly it runs smooth as well. So I guess firefox is slowly catching up. Oh and just forget about IE.

Approach

At first thought this conversion would be trivial as both actionscript and javascript are dialects of ECMAScript. Well, I was wrong. Nevertheless I continued to follow my regex based approach, basically trying to ram my head through a wall. After a few attempts I succeeded to convert Box2DAS3 to javascript. It had a nasty bug tough. Two solid cubes were able to penetrate each other when the fell on their edges. The reason? ActionScript supports 'properties'. I didn't know about this and the conversion script does not support it. In the end I fixed the few properties in the translated code by hand because I was to lazy to add support for getters and setters to the conversion script. Now it seems to work pretty well. Please keep in mind, this is not a generic actionscript to javascript compiler, it's just a script that happens to work for box2dflash.

The explosions in the demo are simulated by shooting out a few tracer particles with a high density and velocity. The benefit over just applying an impulse to each object is that the strength of the impulse is proportional to the surface area. Also the force of the explosion will to some extend be redirected to the side by the floor. When using this in production code you would probably want to destroy this tracer particles after their first collision or a few seconds.

Please keep in mind, I'm not an expert on the subject. There are probably better and faster ways to approximate this than my crude way of using tracer particles (Navier-Stokes in javascript anybody? ;) ). Maybe I'll try to do some fluid dynamics on the gpu using webgl some day. It would be cool for sure.

Compiled Script

I compiled a single file version of the script using googles closure compiler. box2d.js.

Complete Zip

The zip file contains the actionscript source, the conversion script and a patch to fix some of the things the conversion script misses. box2d2.zip

Github

github.com/jwagner/box2d2-js

Documentation

I didn't write any. But you can use the documentation of box2dflash.

Simulating Fire using Javascript and Canvas

This is another javascript effect I did. I might use it on the loading screen of my next javascript game as it doesn't need any textures (just like the starfield in jswars). It's based on an effect I wrote about 6? years ago. Sadly the canvas tag doesn't support palettes natively and mapping the colors in javscript too slow so the colors look less than optimal. Also chrome seems to render the result differently from firefox. This could be related to this issue.

Demo

Click the image to start the effect

How it works

Basically there are two maps, the heat map and the cooldown map. The cooldown map is generated using a noise function similar to perlin noise.

the noisemap

The noise texture is generated by first randomizing the alpha values and then drawing scaled versions of the noise texture onto itself. The high frequency noise was increased to create more flickering in the flames. The heat map is what you see before you click on the example. The algorithm then basically works like this:

  1. Noise is draw on top of image to cool it down
  2. The whole image is shifted up one row
  3. The heat map is applied to 'heat up' the pixels

For more details just read the source and feel free to ask questions.

Author

Jonas Wagner Jonas Wagner
Software Engineer
Zürich, Switzerland

More about me

Follow 29a_ch on Twitter

Experiments

screenshot screenshot screenshot screenshot

More Experiments

Latest Posts Tags Archive Links

guitarmasterclass.net (guitar lessons)