About Me

Hi. I'm Josh Ols. Lead Graphics Developer for RUST LTD.


View Joshua Ols's profile on LinkedIn


Skylights & Global Illumination


I've recently found out just how wrong this article really was when I learned about Image-Based Lighting and Physically-based BRDFs. So if you want to see the correct implementation, please refer to my new RSRM blog post.



You really don't appreciate the difference it makes in lighting until you take a look at any of the idTech 4 games, and see just how bad Lambertian + Constant Ambient really looks. Problem is, proper global illumination is a tricky business. Seems like there is no one perfect solution that won't cost an arm and a leg to get quality results. So you can imagine how this has caused me much frustration in my own project.


Approaches I've considered:

  • Hemisphere Lighting
  • Irradiance volumes 
  • Spherical Harmonic Light Mapping (SHLM)
  • Screen-Aligned Irradiance Volumes
  • Skylights 
  • Dynamic Radiosity <several techniques>

My requirements:

  • Dynamic illumination
  • Influenced by surface normals
  • Cheap to calculate offline and at runtime
  • Low storage offline and at runtime
  • Works in most situations, both indoors and outdoors
  • Works over great distances

After much deliberation and experimentation, I settled on Skylights. While not ideal, they meet enough of my criteria to make them a good choice. Also, the fact that the game Brütal Legend uses them to great effect made me see how they could be viable in a real game. :)



This was where things got a little tricky. There didn't seem to be a whole lot of resources on the web about how to implement a system like this. There were a few on how to implement a dynamic skydome, but that was about it.

Having read several articles off the web, I derived a system that employed a 2D lookup texture which held gradients for altitudes, and time of day. From this I cobbled together something that employed bits from hemisphere lighting to look-up values in the texture. This provided enough for diffuse lighting, and glossy specular.

A proper metallic reflection took a bit longer, as it was clear that it would need a separate function that behaved very differently. This proved to be more difficult, and caused me to have limited success for several months. That was until I stumbled onto the article Dynamic Sky & Rain Effect. This helped me fill in most of the missing pieces to get some nice reflections, and a crude skybox (need to switch to skysphere).

Sky diffuse (sharp) Sky glossy (sharp) Sky reflection


Figure 1. 1, Sky diffuse lighting; 2, Sky glossy lighting; 3, Sky reflection; 4, skymap



Firstly, it seems that metallic reflections only look good with smooth geometry. As you can see from the third picture, they don't seem to like normal maps. This means that I can't have bumpy reflections, which is less than ideal, but not a deal-breaker.

Secondly, getting a nice horizon in metallic reflections required me to draw a dark line across the bottom of my gradient texture. While this worked for metallic reflections, it had the side effect of causing a black void in diffuse and glossy reflections. Since it would be too much of pain to produce two maps for every skylight, I'm guessing I will need to come up with some more complex function that darkens values below the horizon. That way, the burden of fixing this problem doesn't fall on an artist.


That's all I have to report right now. I'll keep everyone posted on future developments. ;)



Picking up where the last entry left off, I'll start with materials, and meshes.

The trend these days seems to be keeping vertex data to the absolute minimum. All the material surface details are supplied by multiple high-resolution textures. Of course these high-res textures won't fit in VRAM at the same time, so they need texture streaming. Of course they will take up a lot of space on disk, so they need custom compression schemes. Of course, at runtime you will need to transcode them to a GPU friendly format. Then you need servers to manage the really huge textures between multiple workstations. Version control, custom tools...

I say screw all that, and keep it simple. So for my materials, it will be a combination of texture and vertex data. The goal here is to get sufficient pixel density for my materials to look good, but not have several giant textures per object, and all the hell that approach would bring.


For the sake of efficiency, the engine will support RGBA8, DXT1, and DXT5 textures. The expected average texture resolutions for most objects will be 1024 x 1024, 512 x 512. Most textures will default to trilinear mipmap filtering, not giving artists control over this option.

Most objects/characters will be limited to an albedo map and a normal map, in order to cut down on texture memory. Shared detail maps will be used to provide greater pixel density, as well as specular variance across the surface.

Emissive and specular color/intensity will be will be provided per-mesh, per-texture layer. Emissive might benefit from a unique texture, but only when there are a lot of different colored sources all over the object. Otherwise it would end up with a high-res texture that is mostly filled with black, with only small spots of emissive. Specular color/intensity would be better with a unique texture, but can be approximated well enough with per-mesh specular and detail maps.


  • float3, Position
  • float3, Normal
  • short4, Tangent
  • short2,Texcoord
  • uchar4, Detail texture masks
  • uchar4, Directional Occlusion
  • uchar4, Albedo tint color

I plan to split the data up into two interleaved arrays, one with dynamic data and the other with static data. I'm trying to figure out a scheme that would allow each to be 16-byte aligned. However, I think I will be fine with 32 and 16.

I believe I will be able to get away with using a normalized short type for my texcoords, but I am not sure about my tangents. I have considered using the half type for these two attributes. However, my plan is to perform animation on the CPU, so I am not sure it would really be worth the extra calculations.

The second array is all about material data, allowing an artist to control the distribution and color of detail maps per-mesh, per-vertex. Doing things like masking and occlussion per-vertex may seem old-fashioned, but it will drastically reduce VRAM usage. It also allows the values to be smoothly interpolated, even at higher screen resolutions.


That's all for now. Starting to sound intereting yet? ;)


Rendering Approach

Hey there adoring public! I've got an update! :p

Having had a chance to refine my plan, I now have a fairly good idea of how I want my game's renderer to behave. So without further ado, here you go!


It will utilize a hybrid of forward and deferred shading to allow some material variety, but avoid a shader combinatorial explosion. Each stage of the pipeline will be hard-coded, so it won't really be possible to arbitrarily add or remove new stages at runtime.

I'm not sure yet whether I will be using ubershaders with dynamic branching, or preprocessor definitions, to handle shader complexity. I plan to avoid writing a complex, generalized shader managment system.

As it stands, I will likely have to use a RGBA16F target for rendering, and accumulating lights. On SM 3.0 PC hardware, that is about the only way I know to allow multipass HDR lighting with linear blending. This point will be most important for alpha-blending, since I can't rely on sRGB blending for consistent behavior between DX9 and DX10 hardware.


A skylight system will handle ambient lighting and reflections, covering the vast majority of materials. This will consist of a directional light (the sun and/or moon), and an ambient light using a gradient texture. These lights are responsible for filling out the scene, so that it isn't too dark to see. This approach has the advantages of being simple, dynamic, and causing all the objects to feel integrated in the same environment.

Local lights will be handled exclusively by the deferred shading system. These will be Lambertian only, having no influence on specular reflection. For the most part, these lights are just for decorations or effects. This pass will be limited to lights that have a definite volume and extent (ie. NO directional lights).

Shadowing will only be provided for the sun directional light. Rather than darkening or going black, it will simply remove the sun's contribution from the skylight, while leaving the the ambient contribution. This way, detail will not be lost in the shadowed areas.

In the case of materials that need a custom BRDF (ex. Hair, car paint), the sun directional light will be used. The result will then augment or replace the reflections provided by the skylight.


More to follow in the journal entry. ;)


Plan of Attack!

Now that I have your attention, I think I will fill you in on the details of my big game project. Note I say "game" project, and not "engine" project. That distinction will inform most of the design decisions that will follow.

Having established all that, any good project should have some kind of direction, so here's mine.


  • OpenGL 2.1 (SM 3.0)
  • Cg
  • Bullet
  • OpenAL
  • Squirrel
  • wxWidgets
  • C++


  • Partial Derivative Normal Maps
  • Detail Maps
  • Skylights
  • Deferred shading
  • Linear Color Space calculations
  • HDR (?)
  • Directional Occlusion
  • Cascaded Shadow Maps
  • Framebuffer Distortion
  • Stipple Alpha testing
  • Distance Field Alpha testing
  • Linear Depth
  • Deferred Water
  • Soft Particles
  • Linear Alpha Blending
  • Alpha blending detail levels
  • CPU Skinning
  • CPU Blend Shapes
  • IK (?)


  • Asset viewer
  • Asset packer
  • Collada importer
  • .png, .psd, .xcf importer
  • Bump/Normal map converter

Final Word

Admittedly, this is not a complete list of everything that needs to go into this project. However, it covers most of the important points for what I have in mind. If anyone has any comments or suggestions from their own experiences, I would be quite happy to hear them. ;)


Setting Up Shop!

Hello denizens of the Interweb! I'm Josh, aka n00body. Welcome to my humble abode!

To get straight to the point, this site is where any interested parties will be able to track the progress of my graphics and game-related projects. Feel free to comment on my work, or even offer advice. I appreciate criticism, so long as it is constructive.


Page 1 ... 12 13 14 15 16