Compress normals to 32-bit integers in deferred renderer
This commit is contained in:
parent
e7427e1d58
commit
1b8ef017ad
1 changed files with 109 additions and 36 deletions
|
|
@ -95,9 +95,58 @@ in vec3 normal;
|
|||
|
||||
layout (location = 0) out vec3 out0;
|
||||
layout (location = 1) out vec4 out1;
|
||||
layout (location = 2) out vec3 out2;
|
||||
layout (location = 2) out uint out2;
|
||||
layout (location = 3) out vec3 out3;
|
||||
|
||||
uint pack_normal(vec3 n)
|
||||
{
|
||||
uint face = 0u;
|
||||
|
||||
float a0, a1;
|
||||
|
||||
vec3 an = abs(n);
|
||||
|
||||
if (an.x > an.y)
|
||||
{
|
||||
if (an.x > an.z)
|
||||
{
|
||||
bool p = (n.x > 0.0);
|
||||
face = p ? 1u : 6u;
|
||||
a0 = (p ? n.y : n.z) / an.x;
|
||||
a1 = (p ? n.z : n.y) / an.x;
|
||||
}
|
||||
else
|
||||
{
|
||||
bool p = (n.z > 0.0);
|
||||
face = p ? 4u : 3u;
|
||||
a0 = (p ? n.x : n.y) / an.z;
|
||||
a1 = (p ? n.y : n.x) / an.z;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (an.y > an.z)
|
||||
{
|
||||
bool p = (n.y > 0.0);
|
||||
face = p ? 2u : 5u;
|
||||
a0 = (p ? n.z : n.x) / an.y;
|
||||
a1 = (p ? n.x : n.z) / an.y;
|
||||
}
|
||||
else
|
||||
{
|
||||
bool p = (n.z > 0.0);
|
||||
face = p ? 4u : 3u;
|
||||
a0 = (p ? n.x : n.y) / an.z;
|
||||
a1 = (p ? n.y : n.x) / an.z;
|
||||
}
|
||||
}
|
||||
|
||||
uint v0 = uint((a0 * 0.5 + 0.5) * float(1 << 15));
|
||||
uint v1 = uint((a1 * 0.5 + 0.5) * float(1 << 14));
|
||||
|
||||
return (face << 29u) | (v1 << 15u) | v0;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 albedo;
|
||||
|
|
@ -119,7 +168,7 @@ void main()
|
|||
|
||||
out0 = position;
|
||||
out1 = vec4(albedo.rgb / u_max_intensity, (u_flag_mask & O_LIT) != 0u ? 1.f : 0.f);
|
||||
out2 = normalize(normal) * 0.5 + vec3(0.5);
|
||||
out2 = pack_normal(normalize(normal));
|
||||
out3 = u_material;
|
||||
}
|
||||
)";
|
||||
|
|
@ -162,22 +211,66 @@ void main()
|
|||
}
|
||||
)";
|
||||
|
||||
static char const ambient_pass_fs[] =
|
||||
|
||||
static char const light_common[] =
|
||||
R"(#version 330
|
||||
|
||||
uniform sampler2D u_g0;
|
||||
uniform sampler2D u_g1;
|
||||
uniform sampler2D u_g2;
|
||||
uniform usampler2D u_g2;
|
||||
uniform sampler2D u_g3;
|
||||
|
||||
uniform vec3 u_ambient;
|
||||
|
||||
uniform float u_max_intensity;
|
||||
|
||||
in vec2 texcoord;
|
||||
|
||||
out vec4 out_color;
|
||||
|
||||
vec3 unpack_normal(uint v)
|
||||
{
|
||||
uint v0 = v & ((1u << 15) - 1u);
|
||||
uint v1 = (v >> 15) & ((1u << 14) - 1u);
|
||||
uint face = (v >> 29) & 7u;
|
||||
|
||||
float a0 = 2.0 * float(v0) / float(1 << 15) - 1.0;
|
||||
float a1 = 2.0 * float(v1) / float(1 << 14) - 1.0;
|
||||
|
||||
if (face == 1u)
|
||||
{
|
||||
return normalize(vec3(1.0, a0, a1));
|
||||
}
|
||||
else if (face == 2u)
|
||||
{
|
||||
return normalize(vec3(a1, 1.0, a0));
|
||||
}
|
||||
else if (face == 3u)
|
||||
{
|
||||
return normalize(vec3(a1, a0, -1.0));
|
||||
}
|
||||
else if (face == 4u)
|
||||
{
|
||||
return normalize(vec3(a0, a1, 1.0));
|
||||
}
|
||||
else if (face == 5u)
|
||||
{
|
||||
return normalize(vec3(a0, -1.0, a1));
|
||||
}
|
||||
else if (face == 6u)
|
||||
{
|
||||
return normalize(vec3(-1.0, a1, a0));
|
||||
}
|
||||
|
||||
return vec3(0.0, 0.0, 0.0);
|
||||
}
|
||||
|
||||
)";
|
||||
|
||||
static char const ambient_pass_fs[] =
|
||||
R"(
|
||||
|
||||
uniform vec3 u_ambient;
|
||||
|
||||
uniform float u_max_intensity;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 albedo = texture(u_g1, texcoord);
|
||||
|
|
@ -194,12 +287,7 @@ void main()
|
|||
)";
|
||||
|
||||
static char const directional_light_pass_fs[] =
|
||||
R"(#version 330
|
||||
|
||||
uniform sampler2D u_g0;
|
||||
uniform sampler2D u_g1;
|
||||
uniform sampler2D u_g2;
|
||||
uniform sampler2D u_g3;
|
||||
R"(
|
||||
|
||||
uniform vec3 u_light_direction;
|
||||
uniform vec3 u_light_color;
|
||||
|
|
@ -208,15 +296,11 @@ uniform vec3 u_camera_position;
|
|||
|
||||
uniform float u_max_intensity;
|
||||
|
||||
in vec2 texcoord;
|
||||
|
||||
out vec4 out_color;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec3 position = texture(u_g0, texcoord).xyz;
|
||||
vec4 albedo = texture(u_g1, texcoord);
|
||||
vec3 normal = texture(u_g2, texcoord).xyz * 2.0 - vec3(1.0);
|
||||
vec3 normal = unpack_normal(texture(u_g2, texcoord).r);
|
||||
vec3 material = texture(u_g3, texcoord).xyz;
|
||||
|
||||
vec3 view = normalize(u_camera_position - position);
|
||||
|
|
@ -234,12 +318,7 @@ void main()
|
|||
)";
|
||||
|
||||
static char const point_light_pass_fs[] =
|
||||
R"(#version 330
|
||||
|
||||
uniform sampler2D u_g0;
|
||||
uniform sampler2D u_g1;
|
||||
uniform sampler2D u_g2;
|
||||
uniform sampler2D u_g3;
|
||||
R"(
|
||||
|
||||
uniform vec3 u_light_position;
|
||||
uniform vec3 u_light_color;
|
||||
|
|
@ -249,15 +328,11 @@ uniform vec3 u_camera_position;
|
|||
|
||||
uniform float u_max_intensity;
|
||||
|
||||
in vec2 texcoord;
|
||||
|
||||
out vec4 out_color;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec3 position = texture(u_g0, texcoord).xyz;
|
||||
vec4 albedo = texture(u_g1, texcoord);
|
||||
vec3 normal = texture(u_g2, texcoord).xyz * 2.0 - vec3(1.0);
|
||||
vec3 normal = unpack_normal(texture(u_g2, texcoord).r);
|
||||
vec3 material = texture(u_g3, texcoord).xyz;
|
||||
|
||||
vec3 view = normalize(u_camera_position - position);
|
||||
|
|
@ -331,14 +406,14 @@ void main()
|
|||
struct deferred_renderer::impl
|
||||
{
|
||||
gfx::program g_buffer_pass_program{std::string(g_buffer_pass_common) + g_buffer_pass_vs, std::string(g_buffer_pass_common) + g_buffer_pass_fs};
|
||||
gfx::program ambient_pass_program{fullscreen_vs, ambient_pass_fs};
|
||||
gfx::program directional_light_pass_program{screen_vs, directional_light_pass_fs};
|
||||
gfx::program point_light_pass_program{screen_vs, point_light_pass_fs};
|
||||
gfx::program ambient_pass_program{fullscreen_vs, std::string(light_common) + ambient_pass_fs};
|
||||
gfx::program directional_light_pass_program{screen_vs, std::string(light_common) + directional_light_pass_fs};
|
||||
gfx::program point_light_pass_program{screen_vs, std::string(light_common) + point_light_pass_fs};
|
||||
|
||||
// G-buffer attachments:
|
||||
// 0 - position (rbg)
|
||||
// 1 - albedo (rgb), lit (a)
|
||||
// 2 - normal (rgb)
|
||||
// 2 - normal (packed)
|
||||
// 3 - material.diffuse (r), material.specular (g), material.shininess (b)
|
||||
|
||||
gfx::framebuffer g_framebuffer;
|
||||
|
|
@ -440,11 +515,9 @@ void main()
|
|||
auto buffer_size = geom::cast<std::size_t>(target.viewport.dimensions());
|
||||
if (!impl().g_buffer_size || *impl().g_buffer_size != buffer_size)
|
||||
{
|
||||
// TODO: compact normals storage
|
||||
|
||||
impl().g_buffer_texture[0].load<geom::vector<gfx::float16, 3>>(buffer_size);
|
||||
impl().g_buffer_texture[1].load<geom::vector<std::uint16_t, 4>>(buffer_size);
|
||||
impl().g_buffer_texture[2].load<geom::vector<gfx::float16, 3>>(buffer_size);
|
||||
impl().g_buffer_texture[2].load<gfx::integer<std::uint32_t>>(buffer_size);
|
||||
impl().g_buffer_texture[3].load<geom::vector<gfx::float16, 3>>(buffer_size);
|
||||
impl().g_buffer_depth.load<gfx::depth24_pixel>(buffer_size);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue