I like to make digital things.

Movies index page, dynamic tiled layout
Detailed movie view page, when movie is sourced
Hit 't' to quick search from any index
The player, playing an episode of Rick and Morty
Series index page, poster layout
Detailed series page, viewing 2 episodes in detail

μv (aka muvee)

2 Feb, 2013

The Goods

What is it?

muvee is something like Netflix, but run on a server from your own home. I created it to be an open source alternative to Plex. It can attempt to reach out to the Internet to find copies of media that you already legally own, but do not yet possess digital backups thereof.

muvee can control your Philips Hue light bulbs, dimming them when playback starts, and brightening them when playback is paused. There's even rudimentary support for copying hues from frames of playing video for added ambiance.

muvee reaches out to various metadata providers to enrich your media, downloading descriptions, lists of actors, audience feedback ratings, MPAA ratings, and most importantly, appealing background images.

You can mark a movie or TV series as a favourite, giving you quick access to it via the side navigation. This is handy for reminding yourself to check up on movies that may not have released yet, or for quickly resuming playback of a series you're currently binge-watching.

The series index has a shuffle button, which is great for creating an infinite playlist of that specific TV series. The Simpsons lends itself well to this mode. Since all the content is local, you don't have to deal with "Are you still watching?" halting your playback.

There's built-in discovery of new TV series and movies. muvee consults YTS and EZTV for new items.

Throughout the app, there are refresh buttons to reanalyze items, pulling down any updates to the metadata and fixing any difficult-to-categorize sources. Ideally, the buttons will be removed and this process will happen automatically.

My original motivation for creating muvee was that I wanted to view my media on my PS4, which did not support DLNA at the time. Alas, as I've iterated on the styles, I noticed that the PS4 browser can't handle flexbox. So, this is currently unusable on PS4. I've been using it with Chrome from a Mac Mini connected to my TV.

Why use this instead of the alternatives?

Popcorn Time is a modern marvel, but I believe in bandwidth conservation and caching things that I might use again. You would not believe how many times I've re-watched American Dad! The last time I checked, Popcorn Time just tossed all video files upon exiting.

Plex is great software, and has an incredible ecosystem around it. If you want a media manager that just works, I'd recommend you to use Plex. From my experience, Plex doesn't categorize media as well as muvee. It's also not completely open source.

I also looked at emby, and while nice and open source, it seemed a bit too complicated to really get going. The codebase is also prohibitively large for me to think about trying to tweak things.

Technical points of interest

I'm using two great libraries, TurboGraft and Twine, and this has greatly accelerated development. With them, I can make a website that behaves more like an app, without needing to write a true client-side application. So, at its core, it remains a simple rails project. Thus, this project mostly mirrors the paradigm my colleagues and I developed for the Shopify admin interface. I'm a firm believer that single-page applications have their place – when the task at hand is actually building out an application – but muvee is ultimately just a fancy CRUD website.

Background workers are heavily employed, as reaching out to all these metadata services is expensive and slow. Media is transcoded with avconv in the background, since browsers can't handle all modern codecs. Transcoding was/is a huge pain in the ass, but thankfully most rippers use h.264 now.

Current status

I am actively developing muvee, and use it in tandem with my Netflix subscription. It's gotten to the point where I very rarely have to manually intervene to correct unexpected behaviour. I love it, passionately.

echoplexus running as Firefox App on ubuntu
echoplexus used to be a lot darker! It got a revamp in 2014 for greater appeal.


2 Feb, 2013

The Goods

What is it?

Echoplexus was an anonymous, web-based, IRC-like chatting platform that made its best effort to respect your privacy. Here's a list of some of the features:

  • create and manage public or private channels
  • encrypt your chats with a shared secret or PGP
  • secure a pseudonym for linkable anonymity
  • code (JS) and draw together in real time
  • make free and secure Peer2Peer video and voice calls with the people in your channel using WebRTC

Current status

echoplex.us is dead. Now, a spammer owns the domain :/

The userbase / interest just wasn't there for it to be worthwhile for me to continue working on it. Due to the multi-player nature of the beast, I can't enjoy the project alone. One day, I'd like to revisit the concept with a better intial design plan; the ad hoc nature of feature development meant things were getting complex and more difficult to maintain.

Generally: the subtler the pattern, the better the result

WebGL Background Bump Mapping

12 May, 2012

The Goods

What is it?

Background textures have always been fairly flat and static things. I set out to increase their (apparent) depth.

It's not entirely practical, and in retrospect I'm not sure why I created it, but here it is! I think it's kind of neat and kind of pretty.

This project features WebGL, bump mapping, and the Phong reflection model to 'enhance' a websites background. I don't particularly recommend anyone to use it in any kind of production site at this time (like most of WebGL).

WebGL Strategy RPG Engine

5 Dec, 2011

The Goods

Executive Summary

Created for CS488 (Introduction to Computer Graphics) during Fall 2011 at the University of Waterloo as a final project. This marks the second time that I've taken this course. Against all odds, I somehow managed to miss the exam during my first course attempt, and was assigned a Fail outright. I'm pleased to announce that I have since passed this wonderfully fun course!

The focus was on procedural generation, completely framework free code. It was primarily an exploration in real-time interactive graphics, utilizing only shaders and modern graphics techniques.

I did not meet all of the objectives I set for myself, but I was able to explore: texture mapping, texture atlasing, bump mapping, procedural terrain, water reflections, animations using Catmull-Rom splines, Phong shading/lighting model, WebGL, OpenGL ES 2.0, AI pathfinding, Perlin noise, and context-free trees.

When I get the time, I'd like to explore more of the objectives I wasn't able to achieve, probably separate from this project. I've put in a bit of work to polish certain aspects (namely, the character animation and interleaving the terrain data), but haven't had time to commit the changes yet.

Multi-function scene
Mapped onto a spinning cube
Perlin's standard turbulence
Toon shaded / ghetto heat map
Version 1

Animating Functions of Improved 3D Perlin noise

27 Oct, 2011 – a sleepless night



In this experiment, I made a quick port of Ken Perlin's classical noise in 3 dimensions. Due to its continuity properties, we can take a 2D cross-section and step through the 3rd dimension in time. The end result is a continuous animation.

Technical Overview

After reading some of Perlin's work, namely some of his early SIGGRAPH slides, I became intrigued with the potential this has for both 3D texturing and the animation of 2D textures. Many of these 2D textures, when animated, can produce some very compelling effects. In this early demo page I show one example of something that looks like the activity of the planet Jupiter.

I employ fragment shaders to calculate per-pixel Perlin noise. Geometry is minimal, consisting of only 2 triangles that are un-transformed. Texture co-ordinates are generated and used in some animations, but for others only Fragment.xy is used. In all cases, time is used as an index to the Z plane of the 3D noise.

Benchmarks & Comparisons

All I can say is: Wow. WebGL (or more accurately, GLSL) fragment shaders are a huge step up in terms of performance when we compare to my old CPU implementation.

In the old implementation, on a 1GHz machine:

  • Firefox 7 would fail to achieve >30FPS on a 128x128 square.
  • Chrome 15 seemed to achieve >30FPS, or if not, the visual stutter wasn't too noticeable.

In the WebGL shader implementation, on a 1GHz machine:

  • Firefox 7 easily seems to achieve >30FPS on a 1680x945 rectangle.
  • As it did for the old implementation, Chrome 15 seems to outshine Firefox again.
  • Furthermore, both browsers can render arbitrary transforms (the texture mapped cube) of the noise, which is something that I would have considered impossible for real-time in the old implementation.

How do we account for the speed improvements? I would estimate that 99% of it is due to the change from CPU to GPU shaders; programming a highly parallelizable task on the GPU will naturally outperform its corresponding CPU-only implementation. Moreover, the computation of Perlin noise is relatively simple, which makes it a good fit for approximation on the GPU. I hypothesize that less JavaScript being employed might account for some of the speed improvement.


It was very tempting to use the "multi-function" noise as the background "image" for the Lab page. However, after trying it out (and it looks beautiful) I deduced that I couldn't do this in complete faith, since WebGL is still somewhat sketchy; I experienced >4 NVIDIA driver crashes, leading to complete browser failure. Interestingly, it also crashed my Photoshop (and so probably any other program using your GPU extensively). It was either gamble with the value of my visitors' work or use a screenshot, and I think I made the better final choice.

So, where does this leave us? I now have a useful tool that will allow me to explore various noise patterns from within the browser; no need to attempt compiling an application that will then compile the shaders. No need for a ton of external dependencies; just download the page, edit the shaders at the top of the source, and run! This should hopefully allow me to explore new types of noise with ease.

Additionally, WebGL would seem to be a fairly good reduced-power environment. That is to say, we can expect the shaders to perform faster if they were used in a native C++ program, for example.

Finally, those who want to learn more about shaders or procedural art might find looking at my code to be of some use. I've set up the sample pages in such a way that they should resize to fill your browser window completely. As such, if you go to full-screen mode (F11 key in most browsers), you can take a screenshot or save a perfect-fit wallpaper quite easily!


A ray-tracer with a focus on various material properties

26 Jul, 2011

The Goods

Executive Summary

Created for CS488 (Introduction to Computer Graphics) during Summer 2011 at the University of Waterloo as a final project. Math in action.

Render time: Approximately 2 minutes each.