|
Author |
Topic: color() Object Speed Bottleneck (Read 2486 times) |
|
ironwallaby
|
color() Object Speed Bottleneck
« on: Mar 29th, 2005, 12:31am » |
|
Hello, everyone. I first started playing with processing yesterday, and I was surprised to find a large slowdown in making colors to use in the set() function. You can see the fast version (with framerate set to 60 fps) here. My only guess as to why this might be is that the overhead incurred by instantiating the color class many many times grows very much, but since color can be represented as an integer, I found this very surprising. The code is as follows: Code:// XOR Tube, Q12005 Jason LaPorte // Renders a tube, running off forever, painted with an XOR texture // Parameters int speed = 2, torque = 1, fps = 60; // Globals int position = 0, rotation = 0; int[][] rBuffer = new int[320][240]; int[][] zBuffer = new int[320][240]; void setup () { size(320, 240); //framerate(fps); // For speed, buffer the raycasted calculations. for(int y = -120; y < 120; ++y) { for(int x = -64; x < 256; ++x) { rBuffer[x + 64][y + 120] = int((atan2(y, x) + PI) * 256 / PI); zBuffer[x + 64][y + 120] = int(16384 / dist(0, 0, x, y)); } } } void loop () { // Find texel for each pixel, and render it to the screen for(int y = 0; y < 240; ++y) { for(int x = 0; x < 320; ++x) { int b = ((rotation + rBuffer[x][y]) ^ (position + zBuffer[x][y])) % 256; // COLOR BOTTLENECK IS RIGHT HERE set(x, y, b * 65793); // <- This is very fast for setting colors. //set(x, y, color(b, b, b)); // <- This is "correct", but very slow. // END COLOR BOTTLENECK. } } // Update camera position += speed; rotation += torque; } void mousePressed () { speed = speed * 4; torque = torque * 4; } // Zoom! void mouseReleased () { speed = -speed / 4; torque = -torque / 4; } // Unzoom and reverse |
| Can anyone clue me into why this might be?
|
« Last Edit: Apr 11th, 2005, 7:40pm by ironwallaby » |
|
|
|
|
Kha0S
|
Re: color() Object Speed Bottleneck
« Reply #1 on: Apr 12th, 2005, 11:56pm » |
|
I'm having the exact same problem. One way around it is to do an indexed-color type mode, and precompute a look-up table... in cases where you're only modulating one color parameter, this is reasonably constrained to 256 colors... but still... Code: color[] colorLUT = new color[256]; ... void setup() { ... for(int i=0;i<256;i++) { colorLUT[i] = color(i,i,255); } } ... void loop() { ... int dropColorLUTindex = max(0,min(255,int(abs(xvel)*400)+100)); pixels[int(y*2)*winX+int(x*2)] = colorLUT[dropColorLUTindex]; ... } |
| The bottleneck is massive. I managed to get the same framerate with 100k particles with a lookup table as I got with 1k particles calling color() once per particle. If you're trying to modulate multiple color parameters (ie, want full 24-bit color support), precomputing isn't really an option, unless you want to quantize your colormap. Does anyone know the formula for computing a color() object from a set of RGB ints? /Andrew
|
|
|
|
Kha0S
|
Re: color() Object Speed Bottleneck
« Reply #3 on: Apr 13th, 2005, 12:03am » |
|
on Apr 12th, 2005, 11:59pm, fjen wrote: Beautiful. No wonder my RGBA hacks weren't working. Still, this begs the question why the color() constructor is so massively slow, or if there is any inclination to come up with a faster color assignment operator in Processing. (Also, FWIW, I've found when doing my sobel edge maps, the brightness() operator can be roughly approximated by a division by 67593 ... another good place to gain speed). /Andrew
|
|
|
|
fry
|
Re: color() Object Speed Bottleneck
« Reply #4 on: Apr 13th, 2005, 12:04am » |
|
right, color(), get(), and set() are the very slow (but easy and correct) way to deal with colors. color() also uses the current colorMode() so you're missing some speed there too. the fastest method is to use: pixels[y*width + x] = 0xff000000 | (red << 16) | (green < 8 ) | blue; where red, green, and blue are each integers between 0 and 255. better yet, put it in a loop where you don't have to multiply y*width each time: Code: // Find texel for each pixel, and render it to the screen int index = 0; for(int y = 0; y < 240; ++y) { for(int x = 0; x < 320; ++x) { int b = ((rotation + rBuffer[x][y]) ^ (position + zBuffer[x][y])) % 256; pixels[index++] = 0xff000000 | (b << 16) | (b << 8) | b; } } |
|
|
|
|
|
|