Irradiant Shards in WebGL

Irradiant Shards in WebGL

Irradiant Shards features slowly growing crystal shards that develop over time, presented in a slightly vintage style. Each shard moves around smoothly before quietly fading away.


This design is actually just a elaborate modification of Erratic Signals. By increasing the line width we get thick lines with an angular point at the end. Some smooth step interpolation is added for movement so the lines speed up and slow down as they approach each point. As before, the lines fade out over time but now also with interpolation.

On the shader side, colors are slowly cycled through over time. This time however we use a gradient palette mapping function to slightly tint parts of the line based on opacity. The color is also tinted by a plasma texture to add some variance to the intensity. The texture is generated using a few sine functions, then scaled up and movement is added so that the periodic repetition is less noticeable. To achieve a vintage effect, the black background is tinted with the complimentary color of the line. This creates an effect similar to viewing a bad LCD display off angle. Then noise is added for grain simulation and a basic vignette. The frame is scaled up 3x using nearest neighbor filtering for a pixelated look.

It is neat how much shaders can affect the final image when chained together, but they require careful adjustment to get the appearance just right.

This scene is available for your desktop here on Wallpaper Engine. Some of the adjustments can really change the style!

Pumpkin from photo to 3D

3D WebGL Pumpkin

Here is a 3D scan of a pumpkin. The pumpkin was captured with 16 photographs at 16 megapixel resolution and then reconstructed using photogrammetry techniques, producing a high resolution 3D mesh model and a diffuse texture map. The mesh was then simplified to a low polygon mesh and a normal map was baked based on the high polygon mesh.

The mesh is displayed in realtime 3D in a HTML5 browser using the hardware-accelerated WebGL API for Javascript. The three.js library is used to simplify mesh loading, scene management, and lighting model. The model is rendered spinning using toplit Phong lighting from a perspective camera orientation.

Here is the pumpkin rendered in realtime. Below is the original photo.

Photograph of an orange pumpkin

Erratic Signals in WebGL

Erratic Signals in WebGL

Here we have Erratic Signals, a bunch of unpredictable signal lines snapping around with a neat glow effect. It took quite a bit of tuning to get the lines to appear random, but not too aimless. While they move independently, it looks nice when they cluster and overlap. Certainly has a circuits vibe with the angular lines and the via-like tips.

This one is done in pure JS/WebGL. WebGL is basically the same as OpenGL ES 1.0, with a few additions to make it better suited for the Web. ThreeJS is a great library but not as simple when you need to stream generated geometry every frame. So for this scene I just used the WebGL API directly, which is more boilerplate code but also more control over the drawing procedure.


The lines are generated each frame and triangulated using the naive quad method, since glLineWidth doesn’t work properly in WebGL, uploaded to a vertex array, and then drawn to a framebuffer with a vertex color shader. The tip is a diamond that ends up looking like a circle when drawn so small. Since the number of lines can change rapidly between frames the vertex array must be preallocated large enough such that reallocations are rare.

Then a 2-pass blur shader is applied with a wider than normal sampling interval to get the grid effect. The alpha blending isn’t done correctly, causing the typical dark halos associated with wrong premultiplied alpha. But in this case it looks better since it causes the lines to fade out faster and isn’t noticeable with a dark background.

Finally the blur frame and the line frame are drawn to the screen using a simple shader to add a bit of color variation.

Just as before, this scene is also available here on Wallpaper Engine. With it, many of the parameters are adjustable like speed and color.

Ribbon Turmoil in HTML5 Canvas

Ribbon Turmoil in Canvas/JS

Here is another little graphical demo done in Javascript and Canvas. Like before, this one was originally done in Lua. A bunch of pastel ribbons wind and wiggle around pegs.

What is interesting is that the script ends up being much simpler thanks to some key differences in the drawing API. Each ribbon is made up of lines, arcs, and end caps. In love2d each must be drawn individually with separate drawing commands. Javascript with a Canvas context however uses the concept of paths, where the entire path can be set with commands and then drawn all at once in one call. The thickness, end caps, and color are just properties of the path. It is still an immediate mode API, but when the ribbons change each frame the data needs to be streamed anyways. These ribbons run pretty fast as it is. If better performance is needed we must do 2D in WebGL.

You can subscribe to this as a wallpaper if you have Wallpaper Engine.

Chroma Drencher in HTML5 Canvas

Chroma Drencher in JavaScript and HTML5 Canvas

In the last post I showed how technologies like Emscripten can be used to adapt apps written in other languages to the web. This has only become easier since with WebAssembly that replace huge files of unintelligible JavaScript with a true byte code format. Running large apps compiled to the web natively at fast speeds is now possible. Still, sometimes it’s easier to avoid that complexity and just write things directly targeting the web.

I’ve ported Chroma Drencher to JavaScript using HTML5 Canvas. Now all thats needed is a few KB script instead of a multi MB script, and it runs faster too!

Check this out fullscreen!

Porting from Lua to JavaScript isn’t that difficult considering how similar the languages are. Most of the difficulty was adapting the drawing from love2d to canvas. Generating gradients is easier since canvas has drawing functions for them, something love2d lacks altogether. These can be cached on offscreen canvases since drawing hundreds of gradients per frame is slow. Sadly canvas doesn’t have any way to perform sprite batching, so each line has to be drawn with a separate image draw call. I suppose WebGL could do that, but it still runs quickly as is.

Also, if you have Wallpaper Engine on Steam, you can subscribe and use it as an animated desktop wallpaper!

Next time another neat demo ported to JavaScript + Canvas!

Chroma Drencher

LÖVE Demos on the Web with love.js/Emscripten

In the past I’ve built some small graphical demos and games in Lua using the great LÖVE framework. LÖVE is aimed at making games but is actually good for any kind of multimedia applications, providing a rich API for drawing graphics, playing audio, receiving input, etc. Previously these apps only ran on desktop platforms, but with the recent release of LÖVE v0.10 they can now be run on mobile platforms as well. Still, the web with HTML5 was unsupported and I really wanted to be able to show them off here on this site as well. There were a few attempts to achieve this by building a Lua interpreter in JavaScript and then reimplementing the LÖVE API, but these were slow and did not provide the entire feature set. Now a new project called Love.js has brought LÖVE to the web using Emscripten.


Emscripten, the asm.js compiler allows C/C++ code to be compiled to JavaScript that can be run at near native speeds. This compiler allows love.js to compile the native LÖVE codebase directly to JavaScript, providing full API support for LÖVE applications that can be run at reasonable performance. Then, the Lua application is packaged into a javascript file that is loaded along with love.js. At runtime, the application is unpackaged into a virtual filesystem containing the original lua files. These are loaded by the Lua interpreter in love.js to run, outputting to a HTML5 canvas. See the chart below for a simplified overview of this process.

Flowchart showing emscripten usage with love.js

The demo I’m showing today, Chroma Drencher, was built using the LÖVE framework in Lua. Getting it on the web could have been done with a port to JavaScript and HTML5 Canvas, after all Lua’s syntax isn’t all that different from JavaScript, but it would likely have been difficult since the Canvas API is much more barebones. Some of my other demos use shaders so then WebGL is required. Of course there are plenty of Javascript frameworks available through none of them appeared to do things the same way as LÖVE. This made targeting the web directly using a LÖVE port appealing. Packaging an application is done with a simple script that generates a JavaScript file that when combined with the Emscripten compiled LÖVE JavaScript file, allow the application to be displayed on a HTML5 canvas. I modified the loader script to integrate with the page and look a bit nicer since it was originally intended for a dedicated page.

Chroma Drencher is a simple screensaver type demo with slow falling colored lines. It was inspired by a desktop wallpaper I saw someone had which made me think it would look cool if it were animated. Below you can see the result.

Click the box to load the application (warning huge script download). The window is a bit small but you can press the F key to switch to fullscreen mode. By pressing the right mouse button, the controls for adjustment will appear. Try out some different settings and take a screenshot if you like it!

Disassembly listing and game options menu

Assembly Adventures

A while back I was interested in playing an old simulation game from the late 90’s, SimCity 3000. The game still runs great on today’s systems without any major compatibility issues and its raster graphics still look as crisp as back then. Designed back when 1024×768 was a typical monitor resolution, the game preferences dialog limits the maximum resolution to 1280×1024. This doesn’t look very nice on a modern widescreen display. Other games like Age of Empires II have received patches and HD Edition rereleases, but SimCity 3000 clearly wasn’t getting any more updates. Many games have workarounds to use custom resolutions, so surely there must be some way to set higher resolutions for this game?

game options menu

My first idea was to manually edit the configuration file. The game options only list a small set of resolutions that can be set. By selecting each resolution, quitting the game, and viewing the configuration file in a hex editor, It becomes clear that the resolution (and other settings) were stored as binary packed data format consisting of little-endian values. At 640×480, the value in the data file is 0x80 0x02 0xE0 0x01. When changed to 1024×768, the value becomes 0x00 0x04 0x00 0x03. So in an attempt to get 1920×1200, I replaced it with the value 0x80 0x07 0xB0 0x04. Unfortunately this did not work, and the game reset the resolution to 640×480 upon starting. It appears that there is a procedure to not only limit the resolutions shown in the game, but also verify that the one read from the config file is allowed.

Game disassembly listing

The next step was to open up a disassembler (I used OllyDbg). The program uses DirectDraw as its graphics API, and typically the Windows API function CreateWindow is where the initial window is created. This function was easy to find, but it was clear from running the program through the debugger that the higher resolution values written in the config file had already been changed by this point. Even if the window size could be overridden at this function call, the executable would be locked to whatever single resolution was assembled. More likely however is that only the window size will increase, and the game will only occupy the upper left corner of it.

What I really needed to find was the root of the problem, that being the instructions that were limiting the resolution to the preselected values. Attempting to find the location where the config file was read proved to be too difficult due to the amount of other data that was located in and read from the file. Searching for some of the values corresponding to the resolutions shown in the preferences dialog provided too many results to be specific. Instead I had to follow the value backward from the CreateWindow function. This process was tedious since debuggers generally don’t have a “step back” option. Eventually the verification function was located and it was quite obvious when it was found.

Game disassembly listing

Consisting of a series of compare instructions with various resolution values, the function checks that the provided number belongs to the list of allowed resolutions or otherwise changes it to a default. Surprisingly, the next function in memory was the one that filters the allowed resolutions to appear in the preferences dialog. Replacing the first instruction of each function with a simple “return success” stub was all that was needed to disable this behavior. Once the game was restarted, the options showed all resolutions supported by the graphics card and the game appeared to run fine without any glitches using them. The view of the simulated cities was much larger and the UI elements scaled properly.

Game options menu fixed

Indeed, examining assembly code can be difficult and time consuming. But it was fun to change something that would have otherwise been impossible and allow an old classic to take full advantage of a modern display.

Ingame picture

If you have this game and want to patch your own copy, you can do so with a hex editor. This will require a version of the game that isn’t encrypted (or requires a CD to start). Here is the patch procedure:

search for the the byte sequence:
8b 4c 24 04 8b 44 24 08 53
and overwrite the first four bytes with:
c2 08 00 90
then search for the the byte sequence:
8b 4c 24 04 8b 54 24 08 81 f9
and overwrite the first four bytes with:
c2 08 00 90

This solution is now also available on the WSGF Games DB.