Rewrite bump mapping, expose uniforms to keyboard

This commit is contained in:
karl 2021-04-11 20:23:44 +02:00
parent a58aea923a
commit 08204fe63a
4 changed files with 67 additions and 45 deletions

View File

@ -1,7 +1,10 @@
#include "BumpMapDemo.h"
#include "Input.h"
#include <glm/common.hpp>
BumpMapDemo::BumpMapDemo()
: height_scale(0.2), render_shader(Shader("Shader/bump.vs", "Shader/bump.fs")),
: number_of_steps(10.0), number_of_refinement_steps(10.0), bump_depth(0.1),
render_shader(Shader("Shader/bump.vs", "Shader/bump.fs")),
camera(Camera(90, 1920, 1080, 0.1, 1000.0)),
albedo("Resources/Textures/PavingStones/PavingStones070_2K_Color.jpg", Texture::Settings()),
bump("Resources/Textures/PavingStones/PavingStones070_2K_Displacement.jpg",
@ -27,7 +30,29 @@ void BumpMapDemo::render(float delta) {
render_shader.setVec3("lightPos", glm::vec3(0.0, 1.0, 5.0));
// Settings for bump mapping
render_shader.setFloat("height_scale", height_scale);
if (Input::is_key_down(GLFW_KEY_Q)) {
number_of_steps += delta * 5.0;
}
if (Input::is_key_down(GLFW_KEY_W)) {
number_of_steps -= delta * 5.0;
}
if (Input::is_key_down(GLFW_KEY_A)) {
number_of_refinement_steps += delta * 5.0;
}
if (Input::is_key_down(GLFW_KEY_S)) {
number_of_refinement_steps -= delta * 5.0;
}
if (Input::is_key_down(GLFW_KEY_Z)) {
bump_depth += delta * 0.1;
}
if (Input::is_key_down(GLFW_KEY_X)) {
bump_depth -= delta * 0.1;
}
render_shader.setFloat("number_of_steps", glm::max(0.0f, number_of_steps));
render_shader.setFloat("number_of_refinement_steps",
glm::max(0.0f, number_of_refinement_steps));
render_shader.setFloat("bump_depth", glm::max(0.0f, bump_depth));
// Textures
albedo.bind_to(0);

View File

@ -14,9 +14,9 @@ class BumpMapDemo {
void render(float delta);
private:
unsigned int step_count;
unsigned int refinement_step_count;
float height_scale;
float number_of_steps;
float number_of_refinement_steps;
float bump_depth;
Shader render_shader;

View File

@ -14,52 +14,50 @@ layout (binding = 0) uniform sampler2D albedoMap;
layout (binding = 1) uniform sampler2D normalMap;
layout (binding = 2) uniform sampler2D depthMap;
uniform float height_scale;
uniform float bump_depth;
uniform float number_of_steps;
uniform float number_of_refinement_steps;
vec2 get_parallax_offset_uv(vec2 uv, vec3 view_direction)
{
// number of depth layers
const float minLayers = 8;
const float maxLayers = 32;
float numLayers = mix(maxLayers, minLayers, abs(dot(vec3(0.0, 0.0, 1.0), view_direction)));
// calculate the size of each layer
float layerDepth = 1.0 / numLayers;
// depth of current layer
float currentLayerDepth = 0.0;
// the amount to shift the texture coordinates per layer (from vector P)
vec2 P = view_direction.xy / view_direction.z * height_scale;
vec2 deltaTexCoords = P / numLayers;
vec2 get_parallax_offset_uv(vec2 uv, vec3 view_direction) {
float layer_depth = 1.0 / number_of_steps;
float refinement_layer_depth = layer_depth / number_of_refinement_steps;
float current_layer_depth = 0.0;
// the amount to shift the texture coordinates per layer (from vector total_uv_shift)
vec2 total_uv_shift = view_direction.xy / view_direction.z * bump_depth;
vec2 uv_shift_per_layer = total_uv_shift / number_of_steps;
vec2 uv_refine_shift_per_layer = total_uv_shift / (number_of_steps * number_of_refinement_steps);
// get initial values
vec2 currentTexCoords = uv;
float currentDepthMapValue = 1.0 - texture(depthMap, currentTexCoords).r;
while(currentLayerDepth < currentDepthMapValue)
{
// shift texture coordinates along direction of P
currentTexCoords -= deltaTexCoords;
// get depthmap value at current texture coordinates
currentDepthMapValue = 1.0 - texture(depthMap, currentTexCoords).r;
// get depth of next layer
currentLayerDepth += layerDepth;
// Initial values
vec2 current_uv = uv;
float current_bump_value = 1.0 - texture(depthMap, current_uv).r;
// Loop until our depth is greater than the value in the bump map, meaning our ray collided
while(current_layer_depth < current_bump_value) {
current_uv -= uv_shift_per_layer;
current_bump_value = 1.0 - texture(depthMap, current_uv).r;
current_layer_depth += layer_depth;
}
// get texture coordinates before collision (reverse operations)
vec2 prevTexCoords = currentTexCoords + deltaTexCoords;
// Reverse the last operations so we're at the point before the collision
current_uv += uv_shift_per_layer;
current_bump_value = 1.0 - texture(depthMap, current_uv).r;
// get depth after and before collision for linear interpolation
float afterDepth = currentDepthMapValue - currentLayerDepth;
float beforeDepth = 1.0 - texture(depthMap, prevTexCoords).r - currentLayerDepth + layerDepth;
// interpolation of texture coordinates
float weight = afterDepth / (afterDepth - beforeDepth);
vec2 finalTexCoords = prevTexCoords * weight + currentTexCoords * (1.0 - weight);
// Loop again for the refinement steps
while(current_layer_depth < current_bump_value) {
current_uv -= uv_refine_shift_per_layer;
current_bump_value = 1.0 - texture(depthMap, current_uv).r;
current_layer_depth += refinement_layer_depth;
}
return finalTexCoords;
// Referse the UV operation again and return the result
current_uv += uv_refine_shift_per_layer;
return current_uv;
}
void main()
{
void main() {
// Offset texture coordinates with Parallax Mapping
vec3 view_direction = normalize(fs_in.TangentViewPos - fs_in.TangentFragPos);
vec2 uv = fs_in.TexCoords;

View File

@ -21,8 +21,7 @@ uniform mat4 model;
uniform vec3 lightPos;
uniform vec3 viewPos;
void main()
{
void main() {
gl_Position = projection * view * model * vec4(aPos, 1.0);
vs_out.FragPos = vec3(model * vec4(aPos, 1.0));
vs_out.TexCoords = aTexCoords;