Friday, 21 February 2014

And He Said: Let There be Shade

This week the topic I will be covering will be shadows

Radiosity

Direct illumination is not realistic but radiosity is more. With radiosity you are not cutting off at shadows directly but with it shadows do not have sharp edges. The edges are soft and blurry which gives it a feel or realistic and ambient light. Windows and other edges will gain light as it can now be lit through reflected light instead of relying on direct contribution.

Add power to everything for reflection and set the power to zero except for the light sources, you then sort everything in order of how much power it has. Then you thrust some of the power to all the triangles you see, rinse and repeat.

Shadows

Shadows are used as a form of visual information that allows us to discern the position of objects at a distance as well as how the light is a scene operates. From shadows we can discern the strength and direction of light.

Shadows also give realism to a scene. If there are no shadows then a scene will look off. Not only this but shadows give us an idea of the space an object occupies, if something does not have a shadow, or if the shadow is far away then it looks like it is floating, but if the object is connected to its shadow then it looks like it is on the ground.


Shadow Mapping

With shadow mapping you want to render the scene twice. The first time you render the scene it is from the lights point of view. From this we can get the depth values of all the objects from the light point of view. This will create what is called a shadow map. You then render the scene from the cameras view. The newly created shadow map is then projected onto the scene after being compared to objects depth transformed to the lights position. Areas that are further away from the light than indicated by the mapping are then shaded.
This can create a few problems, the first problem being aliasing. Since all you are doing is overlaying a texture the edges could be jagged. 

We could always raise the texture resolution but there are other ways to fix this issue. The first way would be to compare multiple samples of the same map and then filter them. The second way would be to smooth the edges by using the UV offset of the texture to weight the mapping. If we pull ourselves off the grid system then we can use non-uniform sampling. While error is still there we can randomize our samples. Our offsets can be coded in; we can store two per vector for optimum efficiency. You have to be careful because constantly changing you offsets will give you undesirable results. You can pre-compute your values in the screen and based on your already aligned textures.

Depth Masking

There is always a problem though. If an object is behind another one, we still calculate the lighting and shading, even if we cannot see it. This leads to a large amount of unnecessary calculations. In this kind of scene we try not to use edge mapping, instead we use depth mapping, where, if there is an edge, we do a minimum and maximum depths for the region, this prevents us from having to do shading for multiple objects that we cannot see.

Shadow Silhouettes

Silhouette mapping is a way of increasing the qualities of our shadows without having to increase the size of our textures. The map contains new positions for the centers of each texel. To do this there is a three step process, first we start out by rendering our shadow map, after that we render our silhouette map. We offset our mapping centers in order to represent our edges better. Finally we do our lighting pass. Through the silhouette we chose which shadow map texel to pull data from.

To do this we find the location of the current pixel. We then grab the data of its neighbouring pixels as well. Using this data we find out which area quadrant the sub location is.

There is one large limitation for silhouette mapping. There cannot be overlapping silhouettes, doing so creates artifacts. Despite these limitations silhouette mapping provides a much higher quality than regular shadow mapping.

Bias

Bias is an increase of the depth values of your shadow map. You use this when you get incorrect depth values while shading you scene, a problem caused by the limited precision of depth maps as well as differences in the sampling rates of shadow maps and the sampling rate of the scene. If you have to little bias then you get artifacts along the orders of you shadow but if you give too much bias the shadows will become disjointed from the body itself.

A bias has two components, numeric and geometric. The numeric component is simply the shadow map component. The geometric component is the fact that when a shadow map is applied to an area of a scene, they only represent a single depth value, this means that a low resolution map, or a highly sloped scene will affect precision.

To understand bias we need to understand depth textures. These are what shadow maps use and, are themselves, essentially shadow maps. These maps hold data from the scene that holds the depth of each piece of geometry. Through rendering into the depth map we are able to not only save memory, but render any sized depth texture. These take care or memory issues and slope based bias without any additional cost. We use depth textures for depth of field, semi-transparent objects, lens flares and fog.

As you can see above, the light is hitting the plane at an angle. This causes shadow disconnect. What we want instead is a flattened, untangled shadow map. For this we need to know how the depth of the terrain changes based on the texture coordinates.


To do this we need to get the derivative of the texture coordinates based on the screen, or view, coordinates. This creates a transformation matrix which transforms information in the screen space to the texture space, this allows for proper mapping.

Monday, 3 February 2014

Blurred Design



Week 4

Well, its week four and here we are, this is where the difficulty ensues. Well, at least for me. This week we started to learn about blurring.
Convolution Kernel Filtering

Kernel filtering is a way of processing images through a “filter”. Through it you take a sample of the pixel and the surrounding pixels from its texture, then you use the sum of these pixels based on their weight. This new pixel is placed on to a new texture.



When you need to move over pixels you increase you pull location by 1/textureWidth and when you reach the end of a row you need to increase the height by 1/textureHeight.

More information: http://www.aforgenet.com/framework/features/convolution_filters.html

Blurring

Box Filter – A filter\ where every pixel is weighted the same.

 Left- regular image, Right – Box Blurred

Gaussian Blurring - Where the middle has a higher weight and the surrounding ones have a lower weighting; the bigger the sample window, the stronger the blur.

Edge Detection

Design a convolution kernel that favours things with a high change. Output values where left right values are different. For example the following is a sobel filter.




-1
0
1
-2
0
2
-1
0
2


-1
-2
-1
0
0
0
1
2
2

The top graph detects for edges on the x axis while the bottom graph detects for edges on the y axis. This gathers data for when the color of an object drastically changes letting us find when there is an edge. Then at this edge we can add in extra light. Normally you would do this in the lighting and shading but you do not have access to your neighbors in a fragment or vertex shader, therefore you need to do this in a second pass after the whole scene is saved as an image.

HDR, Bloom and Frame Processing

HDR and bloom are done though a post processing effect. It is done after you have your geometry and lighting.



Following the above steps you should end up with three separate textures which you merge together into the final frame. This data is processed in layers where you start with the base image and add the data together into a new image. This is done after rendering. To display your final image you would save everything in you back buffer, then make it into a texture. Then you make a quad the size of the screen and attach this texture to it. Through this process you can do everything through shaders. By sending the vertex information you can interpolate the UVs of the quad and send them to a pixel shader; this shader is called for every pixel. This means that this whole process can go into one function. If we want to make the image smaller than we just need to draw it at a percentage of its size.