Lantern, part 3

2015/09/04 | Simon Rodriguez | ios rendering scenekit sound
Table of Contents

After a few silent weeks, some news about my Lantern project! I spent some time polishing the 3.4 Aquarii update, but also had the time to add many features to this project. Many general improvements have been made, and things like sounds, effects and procedural generation have been implemented.

head pic
head pic


The soundscape has been built in the last four weeks. I'm mixing multiple backgrounds sounds : waves breaking on the coast, fire crackling, combined with two layers of wind. The ocean and wind recordings are played at a constant volume, whereas the fire sound volume is adjusted based on the distance between the viewer and the lantern. On top of those, chimes and bells sounds are played randomly from time to time. The sounds are all copyright free, taken either from the GarageBand loops ressources or from online sound libraries. The background sounds have been looped and corrected in GarageBand.

A short recording of the app's sound:


I've improved the particle system used for the fire. It took a lot of tweaking and real-life observations to get something that starts to look like the flame of a candle. I'm quite satisfied by the current result, in combination with the burning ashes.

Lantern generation

Each time the user starts the app, a new lantern is generated. I wanted to use a pseudo-random generator based on a seed, to allow users to re-generate previously generated lanterns. This ruled out the usual random source in Swift/Objective-C, namely arc4random(3). For each lantern, only a few numbers are generated, so I needed a reliable source, ie not rand(1). The rand48(3) family of functions was good enough for what I wanted to do : it can be seeded by calling srand48(seed) and can generate (among other types) double values (drand48()) and long values (lrand48()).

Each lantern is divided in three parts : the base, the columns and the top. For each part, the height, radius, type, general shape and 3D model are determined using the pseudorandom generator. There are three general shapes: circle, octogon, square; multiple 3D models are associated to each one of those. I've already modeled 12 bases templates, combined in one Collada file. They are deformed to fit in a 1x1x1 box, so that the generated radius can be directly applied as a scaling factor, independently of each shape.

bases in blender
bases in blender

For the columns, I'm currently limiting their number to four. I could place an arbitrary number of columns correctly placed and oriented, but as I want to provide closed lanterns (with glass panels for instance) without having disgracious scaling deformations when placing the panels, I chose to simplify it for now.

I'm now hitting the part where I have to model all the columns and top templates in Blender. This is clearly going to take some time. Once they will all be designed, I could try to texture them, or at least add normal maps.


I've also started to clean the interface. Exit the coloured tests switches, only three simple buttons remain : sharing, sound control and information. This is my first important project where I'm using Autolayout. I prefer to have pixel perfect control over my interface, but this is extremely convenient to (almost) automatically adapt a simple interface to various screen sizes. The lantern now being procedurally generated, you can change its seed[1] in the information panel. The user can input text instead of just numbers: people like to enter names, sentences, that are easily remembered and/or have a personal significance.

information panel screenshot
information panel screenshot

The information panel also displays a few links (contact, App Store page, website). As you can notice on the screenshots, there is room in the center of the screen for more text. More on this in the next update!

  1. a number used to initialize the random generator. Each time you use the same seed, you will get the same sequence of numbers.