HTML5 canvas: Same code outputs different results in different browsers
Asked Answered
T

2

5

In a simple canvas test I created for performance and quality measurement purposes, a canvas is painted with randomised colors and images during an unlimited period.

A sample is shown here: http://litterific.com/minisite/

Warning: Only open this in Opera or Chrome, the script is pretty heavy can hang up on slow computers, don't leave the script running while you are getting coffee ;)) It is just a rough prototype and did not optimize it.

What I noticed here is that the results as painted by the script (js/asset.js) are different in various browsers. Especially in Opera there is much more "green" in the painting than in Chrome

alt text

code is found here: http://litterific.com/minisite/js/asset.js

My question is:

How this is caused. Different random seeds? Different rounding or different color behavior in Opera?

Note: It is exactly the same script in both browsers, so perhaps you could have a look at it in both Chrome and Opera.

Thelmathem answered 8/10, 2010 at 8:0 Comment(2)
The first thing I'd would try is to use an alternative random number generator for which you can provide a seed, or just use the same pre-generated array of numbers, so that both browsers get the same input.Mitman
I tried this in Firefox 3.6. The performance isn't too bad - it stutters a bit (I'm guessing garbage collection), but there is results, and it's quite reddish, with a bit of black, like Chrome. dl.dropbox.com/u/1722364/Screenshot-3.pngPhebephedra
P
6

It's not random numbers causing the problems, it's "funny" pixel data. Here's the change:

for (i = 0, n = pixels.data.length; i < n; i += 4){
  pixels.data[i + 0] = Math.max(0, Math.min(255, Math.floor(r * f)));
  pixels.data[i + 1] = Math.max(0, Math.min(255, Math.floor(g * f)));
  pixels.data[i + 2] = 0;
  pixels.data[i + 3] = pixels.data[i + 3]; 
}

If you ensure that the pixel values are integers in the right range, Opera works fine.

Oh also, and this is probably obvious, it goes a lot faster if you hoist those multiplications out of the loop.

Paraldehyde answered 11/10, 2010 at 13:58 Comment(3)
I suspected something like this. that means that all values above 255 in pixels.data[0] are put in pixels.data[1] (and multiplied by 255) ? so { pixels.data[0] = 300 } would be the same as { pixels.data[0] = 255, pixels.data[1] = 45 } ? That makes sense since Javascript does not know numeric types between 0 and 255 but only "integers". (in opera's case that makes the array pretty useless, since in opera only the first pixeldata needs to be filled, bit like colors in C# or PHP.) but is somewhat "fixed" in Chrome. I also dumped this question at Opera, perhaps it's some sort of unfinished issue.Thelmathem
I'm not sure what happens; you may be correct that the value "spills" into other color cells, but it's hard to say exactly. (I suppose you could figure it out by experimentation.)Paraldehyde
yeah, you're right, going to look after that. thanks for your efforts anyway, much appreciated. Tested it a bit and, you confirmed my suspicion. Bounty will apply in 17 hours from now ;)Thelmathem
P
1

As you guessed, Math.random starts with a different seed in each case. There is unfortunately no way to provide a fixed seed to the Math.random function. If you really need that, you will have to find one or implement it yourself.

I have noticed that different canvas implementations do vary slightly when drawing partially opaque objects, but that is a minor issue compared to your differing random sequences!

Btw, your script does produce nice looking output :)

Poikilothermic answered 8/10, 2010 at 8:53 Comment(1)
I've tested with plain numbers... still producing the output different, also in a loop.Thelmathem

© 2022 - 2024 — McMap. All rights reserved.