filter-sdf-effects: Fix and improve effect rendering

Fixes the bug that rendering an outline would remove all other effects not directly under the outline, while also improving the rendering speed drastically by only initializing and clearing the rendertarget once instead of for each effect.
This commit is contained in:
Michael Fabian 'Xaymar' Dirks 2019-05-28 02:50:03 +02:00
parent 0e39490284
commit ccc4c6ea22
2 changed files with 31 additions and 112 deletions

View file

@ -256,16 +256,9 @@ uniform float pOutlineSharpnessInverse <
float4 PSOutline(VertDataOut v_in) : TARGET float4 PSOutline(VertDataOut v_in) : TARGET
{ {
// Sample Input and SDF float2 iodist = pSDFTexture.Sample(sdfSampler, v_in.uv).rg * MAX_DISTANCE;
float4 tex_input = pImageTexture.Sample(imageSampler, v_in.uv); float dist = iodist.r - iodist.g;
float4 tex_sdf = pSDFTexture.Sample(sdfSampler, v_in.uv);
// Expand SDF range to full.
float2 sdf = tex_sdf.rg * float2(MAX_DISTANCE, MAX_DISTANCE);
// Calculate distance.
float dist = sdf.r - sdf.g;
// Calculate where we are in the outline. // Calculate where we are in the outline.
// We can use any of the following gradient functions: https://www.desmos.com/calculator/bmbrncaiem // We can use any of the following gradient functions: https://www.desmos.com/calculator/bmbrncaiem
/// Base Curve /// Base Curve
@ -279,7 +272,7 @@ float4 PSOutline(VertDataOut v_in) : TARGET
// Blend by Color.a so that our outline doesn't delete information. // Blend by Color.a so that our outline doesn't delete information.
float l = 1.0 - ((1.0 - y1) * pOutlineColor.a); float l = 1.0 - ((1.0 - y1) * pOutlineColor.a);
return lerp(pOutlineColor, tex_input, l); return float4(pOutlineColor.r, pOutlineColor.g, pOutlineColor.b, pOutlineColor.a * (1.0 - y1));
} }
technique Outline technique Outline

View file

@ -775,32 +775,24 @@ void filter::sdf_effects::sdf_effects_instance::video_render(gs_effect_t* effect
// Inner Glow // Inner Glow
// Outline // Outline
{ // Normal Source // Optimized Render path.
try {
auto op = this->m_output_rt->render(baseW, baseH);
gs_ortho(0, 1, 0, 1, 0, 1);
gs_enable_blending(false); gs_enable_blending(false);
gs_blend_function(GS_BLEND_ONE, GS_BLEND_ZERO); gs_blend_function(GS_BLEND_ONE, GS_BLEND_ZERO);
auto param = gs_effect_get_param_by_name(default_effect, "image"); auto param = gs_effect_get_param_by_name(default_effect, "image");
if (param) { if (param) {
gs_effect_set_texture(param, this->m_output_texture->get_object()); gs_effect_set_texture(param, this->m_output_texture->get_object());
} }
while (gs_effect_loop(default_effect, "Draw")) {
{ gs_draw_sprite(0, 0, 1, 1);
auto op = this->m_output_rt->render(baseW, baseH);
gs_ortho(0, 1, 0, 1, 0, 1);
while (gs_effect_loop(default_effect, "Draw")) {
gs_draw_sprite(0, 0, 1, 1);
}
} }
// Flip Buffers gs_enable_blending(true);
m_output_rt->get_texture(this->m_output_texture); gs_blend_function_separate(GS_BLEND_SRCALPHA, GS_BLEND_INVSRCALPHA, GS_BLEND_ONE, GS_BLEND_ONE);
} if (this->m_outer_shadow) {
if (m_outer_shadow) {
try {
gs_enable_blending(true);
gs_blend_function_separate(GS_BLEND_SRCALPHA, GS_BLEND_DSTALPHA, GS_BLEND_ONE, GS_BLEND_ONE);
consumer_effect->get_parameter("pSDFTexture").set_texture(this->m_sdf_texture); consumer_effect->get_parameter("pSDFTexture").set_texture(this->m_sdf_texture);
consumer_effect->get_parameter("pSDFThreshold").set_float(this->m_sdf_threshold); consumer_effect->get_parameter("pSDFThreshold").set_float(this->m_sdf_threshold);
consumer_effect->get_parameter("pImageTexture").set_texture(this->m_source_texture->get_object()); consumer_effect->get_parameter("pImageTexture").set_texture(this->m_source_texture->get_object());
@ -810,26 +802,11 @@ void filter::sdf_effects::sdf_effects_instance::video_render(gs_effect_t* effect
consumer_effect->get_parameter("pShadowOffset") consumer_effect->get_parameter("pShadowOffset")
.set_float2(this->m_outer_shadow_offset_x / float_t(baseW), .set_float2(this->m_outer_shadow_offset_x / float_t(baseW),
this->m_outer_shadow_offset_y / float_t(baseH)); this->m_outer_shadow_offset_y / float_t(baseH));
while (gs_effect_loop(consumer_effect->get_object(), "ShadowOuter")) {
{ gs_draw_sprite(0, 0, 1, 1);
auto op = this->m_output_rt->render(baseW, baseH);
gs_ortho(0, 1, 0, 1, 0, 1);
while (gs_effect_loop(consumer_effect->get_object(), "ShadowOuter")) {
gs_draw_sprite(0, 0, 1, 1);
}
} }
// Flip Buffers
m_output_rt->get_texture(this->m_output_texture);
} catch (...) {
} }
} if (this->m_inner_shadow) {
if (m_inner_shadow) {
try {
gs_enable_blending(true);
gs_blend_function_separate(GS_BLEND_SRCALPHA, GS_BLEND_INVSRCALPHA, GS_BLEND_ONE, GS_BLEND_ONE);
consumer_effect->get_parameter("pSDFTexture").set_texture(this->m_sdf_texture); consumer_effect->get_parameter("pSDFTexture").set_texture(this->m_sdf_texture);
consumer_effect->get_parameter("pSDFThreshold").set_float(this->m_sdf_threshold); consumer_effect->get_parameter("pSDFThreshold").set_float(this->m_sdf_threshold);
consumer_effect->get_parameter("pImageTexture").set_texture(this->m_source_texture->get_object()); consumer_effect->get_parameter("pImageTexture").set_texture(this->m_source_texture->get_object());
@ -839,26 +816,11 @@ void filter::sdf_effects::sdf_effects_instance::video_render(gs_effect_t* effect
consumer_effect->get_parameter("pShadowOffset") consumer_effect->get_parameter("pShadowOffset")
.set_float2(this->m_inner_shadow_offset_x / float_t(baseW), .set_float2(this->m_inner_shadow_offset_x / float_t(baseW),
this->m_inner_shadow_offset_y / float_t(baseH)); this->m_inner_shadow_offset_y / float_t(baseH));
while (gs_effect_loop(consumer_effect->get_object(), "ShadowInner")) {
{ gs_draw_sprite(0, 0, 1, 1);
auto op = this->m_output_rt->render(baseW, baseH);
gs_ortho(0, 1, 0, 1, 0, 1);
while (gs_effect_loop(consumer_effect->get_object(), "ShadowInner")) {
gs_draw_sprite(0, 0, 1, 1);
}
} }
// Flip Buffers
m_output_rt->get_texture(this->m_output_texture);
} catch (...) {
} }
} if (this->m_outer_glow) {
if (m_outer_glow) {
try {
gs_enable_blending(true);
gs_blend_function_separate(GS_BLEND_SRCALPHA, GS_BLEND_DSTALPHA, GS_BLEND_ONE, GS_BLEND_ONE);
consumer_effect->get_parameter("pSDFTexture").set_texture(this->m_sdf_texture); consumer_effect->get_parameter("pSDFTexture").set_texture(this->m_sdf_texture);
consumer_effect->get_parameter("pSDFThreshold").set_float(this->m_sdf_threshold); consumer_effect->get_parameter("pSDFThreshold").set_float(this->m_sdf_threshold);
consumer_effect->get_parameter("pImageTexture").set_texture(this->m_source_texture->get_object()); consumer_effect->get_parameter("pImageTexture").set_texture(this->m_source_texture->get_object());
@ -866,26 +828,11 @@ void filter::sdf_effects::sdf_effects_instance::video_render(gs_effect_t* effect
consumer_effect->get_parameter("pGlowWidth").set_float(this->m_outer_glow_width); consumer_effect->get_parameter("pGlowWidth").set_float(this->m_outer_glow_width);
consumer_effect->get_parameter("pGlowSharpness").set_float(this->m_outer_glow_sharpness); consumer_effect->get_parameter("pGlowSharpness").set_float(this->m_outer_glow_sharpness);
consumer_effect->get_parameter("pGlowSharpnessInverse").set_float(this->m_outer_glow_sharpness_inv); consumer_effect->get_parameter("pGlowSharpnessInverse").set_float(this->m_outer_glow_sharpness_inv);
while (gs_effect_loop(consumer_effect->get_object(), "GlowOuter")) {
{ gs_draw_sprite(0, 0, 1, 1);
auto op = this->m_output_rt->render(baseW, baseH);
gs_ortho(0, 1, 0, 1, 0, 1);
while (gs_effect_loop(consumer_effect->get_object(), "GlowOuter")) {
gs_draw_sprite(0, 0, 1, 1);
}
} }
// Flip Buffers
m_output_rt->get_texture(this->m_output_texture);
} catch (...) {
} }
} if (this->m_inner_glow) {
if (m_inner_glow) {
try {
gs_enable_blending(true);
gs_blend_function_separate(GS_BLEND_SRCALPHA, GS_BLEND_INVSRCALPHA, GS_BLEND_ONE, GS_BLEND_ONE);
consumer_effect->get_parameter("pSDFTexture").set_texture(this->m_sdf_texture); consumer_effect->get_parameter("pSDFTexture").set_texture(this->m_sdf_texture);
consumer_effect->get_parameter("pSDFThreshold").set_float(this->m_sdf_threshold); consumer_effect->get_parameter("pSDFThreshold").set_float(this->m_sdf_threshold);
consumer_effect->get_parameter("pImageTexture").set_texture(this->m_source_texture->get_object()); consumer_effect->get_parameter("pImageTexture").set_texture(this->m_source_texture->get_object());
@ -893,26 +840,11 @@ void filter::sdf_effects::sdf_effects_instance::video_render(gs_effect_t* effect
consumer_effect->get_parameter("pGlowWidth").set_float(this->m_inner_glow_width); consumer_effect->get_parameter("pGlowWidth").set_float(this->m_inner_glow_width);
consumer_effect->get_parameter("pGlowSharpness").set_float(this->m_inner_glow_sharpness); consumer_effect->get_parameter("pGlowSharpness").set_float(this->m_inner_glow_sharpness);
consumer_effect->get_parameter("pGlowSharpnessInverse").set_float(this->m_inner_glow_sharpness_inv); consumer_effect->get_parameter("pGlowSharpnessInverse").set_float(this->m_inner_glow_sharpness_inv);
while (gs_effect_loop(consumer_effect->get_object(), "GlowInner")) {
{ gs_draw_sprite(0, 0, 1, 1);
auto op = this->m_output_rt->render(baseW, baseH);
gs_ortho(0, 1, 0, 1, 0, 1);
while (gs_effect_loop(consumer_effect->get_object(), "GlowInner")) {
gs_draw_sprite(0, 0, 1, 1);
}
} }
// Flip Buffers
m_output_rt->get_texture(this->m_output_texture);
} catch (...) {
} }
} if (this->m_outline) {
if (m_outline) {
try {
gs_enable_blending(true);
gs_blend_function_separate(GS_BLEND_SRCALPHA, GS_BLEND_INVSRCALPHA, GS_BLEND_ONE, GS_BLEND_ONE);
consumer_effect->get_parameter("pSDFTexture").set_texture(this->m_sdf_texture); consumer_effect->get_parameter("pSDFTexture").set_texture(this->m_sdf_texture);
consumer_effect->get_parameter("pSDFThreshold").set_float(this->m_sdf_threshold); consumer_effect->get_parameter("pSDFThreshold").set_float(this->m_sdf_threshold);
consumer_effect->get_parameter("pImageTexture").set_texture(this->m_source_texture->get_object()); consumer_effect->get_parameter("pImageTexture").set_texture(this->m_source_texture->get_object());
@ -921,21 +853,15 @@ void filter::sdf_effects::sdf_effects_instance::video_render(gs_effect_t* effect
consumer_effect->get_parameter("pOutlineOffset").set_float(this->m_outline_offset); consumer_effect->get_parameter("pOutlineOffset").set_float(this->m_outline_offset);
consumer_effect->get_parameter("pOutlineSharpness").set_float(this->m_outline_sharpness); consumer_effect->get_parameter("pOutlineSharpness").set_float(this->m_outline_sharpness);
consumer_effect->get_parameter("pOutlineSharpnessInverse").set_float(this->m_outline_sharpness_inv); consumer_effect->get_parameter("pOutlineSharpnessInverse").set_float(this->m_outline_sharpness_inv);
while (gs_effect_loop(consumer_effect->get_object(), "Outline")) {
{ gs_draw_sprite(0, 0, 1, 1);
auto op = this->m_output_rt->render(baseW, baseH);
gs_ortho(0, 1, 0, 1, 0, 1);
while (gs_effect_loop(consumer_effect->get_object(), "Outline")) {
gs_draw_sprite(0, 0, 1, 1);
}
} }
// Flip Buffers
m_output_rt->get_texture(this->m_output_texture);
} catch (...) {
} }
} catch (...) {
} }
this->m_output_rt->get_texture(this->m_output_texture);
gs_blend_state_pop(); gs_blend_state_pop();
this->m_output_rendered = true; this->m_output_rendered = true;
} }