Giving In To The Graphics Pimp · 1303 days ago
Last week I decided to let myself play with improving the graphics of the game a bit. Usually I keep my graphics pimp on a tight chain since there is so much other work to be done on gameplay and art, but these deep desires can only be contained for so long before they demand attention. In the end this means great things for the gameplay.
Since I started working with the game engine I’m using, there were a few graphics things that bugged me. One was that if you used dynamic lights inside a building, all the buildings diffuse textures would be washed out. This really looked like monkey butt, and meant that I couldn’t use any torches or summoned lights to explore dark caverns in the game.
Looking into it a bit closer, when the buildings are rendered, the engine would do something like
first pass:
(lightMap * diffuseTexture)dynamic light pass:
alpha blend (dynamicLightTexture*color)This alpha blending of the dynamic lights looks ok, but it’s not really how lights work. What you really want to happen in this situation is for the dynamic lights to light the diffuse texture and then have the result add to any lighting in the game.
first pass: (the same)
(lightMap * diffuseTexture)dynamic light pass:
additive blend (dynamicLightTexture*color*diffuseTextureMap)Lucky for me all the hard work of setting up the dynamic lights in the engine was already done, I just had to dust off my fixed-function-pipeline programming knowledge and work on the graphics. In the end this only touched about 10 lines of code, but makes a huge difference to the game.
The next problem I ran into was reflective surface. I knew the engine had some basic environment mapping support built in, but hadn’t played with it much. This would be great for making crystals in the cavern. Setting it up to work was fairly easy. There is a materialProperty script file that you can associate certain properties with a given texture. So I can make all of my stone wall textures environment mapped with some code like this:
addMaterialMapping( “UEGSTN7” ,
“environment: UEG_TheTower/data/uegMade/interiors/uegStn7Env 0.5” );
This says that everywhere the UEGSTN7 texture is used, it is 50% reflective with the uegStn7Env texture.
This worked ok, but the first problem I saw was that it would show the reflection even in areas that are in shadow. So if you have a reflective floor and no lights on, you will see the reflection as though it were fully lit:
first pass:
(lightMap * diffuseTexture)environmentMap pass:
alphaBlend( lerp( environmentMap, diffuseTexture, factor) )This ignores the light map entirely, so you can see why it’s not shadowing properly. This has been used by some people to hack emissive textures into the engine which is nice, but a different feature than what I need for UnEarthed Gods right now.
I changed the environmentMap pass to do the following:
existingColorOnScreen*(1-factor) + (existingColorOnScreen)*environmentMap * factor
The first part of that equation gives you 50% (or whatever factor is) of the existing lightmapped texture on the screen. The second part gives you 50% of the environment map * the existing lightMapped diffuse texture. This isn’t completely realistic, but it gives the look I was after.
The final thing I had to do was move the environment mapping code into it’s own function that was done after the dynamic light pass. So now you can creep through a crystal cavern carrying a sputtering torch and everything looks how it should.
The moral: Yes, keep your desires on a tight leash, but let the graphics pimp out of the cave every once in a while and your game will be better for it.

