2/26/08

Chocolux 1k intro

Chocolux is a real-time recursive raytracer using four spheres. Lighting and intersections are all approximated to fit the 1024 bytes boundary. I used crinkler 1.1 for compression. The executable can be downloaded at Pouet or Intro Inferno. For those with no PS3.0 card is a video:



The code can be downloaded here.

Probably the best space saving trick in the code is:

t=GetTickCount();
glRecti(t,t,-t,-t);


This allows the time to be passed into the shader without either using glGetProcAddress calls for the extensions or using glColor3f which is smarter but still not as good. So long as t is bigger than 1 (it will be as GetTickCount is a millisecond counter from boot time of the PC) the screen will be drawn and the value of the vertex can be used for the timer.

The recursive raytracer is no use to anyone outside this code as the maths is corrupted to give a more detailed image and smaller bytes. However, Pohar found a trick worth mentioning. The nested loops in the fragment shader both use i as the variable (rather than say i and j). This allows crinkler to really go to work and compress this code down. Its legal in shaders and, I'm told, C too.

One other byte saving trick I haven't seen anywhere else is I have no background test in the code when rays do not intersect objects. Normally this would be an if and some calculation to assign colour for the background. Instead, I place the scene inside a sphere so I know the ray will always hit one object. This also adds a lot of visual complexity to the scene.

There are pragma statements like:

#pragma data_seg(".shad2")
.
.
.
#pragma code_seg(".compile")

scattered through the code. These are to assist crinkler as it may reorder the code more, saving here, 6 bytes. These are placed just before data and just before every function and the main entry point.

3 comments:

  1. Anonymous18/2/12

    Kudos! Many, many Kudos!

    ReplyDelete
  2. Hi,
    Awesome demo and thanks for sharing the code!

    In the future could please fix your dmScreenSettings so it compiles without warnings? :-) The unions need extra braces :-/
    i.e. replace with:
    DEVMODE dm =
    {
    "", 0, 0, sizeof(dm), 0, DM_PELSWIDTH|DM_PELSHEIGHT, {{0,0,0,0,0,0,0,0}}, 0,0,0,0,0,
    "", 0, 0, SCREENX, SCREENY, {0}, 0,0,0,0,0,0,0,0,0
    };
    e.g. I'm compiling some of your under MinGW via:
    g++ -Wall -s -O2 -mwindows -o choc.exe choc.cpp -lopengl32 -lglu32

    I also replaced your loop/goto with this to prevent Win7 from showing a busy cursor while waiting:
    while( !GetAsyncKeyState( VK_ESCAPE ) )
    {
    MSG msg;
    while (PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ))
    {
    //TranslateMessage( &msg ); // Don't have any keys that need translating to WM_CHAR messages
    DispatchMessage( &msg );
    }
    int t = GetTickCount();
    glRecti( t, t, -t, -t );
    SwapBuffers( hDC );
    }

    Fan of any demoscene code that shares their code for others to learn!

    Cheers,
    Michael

    ReplyDelete
  3. Hello,
    I used your shader to make free wallpaper:
    https://play.google.com/store/apps/details?id=pl.mawo.wallpapers.chocolux
    Hope you like it :)
    BR,
    Marcin

    ReplyDelete