Deferred renderer: support choosing between 16-bit and 32-bit floats for position representation

This commit is contained in:
Nikita Lisitsa 2020-12-09 18:18:32 +03:00
parent 28b676b002
commit 167f979285
2 changed files with 34 additions and 15 deletions

View file

@ -19,6 +19,16 @@ namespace psemek::gfx
deferred_renderer();
~deferred_renderer();
enum class position_mode
{
// Default position mode is float32
// TODO: support fixed16 & fixed32
float16,
float32,
};
void set_position_mode(position_mode mode);
struct material
{
std::optional<color_4f> color;

View file

@ -549,6 +549,9 @@ void main()
struct deferred_renderer::impl
{
deferred_renderer::position_mode position_mode = deferred_renderer::position_mode::float32;
bool position_mode_changed = true;
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, std::string(light_common) + ambient_pass_fs};
gfx::program directional_light_pass_program{screen_vs, std::string(light_common) + directional_light_pass_fs};
@ -634,6 +637,12 @@ void main()
deferred_renderer::~deferred_renderer() = default;
void deferred_renderer::set_position_mode(position_mode mode)
{
impl().position_mode = mode;
impl().position_mode_changed = true;
}
static std::uint32_t const O_UNIFORM_COLOR = 1 << 0;
static std::uint32_t const O_TEXTURE_COLOR = 1 << 1;
static std::uint32_t const O_TRANSPARENT = 1 << 2;
@ -690,13 +699,21 @@ void main()
// Resize g-buffer if needed
auto buffer_size = geom::cast<std::size_t>(target.viewport.dimensions());
if (!impl().g_buffer_size || *impl().g_buffer_size != buffer_size)
bool const buffer_size_changed = !impl().g_buffer_size || *impl().g_buffer_size != buffer_size;
if (buffer_size_changed || impl().position_mode_changed)
{
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<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);
if (impl().position_mode == position_mode::float16)
impl().g_buffer_texture[0].load<geom::vector<gfx::float16, 3>>(buffer_size);
else if (impl().position_mode == position_mode::float32)
impl().g_buffer_texture[0].load<geom::vector<float, 3>>(buffer_size);
if (buffer_size_changed)
{
impl().g_buffer_texture[1].load<geom::vector<std::uint16_t, 4>>(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);
}
if (!impl().g_buffer_size)
{
@ -710,6 +727,7 @@ void main()
impl().g_framebuffer.assert_complete();
impl().g_buffer_size = buffer_size;
impl().position_mode_changed = false;
}
// Setup g-buffer
@ -1073,15 +1091,6 @@ void main()
o.mesh->draw();
}
}
/*
gfx::pixmap_float pixmap({impl().point_shadow_texture.width(), impl().point_shadow_texture.height()});
impl().point_shadow_texture.pixels(1, gl::DEPTH_COMPONENT, gl::FLOAT, pixmap.data());
auto pixels = util::map([](float x){ return std::uint8_t(x * 255); }, pixmap);
std::ofstream out{"/home/lisyarus/depth.pgm"};
gfx::write_pgm(pixels, out);
//*/
}
target.bind();