Back from the Ultimate Meeting 2010

Twenty four hours after getting back from tUM 2010 I almost completely recovered from the party coding, sleep deprivation, walking in the snow, and from the two hours late train ride to get there as well as get back from there. As planned, our new 64kB PC intro, E – Departure was presented there (sadly there was no other 64kB entry, so it was shown in a combined competition with PC demos).

What first drew my attention on this party was the website: carefully polished, with a beautiful layout, loads of useful and detailed information, random photos and links to productions from the previous years, etc. Also some details like the number of different music competitions (executable, tracked, streamed, loop : even though I am not into music myself, I think this is great), the fact that tracked music would feature a tracker rendering, the namevoting preventing rule, all stacked together left no doubt it was a carefully prepared event. Moreover, the so called Ultimate Breakfast and the free coffee and tea gave the feeling it would be pretty cozy.

Once there, all of this proved to be true. Flawless German organization. The Intranet had an embedded Google Map with everything a scener might possibly need, from food and cash dispenser to computer stores, and featured a food delivery service: the so called Foodwave. No need to get lost outside to find some hypothetical pizza, one just had to choose from the broad choice, pay at the food desk, and get back to coding or to whatever other activity more interesting than braving the cold the party was providing, until the food delivery was announced. A truly great service.

fr-063: Magellan, by Farbrausch

fr-063: Magellan, by Farbrausch

The party place itself, at a walking distance from the train station, is a very nice hall with a nice looking inside iron architecture. The wooden floor, although making stomps more disturbing during the night, contributes to making it a very warm environment. The work done on the lighting and theme is nice too: this year it was the 10th edition, and various artifacts from previous years were exhibited here and there, as well as some printed graphic productions. Those details and the rather small, but not narrow, size of the place make a cozy feeling, but not a mediocre party: there are great people there, and the competition have a fair level even though the number of entries could be way higher. The real downside of this place though, and maybe the biggest downside of the party altogether, is the absence of showers, and the absence of hot water in the toilet. Washing as little as hands and face with cold water during a German Winter is probably among the rites of passage into adulthood, along with explaining to Scamp you’re launching in Norway a demoparty called The Breakpoint Replacement.

Something I absolutely loved there was the job Franky did by bringing one of his pinball games. A good old late 80’s blinking and blipping pinball! It became a hot spot, where people gathered and chatted while playing when there was nothing to see on screen. I doubt I would have met as many sceners otherwise. The Ultimate Meat Thing was a very nice job done by the Nuance folks, even though a bonfire in the snow isn’t exactly as much fun as one during summer. The Ultimate Breakfast on the other hand was pretty cool, as a way to wake up and all have a meal together while waiting for the first events.

Rumors and Facts, by Rebels

Rumors and Facts, by Rebels

I won’t list all competitions, but the main productions were without a doubt the new Farbrausch demo, fr-063: Magellan, and the much awaited Easter Party invitation, Rumors and Facts, by Rebels. The 4k intro White One, by Never, also got the audience with its delicate feedback effect. Another production that blew me off was the epic streamed music entry, End Credits, by jco.

At last, a thing that disappointed me (apart from how we ranked) was the way the party feeling suddenly vanished once the competitions ended. While Breakpoint, Evoke and Main all had a live show to end up with, nothing happened and many people left, leaving the place with a weird feeling. It’s not like there wasn’t any live acts, there was even one right before the demo competition, but this felt like it was missing a decent final.

So as a conclusion, the Ultimate Meeting is definitely a good party, with the nice feeling brought by its small size and perfect organization. But to compare it to another German party, I prefered Evoke 2010 (which doesn’t have this family feeling though).

Early draft

Here is a sketch made about a month ago, after Cyborg Jeff, our dear composer, let us hear the first elements of his soundtrack. This was the base of our upcoming next production, a 64kB PC intro codenamed E. Our first demo, B – Incubation, have received a positive feedback, but was criticized design wise. E is music driven and focused on the visual experience; I hope it will succeed on the points the previous demo missed.

There is still work to do, but I am pretty confident we will be able to release it at the Ultimate Meeting that will take in Karlsruhe, Germany, starting tomorrow. I do not guaranty the fulfilling of this assertion though, should any supervening circumstances amounting to force majeure. Such circumstances shall include, but shall not be limited to, strike, snow storm, riots, train hitting a truck, hard drive toast, power plug left at home, earthquake, war or acts of God.

See you at tUM!

Update: nor the snow and the resulting almost three hours delay on train schedule, nor the very addictive pinball game could prevent the release of E as planned. :-)

GLSL Minifier – smaller and smaller

The new version of our tool is released! Here is the changelog:

  • Allow forward declarations in the input code and remove them (functions are automatically reordered). Please use the syntax “int foo(int x)” and not “int foo(int)”.
  • More intelligent renaming based on the context the variable is used.
  • Allow structs in source code, fields are not renamed. Field names cannot look like vec fields (.rgb, .r…) because I haven’t written the typer yet.
  • Remove the –macro-threshold option. Will be fixed in a future version.
  • As usual, several bug fixes

The most important news is the improvement on the renaming strategy. In the 0.4 version, the Minifier tried to reuse the same variables again and again, and increased the frequency of a few characters. Now, it’s getting more complex: the name of a variable  depends on how it is used.

For instance, if you often call functions “max” and “mix”, you’ll often have the “x(” pattern. Thus, GLSL Minifier will probably name your function x to increase of the frequency of this pattern. The same goes for each two-char pattern the tool will find.

Here are some statistics I’ve just made, using shaders from 4k intros. I’ve taken a short C file, inserted the shader as a string, compiled, and compressed using Crinkler (/COMPMODE:SLOW /ORDERTRIES:3000). So, it’s all about making the shader compress better. Numbers are the filesize in bytes:

  • Retrospection
    • Original: 1462 (hand optimized)
    • Minifier 0.4: 1429
    • Minifier 0.5: 1421
  • Valleyball
    • Original: 2240 (using old BluFlame minifier)
    • Minifier 0.5: 2184
  • Another theory
    • Original: 1511 (hand optimized)
    • Minifier 0.4: 1475
    • Minifier 0.5: 1463
  • Lunaquatic
    • Minifier 0.4: 2635
    • Minifier 0.5: 2613
  • Sult
    • Minifier 0.4: 1411
    • Minifier 0.5: 1408
  • Slicesix
    • Minifier 0.4: 2493
    • Minifier 0.5: 2432

Conclusion: If you’re not using any tool to minify your GLSL shader, I bet you could save at least 20 bytes on your 4k intro. Try and see!

=> GLSL Minifier 0.5

GLSL Minifier, bug fix release

I’ve just fixed a few bugs in GLSL Minifier. Here is the list of changes for the 0.4.2 version:

  • Smaller file to download (700kb instead of 1.8Mb), using MPress. Thanks eyebex!
  • Print -.5 instead of -0.5. Thanks to stan_1901!
  • Parse octal and hexadecimal numbers. Bug found in Valleyball source code, thanks BluFlame!
  • Can compress several shaders at once, but only if the –preserve-externals flag is set.
  • Reorder uniform/varying/attribute declarations. This reduces the size of some shaders.
  • Fix a bug where the order of instructions was messed-up. Thanks to XT95!
  • Fix the –macro-threshold option. Thanks to Řrřola!
  • Forbid the reusing variable names in the same function (which is rejected by ATI compiler). Thanks again to Řrřola!
  • Handle multiline macros in the parser. Bug found in The Wind under my wing code, thanks Navis!
  • Improve the way the C header file is generated, trying to avoid name clashing. Thanks again eyebex!

My testing scripts are not fully set up, so you might find some other bugs. Please report them! If you use the –preserve-externals option, you might get name clashes if you use one letter names. That will be fixed another time.

Download GLSL Minifier

Behind Incubation

After months of work, we’ve finally released our first demo: B – Incubation. As I love eading how other demos are made, I’m going to share a few things.

Zavie and I seriously started Incubation in January. At this time, we had no real experience in size coding, and almost no code base. We didn’t even know how to write a shader. All we had was a texture generator. We decided to start from IQ’s 64k framework (to get compiler options and basic code optimized for 64k intros). We planned to release our intro at Breakpoint in April, but it was so crappy that we decided to delay it. We finally released it at Evoke, in August.

Some groups (e.g. Farbrausch, Conspiracy, Fairlight) create their demos with a tool, while other groups like ASD prefer pure code. In Incubation, everything is hard-coded, but we used some tricks to improve our productivity and reduce the number of compilations. When the code is compiled in debug-mode, many shortcuts are available, such as time-control (play, pause, backward, forward), and camera control with mouse and keyboard. Camera data is stored in an array, and we use a spline to interpolate positions (thanks IQ!). This array is in a separate file: In debug-mode, we can reload it at any time; in release, the file is simply included. The same goes for the light position.

We also use a tricky macro, called Tweakable Value, to tweak our constants at runtime. For instance, we use it to update text position, fade in / fade out dates, and so on. As you can see, there are many things we can edit and update without recompilation (shaders are obviously reloadable at runtime, too).

In Incubation, we use about 50 colour textures, 25 normal maps (for parallax mapping), and 25 specular maps. Everything is generated in code – we don’t have any fancy node-based editor. I wrote a minimalist script language to call the texture generator functions and get immediate feedback without recompilation. We later replaced this broken language with picoc, a C interpreter.

For fun, I put this texture generator on my webserver. Imagine: You enter a few lines of code in your browser, press a button, and see the generated texture within a second. As everything is shared, we can see when other people’s textures, copy and edit their code, etc. Although a browser is not the best tool to write code, it is awesome for social interactions. We started making many textures for fun, we invited our friends to play with the online texgen, and we got many interesting results. For example, Rubix made a Pacman shape for fun, I decided to put it on a wall, and it ended up in the demo.

Pacman wall

Here is a random list of things we’ve used: kkrunchy, v2, game of life, L-system, Voronoi cells, Perlin noise, convolution filters, parallax mapping, godrays, depth of field, glow, Bresenham’s line. Nothing new here, but this might help some beginners.

Size limit has not been an issue for us; 64 kilobytes is a lot when you have only code and no external library. We didn’t even apply the planned optimizations, but we’ll probably do the following for our next intro: truncate floats, reorder data, do delta encoding, obfuscate shaders… Here is the estimated compressed size of a few parts:

  • Music: 15.5k
  • Textures: 10k
  • Camera data: 4k
  • Animations data: 5k
  • Shaders: 3.5k

Yes, this is very different from Panic Room, about which Smash mentioned that “You might be surprised to learn that the shaders are the biggest single (yes, compressed) data block in the 64k, bigger than the meshes, samples, music data, texture data etc. modern rendering apparently doesn’t come for free.”

Next time, we’ll improve our rendering and get meshes. :)

Back from Evoke

So last weekend we were at Evoke in Cologne, Germany. It was our first time there, and we decided to go after being told to do so by some friends and, to be honest, also because of the very engaging invitation demo. The event was great, beyond what we already heard about it: rather cheap entry fee, cool atmosphere, nice barbecue, great sound system and huge screens in an awesome location, an old factory (although not very straightforward to find). We were surprised by the number of productions and their level: there sure are things to watch or listen to. But from our point of view, one of the best things was the cheering feedback from other sceners. It seems some people liked the adventures of our spinning OpenGL cube. :-)

A Weighted Companion Cube and the Evoke 64kB demo trophee

First released 64k

We released earlier our first 64kB PC demo: “Incubation”, codenamed B.

The live feedback of the public, reacting at most winks we put, was really awesome. Likewise, the comments we can already see on Pouët are very much appreciated. Thank you all. As we are very tired, we will get some rest first (actually, two of us three are already sleeping somewhere :) ), then we will fix a couple of things: correct bugs some people seem to be experiencing, capture a video, etc.

For now, here are just these links:
Pouët page: B – Incubation
Download Incubation

Goodnight all.

GLSL Minifier 0.4

We’ve just released GLSL Minifier 0.4! It fixes many problems, and add some new features. Tuesday update: version 0.4.1 improves a few things and adds an option to preserve external values, such as uniforms and varying. Here is the list of changes:

  • Command line is properly handled. Try the “-h” option to see the complete list of flags.
  • The -o option has been added, if you want to get the output in a particular file.
  • There is also a –shader-only, if you don’t want the C header and the formatted string.
  • Vectors accesses are made uniform, using (by default) only the “rgba” set. For instance, “foo.x” is renamed into “foo.r”.
  • Macros can be inserted to shorten external functions calls and types. This can greatly reduce the uncompressed output shader. However, the compressed file will most of the time be bigger (we’ve tested with Crinkler and kkrunchy). You can choose the threshold to control the number of macros that are inserted. This option is disabled by default.
  • The renaming algorithm has been changed. Previous versions of this tool were based on the GLSL 1.10 spec, which states that functions and variables use different namespaces. This is not true anymore since GLSL 1.20, so I had to remove a few tricks in the renamer & obfuscator.
  • The smoothstep function can be rewritten using IQ’s trick. It’s not done by default, because it’s not always a good thing to do.
  • Some information is now displayed on the console.
  • The –preserve-externals option has been added, so that you can use this compressor even if you have multiple shaders!

GLSL Minifier has been tested on the hand-optimized shader used in Retrospection, a great 4k intro (many thanks to FRequency and TITS who provided me the code). Here is the data:

Input file size is: 1727
File parsed. Shader size is: 1725
Rewrite tricks applied. Shader size is: 1723
Identifiers renamed. Shader size is: 1610
Macros added.
Minification finished. Shader size is: 1495

Note that this is the uncompressed size (size after macro injection is not useful). Once compiled with the C code and packed with Crinkler, it turns out we saved more than 30 bytes using this tool. If they had GLSL Minifier, FRequency and TITS could have improved even more their intro!

GLSL Minifier was also able to save a few bytes on To the Road of Ribbon, even if auld^titan spent time optimizing the intro to fit in 1k on Windows. Here is an example of output of the tool. See how it’s easy to include the file in your C/C++ project!

#ifndef SHADER_CODE_H_
#define SHADER_CODE_H_

const char *shader_roadOfRibbon = ""
 "float c=gl_Color.r*55;"
 "float e(vec3 e)"
 "{"
   "return min(cos(e.r)+cos(e.g)+cos(e.b)+cos(e.g*20)*.02,length(max(abs(e-vec3(cos(e.b)*.2,cos(e.b)*.2-.5,0))-vec3(.2,.02,c+3),vec3(0))));"
 "}"
 "vec3 o(vec3 c)"
 "{"
   "return normalize(vec3(e(c+vec3(.02,0,0)),e(c+vec3(0,.02,0)),e(c+vec3(0,0,.02))));"
 "}"
 "void main()"
 "{"
   "vec3 v=vec3(cos(c),-cos(c*.5)*.5+.5,c),r=normalize(vec3(gl_FragCoord.rg*.002-1,1)),n=v;"
   "for(int c=0;c<55;c++)"
     "n+=r*e(n);"
     "vec3 l=n+=r=reflect(r,o(n));"
     "for(int c=0;c<55;c++)"
       "n+=r*e(n);"
       "gl_FragColor=abs(dot(o(n),vec3(.1)))+vec4(.2,cos(c*.5)*.5+.5,sin(c*.5)*.5+.5,1)*length(n-v)*.01+length(n-v)*.01+(1-min(l.g+2,1.))*vec4(1,.8,.7,1);"
 "}";
#endif // SHADER_CODE_H_

GLSL Minifier 0.3

Today is the new release of our GLSL obfuscator & minifier.

Here is the change log:

  • Feature: Variables that start with “i_” are now inlined. That will help you keep a clear code, name your values, while still having a short shader code.
  • Feature: The shader in the C code is now split into many lines (using quotes on every line), and indented. That will help you maintain the obfuscated GLSL code.
  • Improvement: The useless space that sometimes appeared after “else”, “do” and “return” is removed.
  • Bug fix: Postfix operators are now handled.
  • Bug fix: Some parenthesis were missing +various other fixes

Edit: I’ve just updated this 0.3 release to include a few additional fixes (mainly parse errors), thanks to Ponce.

GLSL Minifier 0.2 is out

Hello,

GLSL Minifier has just been released. This is the first public version, but it’s still a preview. It has not been much tested, and probably contains bugs. However, I believe it’s usable and it should help intro coders a lot.

Changes since 0.1 version:

  • Bug fix: problems with field accesses
  • Bug fix: macros are now accepted (but ignored) in the user code
  • Feature: multiple declarations with the same type are now squeezed.
  • Feature: better renaming for the functions, they now have a separated namespace.
  • Feature: use overloaded functions in the generated code: if two functions don’t have the same number of parameters, they can have the same name.