Very first up was making the Ambient light nicer. Below is screenshot of how it appears in HPL2:
This is just a uniform color blend that has been added and does not appear very. It is really tough to see any information when there is a uniform texture such as in the screenshot above. To get nice ambient lighting what you need to have to do is to somehow simulate worldwide illumination. Light does not just hit an object and then stop, but bounces about and scatters color from nearby on each and every other. There is a lot of analysis into this and most of it call for a single to pre-calculate the result in one particular way or an additional.
I settled with anything actually straightforward named hemispherical lighting, which fundamentally imply to have separate up and down (sky and ground) colors and then blend them depending on the typical of the surface. My 1st thought was to use cubemaps to do something comparable, but considering that the cubemap requirements to be really blurred, making use of hemispherical lighting gave fairly a lot the same result and is a lot quicker. Right here is the result:
Now it is a lot less difficult to see information and appears a lot greater.
Next up was the direct lighting from the sun and this was fairly easy. I could just add some tweak to the current shaders and make it operate. Essentially sunlight is just like normal light but without any position or attenuation. This means every single pixel is lit from the identical path and strength is independent of distance to the source (as it does not have a position).
Here is how the scene looks when we add that as well:
Considerably nicer, even though the texture is a bit boring. Note that there now is specular since of the direct light from the sun.
Finally, lets move on to the shadows! The engine currently feature the standard shadow rendering although a approach named shadow maps. What is the big issue now is to make it appear excellent over lengthy distances. Because shadow mapping operates by rendering from the light's point of view, performing shadows from an omnipresent light supply gets a bit difficult. The basic remedy is to use a really huge shadow map, but then you would get very undesirable resolution close to the camera.
What you do instead is to use the reality that objects take up smaller space of the screen the farther away they are. So the idea is to use the shadow map in such a way that you give far more space for pixel nearby and much less to those far away. This is one thing that has been researched quite a bit and there are various strategies to achieve this. A single answer is to warp the projection when rendering to the shadow map. This comes with a lot of concerns although and is extremely hardly ever utilized in games.
Rather most games use a technique named Cascaded Shadow Maps or Parallel Split Shadow Maps. The way this works is that the view frustum (a geometrical shape encompassing all the camera sees) is split into many components and a shadow map is provided to each split. This indicates that the 1st split, which is appropriate in front of the camera, gets a much bigger shadow-per-pixel ratio than the last split, which is much larger, but further away (and therefore has small on-screen pixels).
The algorithm itself is quite simple, specifically because there is very a few papers on it. The huge problem is that you can get some flickering outcomes due to the fact the shadow map can adjust a lot. There are published strategies that resolve this pretty effortless although. Most of my time was as an alternative spent on generating it perform with the rest of the engine. This is one thing that might not be that identified to non-programmers, but most of the function is usually not in the algorithm itself but fitting it into the engine design and style. I consider I commit a 3-4 days on acquiring it inside the engine, before I had every thing set up as it should. The in fact algorithm took two days or so.
Here is how it looks:
Note how shadows are detailed up front, however they are cast all the way into the distance.
Right here is how the shadow maps look (I combine all into a single a single):
These are the 4 shadow maps that all render shadows for diverse slices of the frustum. The white stuff is the objects, the red lines outlines the frustum slice and the sphere is portion of an anti-flicker algorithm (that determines size of shadow maps).
Now lets add this to the image I began with:
And lets add some nicer texture even though at it:
There! Sunlight with shadows is in!
My next job will be to update the really core of the renderer with one thing known as a Light Pre-Pass Renderer. Far more on that in a later post!