Thread: Representing floats with color?

  1. #106
    Registered User
    Join Date
    Oct 2007
    Posts
    166
    Well I have some interesting results.

    I timed both ways in milliseconds. "Mid time" here stands for the first part of assigning values to the bitmap/array. The second part is after checking the bitmap/array and assigning the final values to the bitmap. The bitmap conversion code was pretty much exactly what I posted in my solution earlier.

    Texture size 1024x1024

    Bitmap conversion mid time: 50.069981
    Bitmap conversion final time: 105.990868

    Array mid time: 4.291205
    Array final time: 2142.164307

    Texture size 2048x2048

    Bitmap conversion mid time: 200.142319
    Bitmap conversion final time: 418.508026

    Array mid time: 23.939423
    Array final time: 8596.512695

    Texture size 4096x4096

    Bitmap conversion mid time: 790.517334
    Bitmap conversion final time: 1655.713867

    Array mid time: 111.133240
    Array final time: 34683.953125

    My conclusion is that it is accessing the values in the array that is taking the most time. Since the bitmap only needs to access one row of pixels at a time there are a lot less checks. For the array I tried float arr* and std::vector<float>, both were fairly similar in times. The time for calculating the conversion itself is also a very small part of these times and negligible for the situation.

    This means I save both memory and a whole lot of time. Pretty cool. Goes to show you never know about these things.
    Last edited by DrSnuggles; 12-23-2008 at 02:11 AM.

  2. #107
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by DrSnuggles View Post
    Well I have some interesting results.

    I timed both ways in milliseconds. "Mid time" here stands for the first part of assigning values to the bitmap/array. The second part is after checking the bitmap/array and assigning the final values to the bitmap. The bitmap conversion code was pretty much exactly what I posted in my solution earlier.

    Texture size 1024x1024

    Bitmap conversion mid time: 50.069981
    Bitmap conversion final time: 105.990868

    Array mid time: 4.291205
    Array final time: 2142.164307

    Texture size 2048x2048

    Bitmap conversion mid time: 200.142319
    Bitmap conversion final time: 418.508026

    Array mid time: 23.939423
    Array final time: 8596.512695

    Texture size 4096x4096

    Bitmap conversion mid time: 790.517334
    Bitmap conversion final time: 1655.713867

    Array mid time: 111.133240
    Array final time: 34683.953125

    My conclusion is that it is accessing the values in the array that is taking the most time. Since the bitmap only needs to access one row of pixels at a time there are a lot less checks. For the array I tried float arr* and std::vector<float>, both were fairly similar in times. The time for calculating the conversion itself is also a very small part of these times and negligible for the situation.

    This means I save both memory and a whole lot of time. Pretty cool. Goes to show you never know about these things.
    What in the name of all that is good did you do to those poor arrays? My computer must be a little slower (or I'm a worse programmer), for my 1024x1024 array mid time was 15 ms, and my 4096x4096 array mid time was around 140 ms. But the total time to finish the 4096x4096 array was only 550 ms. As far as I knew, you were finding the maximum value (which I did as I was writing the array, 'cause why not?) and then dividing all the values in that array by the largest value. Was there something else? Just for completeness, this is what I tested with:
    Code:
    #include <iostream>
    #include <ctime>
    int main() {
    
        float *bigarray;
        bigarray = (float *)malloc(4096L*4096*sizeof(float));
        float biggest = -5.0f;
        clock_t beginning, middle, end;
    
        beginning = clock();
        for (int i = 0; i < 4096; i++) {
            for (int j = 0; j < 4096; j++) {
                bigarray[i*4096+j] = i*1.0f*j;
                if (biggest < bigarray[i*4096+j]) {
                    biggest = bigarray[i*4096+j];
                }
            }
        }
        middle = clock();
        for (int i = 0; i < 4096; i++) {
            for (int j = 0; j < 4096; j++) {
                bigarray[i*4096+j] /= biggest;
            }
        }
        end = clock();
    
        std::cout << "To the middle: " << middle - beginning << std::endl;
        std::cout << "To the end: " << end - middle << std::endl;
        std::cout << "Oh and time unit: " << CLOCKS_PER_SEC << std::endl;
        return 0;
    }

  3. #108
    Registered User
    Join Date
    Oct 2007
    Posts
    166
    Ouch man I'm sorry my test was not fair to the array since I was putting in the pixels to the bitmap one by one there instead of a whole line at a time. Updated results...

    1024x1024
    Bitmap conversion mid time: 50.069981
    Bitmap conversion final time: 105.990868

    Array mid time: 4.291205
    Array final time: 56.237366

    4096x4096
    Bitmap conversion mid time: 790.517334
    Bitmap conversion final time: 1655.713867

    Array mid time: 104.611938
    Array final time: 912.804382

    So.. there wasn't a performance gain actually. The difference in time here is most certainly due to putting pixels into the bitmap up until mid time. These times (milliseconds) are so small though that I see no reason not to use the bitmap conversion since the gains in memory can be great.
    Last edited by DrSnuggles; 12-23-2008 at 03:08 AM.

  4. #109
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    Storing colors as floats is not about high dynamic range unless the hardware can use floating point textures. Normalizing colors is an ancient art that has been around for a long time. It's far easier to do color calculations on normalized rgba's than it is to do them on concrete values within a certain range.

    In ALL of my recent shaders colors are ALWAYS sent to the card as floats. You gain nothing except extra memory consumption when you store bitmaps in memory as floats. High dynamic range comes from post-processing on a scene or image and has nothing to do with how the data is originally stored unless you have some very very specific hardware I've not heard of.

    High dynamic range is accomplished by taking an original scene and applying a post-process luminance pass. Then the result is run through a gaussian filter on a floating point texture. The final result is then mixed back into the original scene and the result is rendered to the screen as a screen-sized quad or screen-aligned quad. Some techniques also do a tone map pass and several other passes for different type of post process effects. I suggest you do some googling on high dynamic range rendering and faked high dynamic range rendering. The Shader X series of books all cover this as well as a host of other shader-based books like GPU gems.

    Textures when sent to the video card are already converted into floats but you gain NOTHING from this except ease of calculation. You cannot represent an infinite amount of values between 0 and 255 just because you use floats and you also do not gain ANY color depth unless your system supports floating point textures and/or render targets. Your video card would have to support a floating point primary buffer in order to actually gain color depth. This also would depend on your display's ability to reproduce these discrete values. Even IF your card does support a floating point primary buffer there is still a finite amount of color representations available.

    I'm still completely lost as to what you gain here, why you need it and why it is any different from what has been done in games since DirectX 9 and floating point textures were introduces. Even in DirectX 8 at the shader level colors were represented as 4 floats. I see nothing revolutionary here.

    If you could store an infinite amount of data in a floating point array then I would store my terrain height maps as floats. However storing them as unsigned char arrays yields plenty of information. All I do is then scale the data in the array to arrive at the final world height. The theory is the same whether it be color or heights you are representing. Array...IE textures have a finite resolution and a finite color depth. Nothing you do can or will change that. The only way I know of to get extremely smooth hills (IE: extremely smooth color variations in your case) is to filter the data in the array.

    Also you are killing your bus here by forcing it to pass in 4 floats that are 32 bits each. That is 128 bits of data per texel going across the bus to the video hardware as opposed to 4 bytes or 32 bits. You are passing 4 times more data across the video bus than you need to and with no benefit.
    With the main slowdown and bottleneck these days being the video bus I fail to see how this is a smart move. If you want high dynamic range rendering then do it on the card and not in software.
    Last edited by VirtualAce; 12-23-2008 at 05:01 PM.

  5. #110
    Confused Magos's Avatar
    Join Date
    Sep 2001
    Location
    Sweden
    Posts
    3,145
    The reason he do what he does is so he won't have to allocate another buffer for his per-pixel-float-value (thickness). Instead he stores it in the bitmap memory (since those colors are of no further use after the thickness has been calculated).
    MagosX.com

    Give a man a fish and you feed him for a day.
    Teach a man to fish and you feed him for a lifetime.

  6. #111
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    Thickness and color? Ok. Whatever. There are well developed theories and implementations that already solve all of this.

  7. #112
    Registered User C_ntua's Avatar
    Join Date
    Jun 2008
    Posts
    1,853
    Quote Originally Posted by DrSnuggles View Post
    The color class is not written by me but it is something I have to work with. In my solution I used r,g,b,a freestanding as examples only. In the class those values go from 0.0 to 1.0 and only in steps between 0 and 255 so I can't store any float number there, only steps between 0 and 255. So assigning a value like 0.5f will result in a stored value of 0.4980392 which is (1.0 / 255.0) * 127.

    The color class uses float to be able to store high dynamic range color data if needed. How the colors are stored in memory for the bitmap I'm not sure, in the case of not using high dynamic range I believe it is only the access function for the pixels that is returning floats and the memory is stored as bytes. That might not take up 1,6 GB but the important thing is that an additional array of floats in that case would.
    Well, I don't know how much are you allowed to change. But if you could change the color class you could store directly the float value. I mean, don't use the normal functions to set a color
    So, do you have access to the color class? Are you allowed to add things to it?

  8. #113
    Registered User
    Join Date
    Oct 2007
    Posts
    166
    Bubba - Sounds to me like you are referring to high dynamic range applications for games which I'm sure involves a lot of post processing. 3d applications though use bitmaps in formats like .hdr which stores floating point data that is used to illuminate a scene when rendering in the 3d application. That is the environment I'm working in so that is why the color class is using float values.

    C_ntua - I won't be able to change the color class myself. I could write my own class but that would just add a level of indirection.
    Last edited by DrSnuggles; 12-30-2008 at 04:53 AM.

  9. #114
    Registered User C_ntua's Avatar
    Join Date
    Jun 2008
    Posts
    1,853
    Then maybe you can hope that the variables are protected and not private. In which case you can create a derived class from the base COLOR class. You can then create a function that sets what you want and use the derived class instead of the base class. If the variables are private and you cannot declare them as protected... I have no more ideas

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Critique my lighting model.
    By psychopath in forum Game Programming
    Replies: 4
    Last Post: 08-12-2006, 06:23 PM
  2. egavga.bgi problem
    By sunil21 in forum A Brief History of Cprogramming.com
    Replies: 3
    Last Post: 09-22-2003, 05:06 PM
  3. My opinion on skin color
    By Leeman_s in forum A Brief History of Cprogramming.com
    Replies: 8
    Last Post: 07-11-2003, 12:12 PM
  4. [WinAPI] Developing a color customizable program
    By Templario in forum Windows Programming
    Replies: 6
    Last Post: 02-04-2003, 06:12 PM
  5. Just one Question?
    By Irish-Slasher in forum C++ Programming
    Replies: 6
    Last Post: 02-12-2002, 10:19 AM