2019-04-07 00:18:43 +02:00
# Appendix
![
2019-04-07 20:29:35 +02:00
The seqmented pane with the cobble texture and normal map and lighting applied to it.
2019-04-07 00:18:43 +02:00
](images/0-base.png){#fig:img-base}
![
The plane from @fig:img -base with a perlin noise displacement map applied to it
](images/1-perlin-displacement.png){#fig:img-perlin-displacement}
![
First rendering of the downloaded grass texture and normal map
](images/2-wrong-handedness.png){#fig:img-wrong-handedness}
![
Rendering of the downloaded grass texture with flipped normal map handedness
](images/3-flipped-handedness.png){#fig:img-flipped-handedness}
![
The field with grass texture, normal map and displacement map
](images/4-fine-plane.png){#fig:img-fine-plane}
![
How a mirrored-on-repeat texture behaves
](images/5-gl-mirror.jpg){#fig:img-gl-mirror}
```{.cpp #lst:new -tbn caption="Modified TBN matrix to account for the slope of the displacement"}
if (isDisplacementMapped) {
float o = texture(displaceTex, UV).r * 2 - 1;
float u = (texture(displaceTex, UV + vec2(0.0001, 0)).r*2-1 - o) / 0.0004; // magic numbers!
float v = (texture(displaceTex, UV + vec2(0, 0.0001)).r*2-1 - o) / 0.0004; // magic numbers!
TBN = mat3(
normalize(tangent + normal*u),
normalize(bitangent + normal*v),
normalize(cross(tangent + normal*u, bitangent + normal*v))
);
}
```
![
The displaced field with the TBN matrix rotated along the slope of the displacement.
](images/6-displacement-normals.png){#fig:img-displacement-normals}
![
Car mesh loaded from car model, without transformations
](images/7-car-meshes.png){#fig:img-car-meshes}
![
Car mesh loaded from car model with transformations applied.
](images/8-car-transformations.png){#fig:img-car-transformations}
![
Car mesh loaded from car model with transformations applied, rotated to make z point skyward.
](images/9-car-coordinate-system.png){#fig:img-car-coordinate-system}
![
Diffuse colors loaded from car model
](images/10-car-materials.png){#fig:img-car-materials}
![
Diffuse, emissive and specular colors loaded from car model
](images/11-material-colors.png){#fig:img-material-colors}
![
Car model with all colors, with reflection mapping applied.
](images/12-reflection.png){#fig:img-reflection}
![
The reflection map texture applied to the car
](../res/textures/reflection_field.png){#fig:img-reflection-map}
![
Tree model loaded from model file, no texture support yet.
](images/13-tree.png){#fig:img-tree}
![
Tree model loaded from model file, textures applied.
](images/14-tree-alpha.png){#fig:img-tree-alpha}
![
Tree model with textures, transparent meshes rendered last in sorted order.
](images/15-tree-sorted.png){#fig:img-tree-sorted}
![
Tree model with textures, transparent meshes rendered last in sorted order, with depthbuffer in read-only mode.
](images/16-tree-depth-readonly.png){#fig:img-tree-depth-readonly}
```{.dot include="images/rendering-pipeline.dot" caption="The scene rendering pipline, handling transparent nodes" #fig:render -pipeline}
```
![
Grass model loaded, cloned and placed randomly throughout the scene
](images/17-low-fps.png){#fig:img-low-fps}
```{.cpp caption="The node uniforms being uploaded to the shader" #lst:uniform -upload}
glUniformMatrix4fv(s->location("MVP") , 1, GL_FALSE, glm::value_ptr(node->MVP));
glUniformMatrix4fv(s->location("MV") , 1, GL_FALSE, glm::value_ptr(node->MV));
glUniformMatrix4fv(s->location("MVnormal"), 1, GL_FALSE, glm::value_ptr(node->MVnormal));
glUniform2fv(s->location("uvOffset") , 1, glm::value_ptr(node->uvOffset));
glUniform3fv(s->location("diffuse_color") , 1, glm::value_ptr(node->diffuse_color));
glUniform3fv(s->location("emissive_color"), 1, glm::value_ptr(node->emissive_color));
glUniform3fv(s->location("specular_color"), 1, glm::value_ptr(node->specular_color));
glUniform1f( s->location("opacity"), node->opacity);
glUniform1f( s->location("shininess"), node->shininess);
glUniform1f( s->location("reflexiveness"), node->reflexiveness);
glUniform1f( s->location("displacementCoefficient"), node->displacementCoefficient);
glUniform1ui(s->location("isTextured"), node->isTextured);
glUniform1ui(s->location("isVertexColored"), node->isVertexColored);
glUniform1ui(s->location("isNormalMapped"), node->isNormalMapped);
glUniform1ui(s->location("isDisplacementMapped"), node->isDisplacementMapped);
glUniform1ui(s->location("isReflectionMapped"), node->isReflectionMapped);
glUniform1ui(s->location("isIlluminated"), node->isIlluminated);
glUniform1ui(s->location("isInverted"), node->isInverted);
```
```{.cpp caption="Function for caching the uniform locations per shader. The commented line is the old implementation." #lst:location -cache}
GLint inline Shader::location(std::string const& name) {
//return glGetUniformLocation(mProgram, name.c_str());
auto it = this->cache.find(name);
if (it == this->cache.end())
return this->cache[name] = glGetUniformLocation(mProgram, name.c_str());
return it->second;
}
```
```{.cpp caption="The uniform caching defines" #lst:uniform -cache}
bool shader_changed = s != prev_s;
#define cache(x) static decltype(node->x) cached_ ## x; \
if (shader_changed || cached_ ## x != node->x) { cached_ ## x = node->x;
#define um4fv(x) cache(x) glUniformMatrix4fv(s->location(#x), 1, GL_FALSE, glm::value_ptr(node->x)); }
#define u2fv(x) cache(x) glUniform2fv( s->location(#x), 1, glm::value_ptr(node->x)); }
#define u3fv(x) cache(x) glUniform3fv( s->location(#x), 1, glm::value_ptr(node->x)); }
#define u1f(x) cache(x) glUniform1f( s->location(#x), node->x); }
#define u1ui(x) cache(x) glUniform1ui( s->location(#x), node->x); }
```
![
Car, trees and grass combined into a night driving scene. Two yellow spot lights attached to the head lights, two yelllow point lights attached to the head lights, two red point lights attached to the read lights.
](images/18-night-scene-lights.png){#fig:img-night-scene-lights}
![
A pink rim backlight applied to the car with strength of 0.3.
](images/19-rim-lights.png){#fig:img-rim-lights}
![
Visualisation of the transformed depth buffer, transformed into a 'point of focus' buffer. z=0 at the depth of the car, tends toward 1 otherwise.
](images/20-depth-map.png){#fig:img-depth-map}
![
Depth of field applied to the scene
](images/21-depth-of-field.png){#fig:img-depth-of-field}
![
The vignette effect, applied to a white frame buffer
](images/22-vingette.png){#fig:img-vingette}
![
The chromatic aberration effect. F is the point of focus. The transformed depthbuffer is centered around the vertical line crossing F.
](images/23.5-what-is.jpg){#fig:img-what-is}
![
Chromatic aberration applied to the scene, where the aberration coefficients have been multiplied by 3.
](images/23-chromatic-aberration.png){#fig:img-chromatic-aberration}
![
Noise/grain applied to the frame buffer.
](images/24-noise.png){#fig:img-noise}
![
Noise/grain, multiplied by the depthbuffer/point of focus, applied to the frame buffer.
](images/25-all-effects.png){#fig:img-all-effects}
![
The same scene, during the day. Spotlights have been turned off.
](images/26-day.png){#fig:img-day}
2019-04-07 20:29:35 +02:00
![
The early-morning scene with some strong fog applied. The code was later changed to have the fog affect the background color as well.
](images/27-fog.png){#fig:img-fog}
```{.dot include="images/effect-order.dot" caption="A high-level graph representing the fragment shader for the scene" #fig:effect -order}
```