Single drawcall skybox – ShiVa Engine

Single drawcall skybox

Developing VR games for mobile is often very limited by the hardware capabilities. Stereo rendering means that your draw calls double right off the bat, so you really have to think of clever ways to minimise draw calls in your scenes. A regular sky box for instance requires 6 draw calls, that makes 12 in stereo. Not a good start for any self respecting draw call grinch… Let’s get that down to 1, or 2 in stereo!

Skybox Layout

First we need a UV mapped sphere mesh with the normals pointing inward. The sphere geometry needs to be made of 6 curved panels each subtending 90°, known as a “hexasphere”, “geosphere” or “round cube” in many 3D tools:
skywiki-mesh
Here’s the texture map that we use for the sphere material. Use an art package to assemble regular sky box sides into this composite atlas. Note that the panel aspect ratios do not remain square! I recommend a 2048^2 atlas for mobile and a 4096^2 atlas for desktop. For the material, you can disable “real” lighting and just illuminate it with the ambient color. To minimize overdraw, set the priority to 127, depth write disabled, and depth test enabled. Make sure all other scene materials have a priority lower than 127 and depth writes enabled.
skywiki-texture

Skybox Code

We need the sphere to always be just in view of the camera. So we import our DAE model with scaling such that the radius is at ~95% of camera.getMaxViewDistance. Incidentally, you should always keep your maxViewDistance as low as possible on mobiles, due to the reduced zBuffer resolution on those devices.
Then we need to parent the sphere to the camera. To make the sky translate, but not rotate with the camera, we need to set its transform options too, and put the code into the sky box onInit handler:

--------------------------------------------------------------------------------
function AI_SpaceSphere.onInit (  )
--------------------------------------------------------------------------------
    local hCam = application.getCurrentUserActiveCamera ( )
    local hObject = this.getObject ( )
    object.setParent ( hObject, hCam, false )
    object.setTransformOption ( hObject, object.kTransformOptionInheritsParentScale, false )
    object.setTransformOption ( hObject, object.kTransformOptionInheritsParentRotation, false )
--------------------------------------------------------------------------------
end
--------------------------------------------------------------------------------

That’s it, you now have a 1 DC sky sphere. On desktop machines, you can add fancy things like another skybox with cloud effects, moving stars, and so forth.

Advanced Lighting

To get better lighting, you can modify the method from above, although it will double your drawcalls again. In the pictures below, the skydome has its normals pointing outward and the material is double sided with vertex lighting enabled. Specular Shininess is set to very low, so the light falloff is very smooth. We are looking at the backside of the mesh from within the dome. The main scene directional light is a child of a sun/moon pair that rotates around scene origin. This way, you get the sky shaded nicely depending on the sun’s position.
skysphere_demo1
The skydome in this example has actually no additional DC cost, since it uses only a small part of the main super atlas for the whole scene:
skysphere_demo4

Credits and Links

Thanks to Fraser from SiliconDroid!
Link to the original forum post




Need more answers?

  • slackBanner