Lantern, part 4

05/05/2016
Simon Rodriguez

During the winter break and in the last few weeks, I've had a bit of time to continue working on the Lantern. The project is by no way finished, but I have designed almost all the lantern parts (basis, columns, and some of the tops). Each category is divided in three groups, each with a base shape: circle, square or octogon. Each sub-category contains approximately five 3D models authored in Blender.

Since the last log, I have stopped using Collada files to store my models, and rely instead on the SceneKit scene format, which allow me to edit objects directly in Xcode. Furthermore, this gives me the ability to compose and preview the whole scene at once, including the lights, camera, and other objects.

Editing a scene in Xcode

I have also designed alternative candles and lights, always trying to create models with a low number of polygons but that still have a distinctive look and shape. I think that they combine nicely with the flame and particles effects. For each model, ambient occlusion is computed offline in the SceneKit editor and stored as a vertex attribute.

Various candles models

Phrases generation

To make each generated lantern feel more original and specific, I wanted to generate a random short sentence. I chose to simply draw at random a year, a ship name and a place, from a list of 500 harbors and 5000 ships. I scrapped the data from various online sources (mainly ship wreckages and naval places lists taken from Wikipedia), cleaned it and formatted it properly for my needs.

Sentences displayed in the app

Optimizing the floor

In the previous version of the Lantern, I noticed a drop in framerate as soon as the camera was pointing downwards, looking at the ground plane. The reason was that, in order to properly mix the plane with the background and the lighting effects in a seamless fashion, I was applying a transparent radial texture on it. This led to a lot of alpha blending, and a performance hit as soon as the plane was covering a bug part of the screen.

The gradient used

Fortunately, I replaced this tweak by another one: applying a shader modifier to the floor, I fill pixels that are further away from the centre than a given radius with the background color [1], recreating the seamless blending.

float longueur = length(_surface.diffuseTexcoord - 0.5);
if(longueur>0.4){
    float factorMix = clamp((longueur-0.4)/0.1), 0.0, 1.0);
    _output.color.rgb = mix(_output.color.rgb, vec3(0.105,0.12,0.195), factorMix);
}

Other versions

As SceneKit is designed to be used on all Apple platforms, I tried to make the Lantern run on OS X as a side experiment. Once the generation and scene handling code was separated from the interface [2], it was easy to create targets for iOS, OS X and even tvOS. An additional benefit is that I can now debug the lantern procedural generation using the Mac app, with no simulation overhead, and a specific interface where I can manually edit each part of the lantern.

The mac version of the Lantern app

The tvOS infos pane

I am also thinking about writing some kind of lengthy OpenGL tutorial where I would recreate the lantern scene in raw OpenGL, step by step. After following multiple courses and tutorials on the subject, this would be a nice way for me to enhance my understanding of this complex machinery.




  1. with a smooth transition area

  2. platform specific