Implement bump-mapping in deferred renderer

This commit is contained in:
Nikita Lisitsa 2020-12-13 16:11:00 +03:00
parent 2a3337a912
commit 953544718c
2 changed files with 28 additions and 1 deletions

View file

@ -33,6 +33,7 @@ namespace psemek::gfx
{ {
std::optional<color_4f> color; std::optional<color_4f> color;
texture_2d const * texture = nullptr; texture_2d const * texture = nullptr;
texture_2d const * bump_map = nullptr;
bool transparent = false; bool transparent = false;
bool lit = true; bool lit = true;
bool blooming = false; bool blooming = false;

View file

@ -45,6 +45,7 @@ const uint O_PRE_TRANSFORM = 1u << 5;
const uint O_POST_TRANSFORM = 1u << 6; const uint O_POST_TRANSFORM = 1u << 6;
const uint O_INSTANCED = 1u << 7; const uint O_INSTANCED = 1u << 7;
const uint O_BLOOMING = 1u << 8; const uint O_BLOOMING = 1u << 8;
const uint O_BUMP_MAP = 1u << 9;
uniform uint u_flag_mask; uniform uint u_flag_mask;
)"; )";
@ -68,27 +69,34 @@ out vec4 color;
out vec2 texcoord; out vec2 texcoord;
out vec3 normal; out vec3 normal;
out mat3 normal_transform;
void main() void main()
{ {
vec4 pos = in_position; vec4 pos = in_position;
vec3 n = in_normal; vec3 n = in_normal;
mat3 nt = mat3(1.0);
if ((u_flag_mask & O_PRE_TRANSFORM) != 0u) if ((u_flag_mask & O_PRE_TRANSFORM) != 0u)
{ {
pos = vec4(u_pre_transform * pos, 1.0); pos = vec4(u_pre_transform * pos, 1.0);
n = u_pre_transform * vec4(n, 0.0); n = u_pre_transform * vec4(n, 0.0);
nt = mat3(u_pre_transform);
} }
if ((u_flag_mask & O_INSTANCED) != 0u) if ((u_flag_mask & O_INSTANCED) != 0u)
{ {
pos = vec4(transpose(in_instance_transform) * pos, 1.0); pos = vec4(transpose(in_instance_transform) * pos, 1.0);
n = transpose(in_instance_transform) * vec4(n, 0.0); n = transpose(in_instance_transform) * vec4(n, 0.0);
nt = mat3(transpose(in_instance_transform)) * nt;
} }
if ((u_flag_mask & O_POST_TRANSFORM) != 0u) if ((u_flag_mask & O_POST_TRANSFORM) != 0u)
{ {
pos = vec4(u_post_transform * pos, 1.0); pos = vec4(u_post_transform * pos, 1.0);
n = u_post_transform * vec4(n, 0.0); n = u_post_transform * vec4(n, 0.0);
nt = mat3(u_post_transform) * nt;
} }
position = pos.xyz; position = pos.xyz;
@ -98,6 +106,7 @@ void main()
color = in_color; color = in_color;
texcoord = in_texcoord; texcoord = in_texcoord;
normal = n; normal = n;
normal_transform = nt;
} }
)"; )";
@ -106,6 +115,7 @@ R"(
uniform vec4 u_color; uniform vec4 u_color;
uniform sampler2D u_texture; uniform sampler2D u_texture;
uniform sampler2D u_bump_texture;
uniform vec2 u_material; uniform vec2 u_material;
uniform float u_max_intensity; uniform float u_max_intensity;
@ -113,6 +123,7 @@ in vec3 position;
in vec4 color; in vec4 color;
in vec2 texcoord; in vec2 texcoord;
in vec3 normal; in vec3 normal;
in mat3 normal_transform;
layout (location = 0) out vec3 out0; layout (location = 0) out vec3 out0;
layout (location = 1) out vec4 out1; layout (location = 1) out vec4 out1;
@ -187,9 +198,15 @@ void main()
albedo = color; albedo = color;
} }
vec3 n = normal;
if ((u_flag_mask & O_BUMP_MAP) != 0u)
{
n = normal_transform * (2.0 * texture(u_bump_texture, texcoord).xyz - vec3(1.0));
}
out0 = position; out0 = position;
out1 = vec4(albedo.rgb / u_max_intensity, (u_flag_mask & O_LIT) != 0u ? 1.f : 0.f); out1 = vec4(albedo.rgb / u_max_intensity, (u_flag_mask & O_LIT) != 0u ? 1.f : 0.f);
out2 = pack_normal(normalize(normal)); out2 = pack_normal(normalize(n));
out3 = u_material; out3 = u_material;
} }
)"; )";
@ -837,6 +854,7 @@ void main()
{ {
impl().g_buffer_pass_program.bind(); impl().g_buffer_pass_program.bind();
impl().g_buffer_pass_program["u_texture"] = 0; impl().g_buffer_pass_program["u_texture"] = 0;
impl().g_buffer_pass_program["u_bump_texture"] = 1;
for (std::size_t i = 0; i < 4; ++i) for (std::size_t i = 0; i < 4; ++i)
{ {
@ -946,6 +964,7 @@ void main()
static std::uint32_t const O_POST_TRANSFORM = 1 << 6; static std::uint32_t const O_POST_TRANSFORM = 1 << 6;
static std::uint32_t const O_INSTANCED = 1 << 7; static std::uint32_t const O_INSTANCED = 1 << 7;
static std::uint32_t const O_BLOOMING = 1 << 8; static std::uint32_t const O_BLOOMING = 1 << 8;
static std::uint32_t const O_BUMP_MAP = 1 << 9;
std::uint32_t mask(deferred_renderer::object const & o) std::uint32_t mask(deferred_renderer::object const & o)
{ {
@ -959,6 +978,7 @@ void main()
if (o.post_transform) m |= O_POST_TRANSFORM; if (o.post_transform) m |= O_POST_TRANSFORM;
if (o.mesh->is_instanced()) m |= O_INSTANCED; if (o.mesh->is_instanced()) m |= O_INSTANCED;
if (o.mat->blooming) m |= O_BLOOMING; if (o.mat->blooming) m |= O_BLOOMING;
if (o.mat->bump_map) m |= O_BUMP_MAP;
return m; return m;
} }
@ -1101,6 +1121,12 @@ void main()
mat->texture->bind(); mat->texture->bind();
} }
if (mask & O_BUMP_MAP)
{
gl::ActiveTexture(gl::TEXTURE1);
mat->bump_map->bind();
}
program["u_material"] = geom::vector<float, 2>{mat->specular.intensity, mat->specular.shininess}; program["u_material"] = geom::vector<float, 2>{mat->specular.intensity, mat->specular.shininess};
for (std::size_t i = clip_by_camera ? p.second.first_visible : 0; i < p.second.objects.size(); ++i) for (std::size_t i = clip_by_camera ? p.second.first_visible : 0; i < p.second.objects.size(); ++i)