Ray Lighting: Creating realistic shadows for terrain
In this paper I present a method for creating realistic shadows using a ray tracing technique. The technique calculates the shadows in advance and then adds them to the scene at runtime. Therefore it is not suited for real-time calculations. By using angle based theoretical sun rays the method is able to calculate the shadows shape and brightness in a realistic way. The brightness of the points in the shadows is calculated using a greyscale that simulates the amount of light reaching the different points. To simulate the influence the points have on each other the shadows are blurred. The technique is mainly focused on creating realistic shadows but simplicity is also an important factor.
Shadows are a common part of the world. Adding them to your 3D graphics will add a whole new degree of realism. Without shadows scenes often feel unnatural and flat which confuses the viewer. Over the year several techniques have been developed to create these important shadows.
There are two main approaches for shadow calculations: real-time shadow calculations and static shadow calculations. Using a real-time technique shadows are recalculated every frame whether or not the scene has changed. This way the shadows are always accurate when objects or the light sources move. However one mayor drawback to recalculating the shadows every frame is the large amount of processing power it requires, thus slowing down the rendering of the scene. To counter this calculations have to be fast, which decreases the shadows' realism. Static shadows avoid the issue of having to calculate the shadows in real-time. Instead, the shadows are calculated in advance and then added to the scene at runtime. This allows slower and more complicated calculations since the shadows only have to be calculated once during initialization.
Because terrain is static and doesn't change in shape or position there is no need to recalculate the shadows each frame. Therefore the best choice for terrain rendering is static shadows. In this paper I am going to present a way I have developed to calculate the shadows of a terrain using static shadows calculations. By calculating the shadow based theoretical sun rays the method will be able to create smooth and realistic shadows. The method is characterized with the following features:
2. The Algorithm
2.1. Basic Shadows
The ray lighting method draws a theoretical ray with an specific angle from each point on the x-axis. It then checks each point on that ray starting from the shadow's maximum width (based on the heightmap's highest point) against the heightmap to see if the terrain intersects the ray. If it does this point will cast a shadow on each point that precedes it that is below the ray. Figure 1 should give you a better understanding.
The method needs a way to calculate the rays' height at different points. For this it uses some trigonometry.
This leads to the following equation:
The tan function uses radians for calculation and there has to be made some changes for use of degrees. A full revolution, 360 degrees is the same as 2π. To convert from degrees to radians it has to multiply the angle by the fraction (360/2π) or (180/π).
Since the ray is not a vertical line the method can't stop calculating the RayOriginX when it reaches 0. Terrain won't be included if the terrain is higher than the ray at 0. Since the ray never is vertical there will most certainly be terrain that is not included. To prevent this the calculation needs to continue in the –X direction. The distance it has to go is calculated with the following equation:
Figure 2 illustrates the problem and its solution.
2.2. Soft Shadows
Since different amounts of light reache the ground at different points the different points will have a different amount of brightness. If this is not included in the calculations the shadows will look flat and non-realistic. To simulate the amount of light intersecting the different points a greyscale is used from which the brightness is calculated. This will make points closer to the shadow's origin darker than the ones further away, giving the shadows more depth and making the terrain's outline more visible. Figure 3 illustrates this.
The shadow starts from ShadowOriginX which is the x-coordinate of the highest point that intersects the ray. To keep all the shadows' brightness the same regarding their height, position, etc., a constant greyscale using the coordinates within the current greyscale is used to calculate the different points' brightness. This is shown in Figure 4.
Two variables are needed to hold the x-coordinate of the shadow's origin (ShadowOriginX) and the shadow greyscale's height (ShadowY). Then a variable is used for the greyscale's maximum brightness (because it should be able to modify the shadow's brightness). Then there is an equation to calculate the brightness of the different points.
The equation calculates the x and y-coordinates for the point in the small greyscale. It then divides them with the greyscale's x and y-sizes to get a percentage of the entire greyscale, then multiplies that percentage with the maxBrightness value which is the constant greyscale's size.
These are not physically correct calculations but they give very realistic results. They give the shadows more depth and blends the shadows into brighter areas.
2.3. Shadow Blurring
The sun is a large light source causing the shadows to be blurred. The shadows will be blurred by getting the mean value of all the points in the shadow and its neighbours. This way the points get a bit brighter or darker depending on the brightness of surrounding points. The points in the direction of the sun won't be a part of the calculations since they don't reach the shadow.