Deferred renderer: implement unlit transparent objects
This commit is contained in:
parent
167f979285
commit
e799771a40
1 changed files with 145 additions and 9 deletions
|
|
@ -497,6 +497,88 @@ void main()
|
|||
|
||||
out_color = vec4(color, 1.0);
|
||||
}
|
||||
)";
|
||||
|
||||
static char const transparent_pass_vs[] =
|
||||
R"(
|
||||
|
||||
uniform mat4 u_camera_transform;
|
||||
uniform mat4x3 u_pre_transform;
|
||||
uniform mat4x3 u_post_transform;
|
||||
|
||||
layout (location = 0) in vec4 in_position;
|
||||
layout (location = 1) in vec4 in_color;
|
||||
layout (location = 2) in vec2 in_texcoord;
|
||||
layout (location = 3) in vec3 in_normal;
|
||||
|
||||
layout (location = 4) in mat3x4 in_instance_transform;
|
||||
|
||||
out vec4 color;
|
||||
out vec2 texcoord;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 pos = in_position;
|
||||
vec3 n = in_normal;
|
||||
|
||||
if ((u_flag_mask & O_PRE_TRANSFORM) != 0u)
|
||||
{
|
||||
pos = vec4(u_pre_transform * pos, 1.0);
|
||||
n = u_pre_transform * vec4(n, 0.0);
|
||||
}
|
||||
|
||||
if ((u_flag_mask & O_INSTANCED) != 0u)
|
||||
{
|
||||
pos = vec4(transpose(in_instance_transform) * pos, 1.0);
|
||||
n = transpose(in_instance_transform) * vec4(n, 0.0);
|
||||
}
|
||||
|
||||
if ((u_flag_mask & O_POST_TRANSFORM) != 0u)
|
||||
{
|
||||
pos = vec4(u_post_transform * pos, 1.0);
|
||||
n = u_post_transform * vec4(n, 0.0);
|
||||
}
|
||||
|
||||
gl_Position = u_camera_transform * pos;
|
||||
|
||||
color = in_color;
|
||||
texcoord = in_texcoord;
|
||||
}
|
||||
)";
|
||||
|
||||
static char const transparent_pass_fs[] =
|
||||
R"(
|
||||
|
||||
uniform vec4 u_color;
|
||||
uniform sampler2D u_texture;
|
||||
uniform float u_max_intensity;
|
||||
|
||||
in vec4 color;
|
||||
in vec2 texcoord;
|
||||
|
||||
layout (location = 0) out vec4 out_color;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 albedo;
|
||||
if ((u_flag_mask & O_TEXTURE_COLOR) != 0u)
|
||||
{
|
||||
vec4 base_color = texture(u_texture, texcoord);
|
||||
if ((u_flag_mask & O_UNIFORM_COLOR) != 0u)
|
||||
albedo = u_color * base_color;
|
||||
else
|
||||
albedo = base_color;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((u_flag_mask & O_UNIFORM_COLOR) != 0u)
|
||||
albedo = u_color;
|
||||
else
|
||||
albedo = color;
|
||||
}
|
||||
|
||||
out_color = vec4(albedo.rgb / u_max_intensity, albedo.a);
|
||||
}
|
||||
)";
|
||||
|
||||
static std::size_t bbox_to_screen_fan(geom::matrix<float, 4, 4> const & camera_transform, geom::box<float, 3> const & b, geom::point<float, 2> * result)
|
||||
|
|
@ -558,6 +640,7 @@ void main()
|
|||
gfx::program point_light_pass_program{screen_vs, std::string(light_common) + point_light_pass_fs};
|
||||
gfx::program shadow_builder_program{std::string(g_buffer_pass_common) + shadow_builder_vs, shadow_builder_fs};
|
||||
gfx::program cubemap_shadow_builder_program{std::string(g_buffer_pass_common) + shadow_builder_vs, shadow_builder_gs, shadow_builder_fs};
|
||||
gfx::program transparent_pass_program{std::string(g_buffer_pass_common) + transparent_pass_vs, std::string(g_buffer_pass_common) + transparent_pass_fs};
|
||||
|
||||
// G-buffer attachments:
|
||||
// 0 - position (rbg)
|
||||
|
|
@ -569,6 +652,9 @@ void main()
|
|||
gfx::texture_2d g_buffer_texture[4];
|
||||
gfx::texture_2d g_buffer_depth;
|
||||
|
||||
// Only albedo & depth attached
|
||||
gfx::framebuffer transparent_framebuffer;
|
||||
|
||||
std::optional<geom::vector<std::size_t, 2>> g_buffer_size;
|
||||
|
||||
gfx::framebuffer directional_shadow_framebuffer;
|
||||
|
|
@ -688,7 +774,8 @@ void main()
|
|||
auto const & o = objects[i];
|
||||
assert(o.mesh);
|
||||
|
||||
if (o.mat.transparent) throw std::runtime_error("Transparency is not supported yet");
|
||||
if (o.mat.lit && o.mat.transparent)
|
||||
throw std::runtime_error("Materials that are both tit & transparent are not supported");
|
||||
|
||||
objects_by_mask[mask(objects[i])].push_back(i);
|
||||
|
||||
|
|
@ -726,6 +813,10 @@ void main()
|
|||
|
||||
impl().g_framebuffer.assert_complete();
|
||||
|
||||
impl().transparent_framebuffer.color(impl().g_buffer_texture[1]);
|
||||
impl().transparent_framebuffer.depth(impl().g_buffer_depth);
|
||||
impl().transparent_framebuffer.assert_complete();
|
||||
|
||||
impl().g_buffer_size = buffer_size;
|
||||
impl().position_mode_changed = false;
|
||||
}
|
||||
|
|
@ -767,10 +858,13 @@ void main()
|
|||
|
||||
for (auto const & p : objects_by_mask)
|
||||
{
|
||||
if (p.second.empty()) continue;
|
||||
|
||||
std::uint32_t mask = p.first;
|
||||
|
||||
if (mask & O_TRANSPARENT)
|
||||
continue;
|
||||
|
||||
if (p.second.empty()) continue;
|
||||
|
||||
impl().g_buffer_pass_program["u_flag_mask"] = mask;
|
||||
|
||||
for (std::size_t i : p.second)
|
||||
|
|
@ -798,6 +892,54 @@ void main()
|
|||
}
|
||||
}
|
||||
|
||||
// Render unlit transparent objects
|
||||
|
||||
impl().transparent_framebuffer.bind();
|
||||
impl().transparent_pass_program.bind();
|
||||
impl().transparent_pass_program["u_camera_transform"] = camera_transform;
|
||||
impl().transparent_pass_program["u_max_intensity"] = opts.max_intensity;
|
||||
|
||||
gl::Enable(gl::BLEND);
|
||||
gl::BlendFuncSeparate(gl::SRC_ALPHA, gl::ONE_MINUS_SRC_ALPHA, gl::ONE, gl::ZERO);
|
||||
|
||||
gl::DepthMask(gl::FALSE);
|
||||
|
||||
for (auto const & p : objects_by_mask)
|
||||
{
|
||||
std::uint32_t mask = p.first;
|
||||
|
||||
if (!(mask & O_TRANSPARENT))
|
||||
continue;
|
||||
|
||||
if (p.second.empty()) continue;
|
||||
|
||||
impl().transparent_pass_program["u_flag_mask"] = mask;
|
||||
|
||||
for (std::size_t i : p.second)
|
||||
{
|
||||
auto const & o = objects[i];
|
||||
|
||||
if (mask & O_UNIFORM_COLOR)
|
||||
impl().transparent_pass_program["u_color"] = *o.mat.color;
|
||||
|
||||
if (mask & O_TEXTURE_COLOR)
|
||||
{
|
||||
gl::ActiveTexture(gl::TEXTURE0);
|
||||
o.mat.texture->bind();
|
||||
}
|
||||
|
||||
if (mask & O_PRE_TRANSFORM)
|
||||
impl().transparent_pass_program["u_pre_transform"] = *o.pre_transform;
|
||||
|
||||
if (mask & O_POST_TRANSFORM)
|
||||
impl().transparent_pass_program["u_post_transform"] = *o.post_transform;
|
||||
|
||||
o.mesh->draw();
|
||||
}
|
||||
}
|
||||
|
||||
gl::DepthMask(gl::TRUE);
|
||||
|
||||
// Setup destination framebuffer
|
||||
|
||||
target.bind();
|
||||
|
|
@ -1054,12 +1196,6 @@ void main()
|
|||
|
||||
impl().cubemap_shadow_builder_program.bind();
|
||||
impl().cubemap_shadow_builder_program["u_light_transform"] = geom::matrix<float, 4, 4>::identity();
|
||||
// impl().cubemap_shadow_builder_program["u_layer_transform[0]"] = geom::matrix<float, 4, 4>::identity();
|
||||
// impl().cubemap_shadow_builder_program["u_layer_transform[1]"] = geom::matrix<float, 4, 4>::identity();
|
||||
// impl().cubemap_shadow_builder_program["u_layer_transform[2]"] = geom::matrix<float, 4, 4>::identity();
|
||||
// impl().cubemap_shadow_builder_program["u_layer_transform[3]"] = geom::matrix<float, 4, 4>::identity();
|
||||
// impl().cubemap_shadow_builder_program["u_layer_transform[4]"] = geom::matrix<float, 4, 4>::identity();
|
||||
// impl().cubemap_shadow_builder_program["u_layer_transform[5]"] = geom::matrix<float, 4, 4>::identity();
|
||||
|
||||
impl().cubemap_shadow_builder_program["u_layer_transform[0]"] = transform[0] * translate_by_light;
|
||||
impl().cubemap_shadow_builder_program["u_layer_transform[1]"] = transform[1] * translate_by_light;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue