Browse Source

Fix outline pass depth issue

master
C. J. Howard 3 years ago
parent
commit
2a9fffbdf1
3 changed files with 82 additions and 41 deletions
  1. +2
    -1
      src/renderer/passes/material-pass.cpp
  2. +73
    -36
      src/renderer/passes/outline-pass.cpp
  3. +7
    -4
      src/renderer/passes/outline-pass.hpp

+ 2
- 1
src/renderer/passes/material-pass.cpp View File

@ -327,6 +327,7 @@ void material_pass::render(render_context* context) const
}
}
/*
if ((material_flags & MATERIAL_FLAG_OUTLINE) != (active_material_flags & MATERIAL_FLAG_OUTLINE))
{
if (material_flags & MATERIAL_FLAG_OUTLINE)
@ -342,7 +343,7 @@ void material_pass::render(render_context* context) const
glStencilMask(0x00);
}
}
*/
active_material_flags = material_flags;
}

+ 73
- 36
src/renderer/passes/outline-pass.cpp View File

@ -38,13 +38,18 @@
outline_pass::outline_pass(::rasterizer* rasterizer, const ::framebuffer* framebuffer, resource_manager* resource_manager):
render_pass(rasterizer, framebuffer),
outline_shader(nullptr)
fill_shader(nullptr),
stroke_shader(nullptr)
{
// Load outline shader
outline_shader = resource_manager->load<shader_program>("outline-unskinned.glsl");
model_view_projection_input = outline_shader->get_input("model_view_projection");
outline_width_input = outline_shader->get_input("outline_width");
outline_color_input = outline_shader->get_input("outline_color");
// Load fill shader
fill_shader = resource_manager->load<shader_program>("outline-fill-unskinned.glsl");
fill_model_view_projection_input = fill_shader->get_input("model_view_projection");
// Load stroke shader
stroke_shader = resource_manager->load<shader_program>("outline-stroke-unskinned.glsl");
stroke_model_view_projection_input = stroke_shader->get_input("model_view_projection");
stroke_width_input = stroke_shader->get_input("width");
stroke_color_input = stroke_shader->get_input("color");
}
outline_pass::~outline_pass()
@ -54,49 +59,81 @@ void outline_pass::render(render_context* context) const
{
rasterizer->use_framebuffer(*framebuffer);
if (outline_color.w < 1.0f)
{
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
else
{
glDisable(GL_BLEND);
}
glDisable(GL_DEPTH_TEST);
glDisable(GL_CULL_FACE);
glCullFace(GL_BACK);
glEnable(GL_STENCIL_TEST);
glStencilFunc(GL_NOTEQUAL, 1, 0xFF);
glStencilMask(0x00);
// Determine viewport based on framebuffer resolution
auto viewport = framebuffer->get_dimensions();
rasterizer->set_viewport(0, 0, std::get<0>(viewport), std::get<1>(viewport));
// Get camera matrices
float4x4 view = context->camera->get_view_tween().interpolate(context->alpha);
float4x4 view_projection = context->camera->get_view_projection_tween().interpolate(context->alpha);
float4x4 model_view_projection;
// Perform iterative blur subpass
rasterizer->use_program(*outline_shader);
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
glDisable(GL_DEPTH_TEST);
outline_width_input->upload(outline_width);
outline_color_input->upload(outline_color);
// Render fill
{
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
glEnable(GL_STENCIL_TEST);
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
glStencilFunc(GL_ALWAYS, 1, 0xFF);
glStencilMask(0xFF);
glDisable(GL_BLEND);
// Setup fill shader
rasterizer->use_program(*fill_shader);
// Render fills
for (const render_operation& operation: context->operations)
{
const ::material* material = operation.material;
if (!material || !(material->get_flags() & MATERIAL_FLAG_OUTLINE))
continue;
model_view_projection = view_projection * operation.transform;
fill_model_view_projection_input->upload(model_view_projection);
rasterizer->draw_arrays(*operation.vertex_array, operation.drawing_mode, operation.start_index, operation.index_count);
}
}
// Render outlines
for (const render_operation& operation: context->operations)
// Render stroke
{
const ::material* material = operation.material;
if (!material || !(material->get_flags() & MATERIAL_FLAG_OUTLINE))
continue;
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
if (outline_color.w < 1.0f)
{
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
else
{
glDisable(GL_BLEND);
}
glEnable(GL_STENCIL_TEST);
glStencilFunc(GL_NOTEQUAL, 1, 0xFF);
glStencilMask(0x00);
model_view_projection = view_projection * operation.transform;
model_view_projection_input->upload(model_view_projection);
// Setup stroke shader
rasterizer->use_program(*stroke_shader);
stroke_width_input->upload(outline_width);
stroke_color_input->upload(outline_color);
rasterizer->draw_arrays(*operation.vertex_array, operation.drawing_mode, operation.start_index, operation.index_count);
// Render strokes
for (const render_operation& operation: context->operations)
{
const ::material* material = operation.material;
if (!material || !(material->get_flags() & MATERIAL_FLAG_OUTLINE))
continue;
model_view_projection = view_projection * operation.transform;
stroke_model_view_projection_input->upload(model_view_projection);
rasterizer->draw_arrays(*operation.vertex_array, operation.drawing_mode, operation.start_index, operation.index_count);
}
}
glDisable(GL_STENCIL_TEST);

+ 7
- 4
src/renderer/passes/outline-pass.hpp View File

@ -41,10 +41,13 @@ public:
void set_outline_color(const float4& color);
private:
shader_program* outline_shader;
const shader_input* model_view_projection_input;
const shader_input* outline_width_input;
const shader_input* outline_color_input;
shader_program* fill_shader;
const shader_input* fill_model_view_projection_input;
shader_program* stroke_shader;
const shader_input* stroke_model_view_projection_input;
const shader_input* stroke_width_input;
const shader_input* stroke_color_input;
float outline_width;
float4 outline_color;

Loading…
Cancel
Save