WebGL Development Update 4 – Better Performance

After the disappointing results on my iPad 3, which is by no means a slouch, I concluded (after some experimentation – see last post)  I can not use lights. Or I could use lights, but only with the most basic material types which do not support normal or specular mapping.

This presented a difficult decision. On the one-hand, lights make the scene dynamic and give me (and by extension; the user) full control over the WebGL scene. They cast real-time shadows and present the scene in a relatively realistic way thanks to a combination of normal and specular mapping. However, I must keep sight of why I am doing this. I am hoping to approach property developers who might see this technology as a welcome addition to their web provision. The users of the websites will arrive using a range of different browsers and hardware. If I am to convince my potential clients I have to make this content accessible to as many people as possible, including people using old browsers or slow devices.

Without lights, the scene looks flat but there is another way: Light Mapping.

Light Mapping has been used by real-time game engines for a while now. Essentially you have a development environment that has built in raytracing, you create your scene using your models and materials that would export for a real-time platform, light your scene using as many lights as you wish, and then you request the renderer to create lightmaps for all your models.

These maps are texture files (2D images), just like the diffuse, normal and specular maps discussed earlier in this experiment. If your real-time 3D platform supports them (most do), you can then apply the lightmaps to each model (using its material – just like other types of mapping) and the 3D engine will blend them with the diffuse to create the sense your scene is lit:

wall_bricks_high_light_2
An example light map created in 3D Studio Max of the walls for the house.

You can then delete all the lights in your real-time 3D platform and the light maps take over the job of suggesting the scene is lit.

Here are the benefits of this approach:

  • Performance is dramatically improved so that even the slowest device which supports WebGL (providing the polygon count is also appropriate) will run the scene smoothly.
  • To get a realistic looking scene in WebGL you only require the diffuse and light maps. Normal and specular mapping will have no effect if there are no lights in your real-time scene. You do still need to create them however as they are considered when rendering the light maps (if the lighting is treated properly in the 3D modelling application).
  • Light maps are usually quite small in terms of file size compared to a normal map for example, so this approach is great for transmission across the internet.
  • You can save time by using a 3D modelling application which has better methods and workflows for setting up lighting.
  • It’s far easier to apply ambient occlusion in your scenes for the same reason as above.
  • Using this approach creates the most realistic lighting possible as you can indirectly harness the power of a ray-tracing tool such as the renderer found in 3D Studio Max to create the lighting. Relying solely on real-time lighting, which, for the sake of performance, offers only a very rough approximation and there’s limits to how it behaves (in terms of radiosity and ray-traced shadowing).

However, there are some drawbacks:

  • It adds extra process to the workflow. Rendering a light map doesn’t usually take a great deal of time to generate, but you have to add a second set of texture coordinates to each model as light maps (for obvious reasons) can not tile like your diffuse, specular and normal maps do.
  • Although 3D modelling applications have better methods and workflows for setting up lights (as listed in the benefits above), it is actually very difficult to do for the inexperienced as it feels like there is an infinite amount of variables to control.
  • If you decide to change the lighting in the scene, you have to go back into your 3D modelling application, change the lighting and generate new maps for each object. Again, slowing the workflow right down.
  • There is no control when inside the real-time 3D environment. Lighting, shadows and occlusion are all hard-coded into the exported assets meaning there is nothing you can change with code thus making the scene static.

The decision therefore to use this static lighting approach rather than the real-time (dynamic) lighting should not be taken lightly (no pun intended). You really have to weigh up the pros and cons for each approach, considering always your output and target audience. Only when you have a clear winner should you commit to an approach.

One suggested approach could be that you create the scene for real-time lighting (as you still need the normal and specular maps for light mapping) AND create the light maps when you are done. Providing a WebGL project with all assets means you might be able to code a performance monitor and select between a dynamically or static lit scene depending on the devices/browsers capabilities.

I am going to adopt this approach as there isn’t too much extra work involved and when it comes to working on the scenes but I will save implementing the dynamic lighting scenes for when the project reaches a further stage of development where real-time lighting and shadowing are essential – such as customising the interiors.

Implementation

So, after considering all of the above, here is what the output looks like running on an iPhone 6. It looks identical on my iPad 3 Mini and iPad 3. More importantly, on all the devices I’ve tested this on, it runs at a very smooth 50 – 60 fps meaning there is scope for increasing the geometry and material count:

IMG_0070

Take a look for yourself.

Although the loss of real-time lighting (for now) is a disappointment, I am more than happy with the way the output looks and, more importantly, how consistently smooth it runs across the range of devices/browsers I have tested it on.

My plan now is to finish the exterior but adding the final bricking detail to the front, add all details to the remaining 3 sides, and finally create the extra models of the garage and maybe the fencing and basic garden details. After all, the potential customer will be purchasing the complete plot, not just the house.

I also had the idea of being able to toggle viewing the surrounding houses. They would be extremely low polygon and contain no other detail than the shape of the building. They would only a very basic occlusion lit map applied to them.