Moon Clock a WebGL experiment

webGL moon clock build showing space warp mode


WebGL experiment →
Click and drag/or Ctrl drag

 

This was an experiment to recreate Graeme's Moon Clock iOS app in WebGL. WebGL allows you to render a 3D scene in the browser, using the graphics card to hardware accelerate the rendering. It uses openGL ES, which was developed for mobile devices years back, it's a limited, cut down version of openGL. In email terms it's like desktop Outlook, an old tech with a bunch of constraints. WebGPU is WebGL’s replacement, it’s starting to roll out now with Chrome having just added support. WebGPU is a big jump forward, so we should see more 3D content on the web and subsequently in email; obviously in a limited way as Gifs. Though for now WebGL has solid browser support at 96%. Besides using the Moon clock iOS app myself — we've been spending time in Scotland, and moonlit nights are lovely compared to LA —  I've not had much to do with this project, so I'll let Graeme explain this one.

 

Low light photography

Deserted beach, sky in soft pastel colors, showing the moon over the sea on the West Coast of Scotland, UK

West Coast of Scotland, UK

 

I built the original iOS app for my own use, as I had an interest in low light photography, specifically in moonlit photography. I was regularly visiting timeanddate.com to check the current and future moon phase. So a simple one page app displaying the moon's current and future state, would be useful and convenient.

 

Tech

The layout and functionality was first prototyped in SVG. The general idea was to convey as much information about the moon's state as possible, in the simplest way. For the iOS/WebGL builds the entire UI is rendered via a pixel shader. This shader utilises ray tracing of two basic primitives, a sphere and a quad. All dynamic text is rendered using manipulation of the UV coordinate data returned from collision with a quad. The moon is rendered using the sphere primitive and is textured with a diffuse texture and a normal map for surface detail, all lighting is generated dynamically based on information regarding the moon's current state. Because there are no external dependencies or libraries, and being a single shader, it can be ported easily. So I used the iOS source code (written in Objective-C and Metal shader language) to create a JavaScript/WebGL implementation. Some compromises had to be made, for example the iOS implementation relied on gyroscope and accelorometer input when using the spacewarp functionality (you just have to move the phone around in your hand). This isn't going to be possible in the browser, you have to hold the Ctrl key and drag the mouse.

 

Interface

I wanted a simple, uncluttered interface

I wanted a simple, uncluttered interface.

What it tells you

  • Current moon phase
  • Time the moon crosses meridian
  • Time the moon rises
  • Time the moon sets
  • Moon's current libration
  • Moon's apparent size
  • Brightness of sky at time of meridian crossing

The clock top left displays the current time and date, you can switch between 12 and 24 hour display by tapping/clicking on the clock. The UI always displays the current moon phase at the time shown on the clock. It also illustrates the moons libration and apparent size due to distance (the moon phase is constantly changing and the moon image represents the moons properties right now) not at the time of meridian crossing (when the moon appears at its highest point in the sky).

Screen color approximates the sky at meridian each day (moon highest point in the sky)

Screen color approximates the sky at meridian each day (moon highest point in the sky)

 

The dial around the moon represents a twenty four hour clock. The small triangle shows the time at which the moon will cross meridian on the current day. If the moon does not cross meridian on that day it will show the time of meridian crossing on the following day and the triangle marker will turn blue instead of white. The green bar shows the time of moonrise, this is relative to the meridian crossing so it may indicate the time on the previous day. The red bar shows the time of moonset, this is relative to the meridian crossing so it may indicate the time on the following day. The screen color approximates the brightness of the sky at the time of meridian crossing. So you can easily tell if the moon is up during daylight or night time.

 

Timewarp

Timewarp mode, showing 20th July, 2174

Timewarp mode, showing 20th July, 2174, click and drag left/right in WebGL

 

Some days there's not much to see

Some days there's not much to see

 

Moon clock can display the moons properties for any day over the last millennium and through the next millennium ( I had fun checking dates like my birthday – Anna). In the WebGL build click and drag left/right on the moon, or give it a good mouse flick and it will run on it's own. Timewarp speeds up over time, from days to months, to years the longer it runs. Once it gets going some flashing will occur, as the sky color changes when travelling fast through time. Double click on the moon to return to the current date.

 

Spacewarp

Spacewarp 2.5d mode, Ctr click and drag in WebGL

Spacewarp 2.5d mode, Ctr click and drag in WebGL

 

In the WebGL build Ctrl click and drag. On iOS swipe down on the moon for 2.5d mode; swipe down again to see the Moon Clock in 3d. Tilt/rotate your phone to pan around the moon up to 160 degrees.

 

Location

The Moon Clock iOS app uses your current location to do its calculations. It only checks once at startup (it does not track your movements). So if you change your location you will need to restart to get accurate information about the moon. For the WebGL build it defaults to UK (GMT) time, and isn't using any location data, though for testing purposes there's a hack.

Timezones 1 –  6 on keyboard

  • 1 UK (GMT)
  • 2 LA (PST)
  • 3 Tokyo (GMT+9)
  • 4 Helsinki (GMT +3)
  • 5 Rio de Janeiro (GMT -3)
  • 6 Sydney (GMT +10)