commit x64 compilation from lulu cause the other branch dont seems to compile properly at home
This commit is contained in:
668
include/engine/gpu/gpu_post_process_chain.cpp
Normal file
668
include/engine/gpu/gpu_post_process_chain.cpp
Normal file
@ -0,0 +1,668 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
GSFramework
|
||||
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
||||
----------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#include <math.h>
|
||||
#include "gpu/gpu_renderer.h"
|
||||
#include "gpu/gpu_geometry.h"
|
||||
#include "gpu/gpu_shader_object.h"
|
||||
#include "gpu/gpu_draw_context.h"
|
||||
#include "core/geometry.h"
|
||||
#include "rand/rand.h"
|
||||
#include "log/log.h"
|
||||
|
||||
using namespace GS;
|
||||
using namespace GPU;
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static bool IsPostProcessExcluded(NML::Tag *exclusion_key, const char *tag)
|
||||
{
|
||||
NML::Tag *__t = exclusion_key ? exclusion_key->GetTypedTag(tag, Variant::VariantBool) : NULL;
|
||||
return __t && __t->GetBool();
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
//---------------------------------------------------------------
|
||||
#define _SwapTarget { tmp = t[0]; t[0] = t[1]; t[1] = tmp; }
|
||||
//---------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void Renderer::GetPostProcessNormalDepth(const Stack <RenderPrimitive *> display_lists[2])
|
||||
{
|
||||
if (normal_depth_updated)
|
||||
return;
|
||||
|
||||
ScopedPerfEvent event(this, __FUNCTION__, Color::Purple);
|
||||
|
||||
fRect old_viewport = GetViewport();
|
||||
|
||||
// Generate normal/depth buffer.
|
||||
SetViewport(fRect(0, 0, (float)t_fx[2]->GetWidth(), (float)t_fx[2]->GetHeight()));
|
||||
fx_fbo->SetColorTexture(t_fx[2]);
|
||||
|
||||
if (render_technique == TechniqueDeferred)
|
||||
{
|
||||
SetCurrentFBO(fx_fbo);
|
||||
RenderFullscreenQuad(*single_texture_program, old_viewport.GetWidth() / (float)dimensions.x, old_viewport.GetHeight() / (float)dimensions.y, t_gbuffer[0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
fx_fbo->SetDepthTexture(t_fx_depth);
|
||||
SetCurrentFBO(fx_fbo);
|
||||
|
||||
Clear(0, 0, 0);
|
||||
DrawContext dc(DrawContext::Opaque, DrawContext::Base, MaterialShader::PP_NormalDepth);
|
||||
DrawList(display_lists[0], dc);
|
||||
|
||||
fx_fbo->SetDepthTexture(NULL);
|
||||
}
|
||||
|
||||
SetViewport(old_viewport);
|
||||
normal_depth_updated = true;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void Renderer::ApplyDirectionalBlur(Render::Texture *t[2], const Vector2 &d, float attn)
|
||||
{
|
||||
if (!fx_blur_program)
|
||||
return;
|
||||
|
||||
Render::Texture *tmp;
|
||||
|
||||
ShaderInput *u_pass = fx_blur_program->GetInput("u_pass"),
|
||||
*u_blur_d = fx_blur_program->GetInput("u_blur_d"),
|
||||
*u_attenuation = fx_blur_program->GetInput("u_attenuation");
|
||||
|
||||
SetShaderProgram(fx_blur_program);
|
||||
u_blur_d->SetValue(d.x, d.y);
|
||||
u_attenuation->SetValue(attn);
|
||||
|
||||
fRect nviewport(viewport.sx / dimensions.x, viewport.sy / dimensions.y, viewport.ex / dimensions.x, viewport.ey / dimensions.y);
|
||||
|
||||
for (int n = 0; n < 4; ++n)
|
||||
{
|
||||
fx_fbo->SetColorTexture(t[1]);
|
||||
SetCurrentFBO(fx_fbo);
|
||||
u_pass->SetValue(float(n));
|
||||
RenderFullscreenQuad(*fx_blur_program, nviewport, fRect(0, 0, 1, 1), t[0]);
|
||||
_SwapTarget
|
||||
}
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void Renderer::ApplyBloomFilter(Render::Texture *t_in, float strength, float threshold, float exponent, float radius, float strength_white_screen)
|
||||
{
|
||||
if (!strength || !single_texture_cutoff_program || !tone_mapping_program)
|
||||
return;
|
||||
|
||||
ScopedPerfEvent event(this, __FUNCTION__, Color::Purple);
|
||||
|
||||
Render::Texture *t[] = { t_fx[0], t_fx[1] };
|
||||
ShaderInput *u_cutoff = single_texture_cutoff_program->GetInput("u_cutoff"),
|
||||
*u_strength = tone_mapping_program->GetInput("u_strength"),
|
||||
*u_strength_white_screen = tone_mapping_program->GetInput("u_strength_white_screen");
|
||||
|
||||
if (!u_cutoff || !u_strength || !u_strength_white_screen)
|
||||
return;
|
||||
|
||||
fRect old_viewport = GetViewport();
|
||||
|
||||
fRect nviewport(viewport.sx / dimensions.x, viewport.sy / dimensions.y, viewport.ex / dimensions.x, viewport.ey / dimensions.y);
|
||||
fRect fx_viewport(old_viewport.sx / fx_scale, old_viewport.sy / fx_scale, old_viewport.ex / fx_scale, old_viewport.ey / fx_scale);
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
#define CutoffFrameToBloomFX \
|
||||
{ \
|
||||
SetViewport(fx_viewport); \
|
||||
\
|
||||
fx_fbo->SetColorTexture(t[0]); \
|
||||
SetCurrentFBO(fx_fbo);\
|
||||
SetShaderProgram(single_texture_cutoff_program); \
|
||||
u_cutoff->SetValue(threshold); \
|
||||
RenderFullscreenQuad(*single_texture_cutoff_program, nviewport, fRect(0, 0, 1, 1), t_in); \
|
||||
}
|
||||
|
||||
|
||||
#define OutputBloomFXToFrame \
|
||||
{ \
|
||||
SetViewport(old_viewport);\
|
||||
\
|
||||
EnableBlending(true); \
|
||||
SetBlendFunc(BlendOne, BlendOne); \
|
||||
\
|
||||
fx_fbo->SetColorTexture(t_in); \
|
||||
SetCurrentFBO(fx_fbo);\
|
||||
SetShaderProgram(tone_mapping_program); \
|
||||
u_strength->SetValue(strength * 1.25f); \
|
||||
u_strength_white_screen->SetValue(strength_white_screen); \
|
||||
RenderFullscreenQuad(*tone_mapping_program, nviewport, fRect(0, 0, 1, 1), t[0]); \
|
||||
\
|
||||
EnableBlending(false); \
|
||||
}
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
if (view_registry->GetBool("PostProcess:Bloom:Streak:Enabled", false))
|
||||
{
|
||||
float angle = view_registry->GetReal("PostProcess:Bloom:Streak:Angle"),
|
||||
attn = view_registry->GetReal("PostProcess:Bloom:Streak:Attenuation", 0.975f);
|
||||
|
||||
for (int n = 0; n < 2; ++n)
|
||||
{
|
||||
Vector2 d = Vector2(cos(angle), sin(angle)) * radius / 12.f;
|
||||
|
||||
CutoffFrameToBloomFX
|
||||
ApplyDirectionalBlur(t, d, attn);
|
||||
OutputBloomFXToFrame
|
||||
|
||||
if (!view_registry->GetBool("PostProcess:Bloom:Streak:CrossShaped", false))
|
||||
break;
|
||||
|
||||
angle += Units::Deg(90.f);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CutoffFrameToBloomFX
|
||||
ApplyDirectionalBlur(t, Vector2(radius / 64.f, 0));
|
||||
ApplyDirectionalBlur(t, Vector2(0, radius / 64.f));
|
||||
OutputBloomFXToFrame
|
||||
}
|
||||
|
||||
SetViewport(old_viewport);
|
||||
SetClippingRect(&old_viewport);
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool Renderer::ApplyNoiseFilter(Render::Texture *t_in, Render::Texture *t_out, float strength, float mono, float bias)
|
||||
{
|
||||
if (!strength || !noise_program)
|
||||
return false;
|
||||
|
||||
ScopedPerfEvent event(this, __FUNCTION__, Color::Purple);
|
||||
|
||||
ShaderInput *u_strength = noise_program->GetInput("u_strength"),
|
||||
*u_mono = noise_program->GetInput("u_mono"),
|
||||
*u_bias = noise_program->GetInput("u_bias"),
|
||||
*u_random = noise_program->GetInput("u_random");
|
||||
|
||||
if (!u_strength || !u_mono || !u_bias || !u_random)
|
||||
return false;
|
||||
|
||||
fx_fbo->SetColorTexture(t_out);
|
||||
SetCurrentFBO(fx_fbo);
|
||||
|
||||
float random[2] = { Random::FRand(), Random::FRand() };
|
||||
|
||||
SetShaderProgram(noise_program);
|
||||
u_strength->SetValue(strength);
|
||||
u_mono->SetValue(mono);
|
||||
u_bias->SetValue(bias);
|
||||
u_random->SetValue(random[0], random[1]);
|
||||
RenderFullscreenQuad(*noise_program, viewport.GetWidth() / (float)dimensions.x, viewport.GetHeight() / (float)dimensions.y, t_in);
|
||||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool Renderer::ApplySSAAFilter(Render::Texture *t_in, Render::Texture *t_out)
|
||||
{
|
||||
if (!ssaa_program)
|
||||
return false;
|
||||
|
||||
ScopedPerfEvent event(this, __FUNCTION__, Color::Purple);
|
||||
|
||||
fx_fbo->SetColorTexture(t_out);
|
||||
SetCurrentFBO(fx_fbo);
|
||||
|
||||
SetShaderProgram(ssaa_program);
|
||||
RenderFullscreenQuad(*ssaa_program, viewport.GetWidth() / (float)dimensions.x, viewport.GetHeight() / (float)dimensions.y, t_in);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool Renderer::ApplyResolveMSAADepth(Render::Texture *t_depth_msaa, Render::Texture *t_out)
|
||||
{
|
||||
if (!t_depth_msaa || !t_out || !resolve_msaa_depth_program)
|
||||
return false;
|
||||
ScopedPerfEvent event(this, __FUNCTION__, Color::Purple);
|
||||
|
||||
fx_fbo->SetColorTexture(t_out);
|
||||
SetCurrentFBO(fx_fbo);
|
||||
|
||||
ShaderInput *msaa_depth = resolve_msaa_depth_program->GetInput("u_depthMSAA");
|
||||
SetShaderProgram(resolve_msaa_depth_program);
|
||||
msaa_depth->SetValue(t_depth_msaa);
|
||||
|
||||
RenderFullscreenQuad(*resolve_msaa_depth_program,viewport.GetWidth() / (float)dimensions.x,viewport.GetHeight() / (float)dimensions.y);
|
||||
|
||||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool Renderer::ApplySSAOFilter(Render::Texture *t_in, Render::Texture *t_out, const Stack <RenderPrimitive *> display_lists[2], float s, float r, float d, float blur_r)
|
||||
{
|
||||
if (!s || !ssao_program)
|
||||
return false;
|
||||
|
||||
ScopedPerfEvent event(this, __FUNCTION__, Color::Purple);
|
||||
|
||||
ShaderInput *u_strength = ssao_program->GetInput("u_strength"),
|
||||
*u_radius = ssao_program->GetInput("u_radius"),
|
||||
*u_distance_scale = ssao_program->GetInput("u_distance_scale"),
|
||||
*u_iproj2d = ssao_program->GetInput("u_iproj2d");
|
||||
|
||||
if (!u_strength || !u_radius || !u_distance_scale)
|
||||
return false;
|
||||
|
||||
GetPostProcessNormalDepth(display_lists);
|
||||
|
||||
#if 0
|
||||
// Normal/depth debug output.
|
||||
fx_fbo->SetColorTexture(t_in);
|
||||
SetCurrentFBO(fx_fbo);
|
||||
RenderFullscreenQuad(single_texture_program, viewport.GetWidth() / (float)dimensions.x, viewport.GetHeight() / (float)dimensions.y, t_fx[2]);
|
||||
return false;
|
||||
#endif
|
||||
|
||||
fRect old_viewport = GetViewport();
|
||||
SetViewport(fRect(0, 0, (float)t_fx[2]->GetWidth(), (float)t_fx[2]->GetHeight()));
|
||||
|
||||
// Render raw SSAO to FX texture.
|
||||
SetShaderProgram(ssao_program);
|
||||
u_strength->SetValue(s);
|
||||
u_radius->SetValue(r * (4 / fx_scale));
|
||||
u_distance_scale->SetValue(d);
|
||||
|
||||
float iproj[] = { 1.f / m_projection.m[0][0], 1.f / m_projection.m[1][1] };
|
||||
if (!gpu_config.tex_origin_is_top_left)
|
||||
iproj[1] = -iproj[1];
|
||||
u_iproj2d->SetValue(iproj[0], iproj[1]);
|
||||
|
||||
EnableAlphaTest(false);
|
||||
EnableBlending(false);
|
||||
|
||||
int out_index = 0;
|
||||
fx_fbo->SetColorTexture(t_fx[out_index]);
|
||||
SetCurrentFBO(fx_fbo);
|
||||
Clear(0, 0, 0, 0, 1, ClearColor); // FIXME this is USELESS, but something is killing fragments with 0 alpha in ssao_program and disabling alpha testing does not solves the issue.
|
||||
RenderFullscreenQuad(*ssao_program, viewport.GetWidth() / (float)dimensions.x, viewport.GetHeight() / (float)dimensions.y, t_fx[2]);
|
||||
|
||||
if (ssao_blur_program)
|
||||
{
|
||||
// SSAO blur.
|
||||
if (blur_r > 0.f)
|
||||
{
|
||||
ShaderInput *u_blur_radius = ssao_blur_program->GetInput("u_blur_radius"),
|
||||
*u_normal_depth = ssao_blur_program->GetInput("u_normal_depth"); // the normal depth texture is not always used, depending on the quality settings.
|
||||
|
||||
if (u_blur_radius && u_normal_depth)
|
||||
{
|
||||
fx_fbo->SetColorTexture(t_fx[1 - out_index]);
|
||||
SetCurrentFBO(fx_fbo);
|
||||
Clear(0, 0, 0, 0, 1, ClearColor); // FIXME this is USELESS, but something is killing fragments with 0 alpha in ssao_program and disabling alpha testing does not solves the issue.
|
||||
|
||||
SetShaderProgram(ssao_blur_program);
|
||||
u_blur_radius->SetValue(blur_r);
|
||||
u_normal_depth->SetValue(t_fx[2].c_ptr());
|
||||
RenderFullscreenQuad(*ssao_blur_program, viewport.GetWidth() / (float)dimensions.x, viewport.GetHeight() / (float)dimensions.y, t_fx[out_index]);
|
||||
|
||||
out_index = 1 - out_index;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Composite back over input.
|
||||
SetViewport(old_viewport);
|
||||
|
||||
fx_fbo->SetColorTexture(t_in);
|
||||
SetCurrentFBO(fx_fbo);
|
||||
|
||||
EnableBlending(true);
|
||||
SetBlendFunc(BlendSrcAlpha, BlendOneMinusSrcAlpha);
|
||||
RenderFullscreenQuad(*single_texture_program, 1, 1, t_fx[out_index]);
|
||||
EnableBlending(false);
|
||||
return false;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool Renderer::ApplySharpenFilter(Render::Texture *t_in, Render::Texture *t_out, float strength)
|
||||
{
|
||||
if (!strength || !sharpen_program)
|
||||
return false;
|
||||
|
||||
ScopedPerfEvent event(this, __FUNCTION__, Color::Purple);
|
||||
|
||||
ShaderInput *u_strength = sharpen_program->GetInput("u_strength");
|
||||
if (!u_strength)
|
||||
return false;
|
||||
|
||||
fx_fbo->SetColorTexture(t_out);
|
||||
SetCurrentFBO(fx_fbo);
|
||||
|
||||
SetShaderProgram(sharpen_program);
|
||||
u_strength->SetValue(strength);
|
||||
RenderFullscreenQuad(*sharpen_program, viewport.GetWidth() / (float)dimensions.x, viewport.GetHeight() / (float)dimensions.y, t_in);
|
||||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool Renderer::ApplyHSL(Render::Texture *t_in, Render::Texture *t_out, float H, float S, float L)
|
||||
{
|
||||
if (((H == 1.f) && (S == 1.f) && (L == 1.f)) || !hsl_program)
|
||||
return false;
|
||||
|
||||
ScopedPerfEvent event(this, __FUNCTION__, Color::Purple);
|
||||
|
||||
ShaderInput *u_H = hsl_program->GetInput("u_H"),
|
||||
*u_S = hsl_program->GetInput("u_S"),
|
||||
*u_L = hsl_program->GetInput("u_L");
|
||||
if (!u_H || !u_S || !u_L)
|
||||
return false;
|
||||
|
||||
fx_fbo->SetColorTexture(t_out);
|
||||
SetCurrentFBO(fx_fbo);
|
||||
|
||||
SetShaderProgram(hsl_program);
|
||||
u_H->SetValue(H);
|
||||
u_S->SetValue(S);
|
||||
u_L->SetValue(L);
|
||||
RenderFullscreenQuad(*hsl_program, viewport.GetWidth() / (float)dimensions.x, viewport.GetHeight() / (float)dimensions.y, t_in);
|
||||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool Renderer::ApplyChromaticDispersion(Render::Texture *t_in, Render::Texture *t_out, float width)
|
||||
{
|
||||
if ((width == 0.f) || !chromatic_dispersion_program)
|
||||
return false;
|
||||
|
||||
ScopedPerfEvent event(this, __FUNCTION__, Color::Purple);
|
||||
|
||||
ShaderInput *u_width = chromatic_dispersion_program->GetInput("u_width");
|
||||
if (!u_width)
|
||||
return false;
|
||||
|
||||
fx_fbo->SetColorTexture(t_out);
|
||||
SetCurrentFBO(fx_fbo);
|
||||
|
||||
SetShaderProgram(chromatic_dispersion_program);
|
||||
u_width->SetValue(width);
|
||||
RenderFullscreenQuad(*chromatic_dispersion_program, viewport.GetWidth() / (float)dimensions.x, viewport.GetHeight() / (float)dimensions.y, t_in);
|
||||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool Renderer::ApplyRadialBlur(Render::Texture *t_in, Render::Texture *t_out, float strength, float center_x, float center_y)
|
||||
{
|
||||
if (!strength || !radial_blur_program)
|
||||
return false;
|
||||
|
||||
ScopedPerfEvent event(this, __FUNCTION__, Color::Purple);
|
||||
|
||||
ShaderInput *u_strength = radial_blur_program->GetInput("u_strength"),
|
||||
*u_center = radial_blur_program->GetInput("u_center");
|
||||
|
||||
if (!u_strength || !u_center)
|
||||
return false;
|
||||
|
||||
fx_fbo->SetColorTexture(t_out);
|
||||
SetCurrentFBO(fx_fbo);
|
||||
|
||||
SetShaderProgram(radial_blur_program);
|
||||
u_strength->SetValue(strength);
|
||||
float center[] = { center_x * viewport.GetWidth() / (float)dimensions.x, center_y * viewport.GetHeight() / (float)dimensions.y };
|
||||
u_center->SetValue(center[0], center[1]);
|
||||
RenderFullscreenQuad(*radial_blur_program, viewport.GetWidth() / (float)dimensions.x, viewport.GetHeight() / (float)dimensions.y, t_in);
|
||||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool Renderer::ApplyMotionBlur(Render::Texture *t_in, Render::Texture *t_out, const Stack <RenderPrimitive *> display_lists[2], float strength, int quality)
|
||||
{
|
||||
if (!strength || !quality || !motion_blur_program)
|
||||
return false;
|
||||
|
||||
ScopedPerfEvent event(this, __FUNCTION__, Color::Purple);
|
||||
|
||||
float k_u = viewport.GetWidth() / dimensions.x, k_v = viewport.GetHeight() / dimensions.y;
|
||||
|
||||
// Generate a velocity buffer from the opaque surface list.
|
||||
fRect old_viewport = GetViewport();
|
||||
{
|
||||
ScopedPerfEvent event(this, "Render Velocity Buffer", Color::Purple);
|
||||
|
||||
SetViewport(fRect(0, 0, (float)t_fx[0]->GetWidth(), (float)t_fx[0]->GetHeight()));
|
||||
|
||||
fx_fbo->SetColorTexture(t_fx[0]);
|
||||
fx_fbo->SetDepthTexture(t_fx_depth);
|
||||
SetCurrentFBO(fx_fbo);
|
||||
|
||||
Clear(0, 0, 0);
|
||||
|
||||
DrawContext dc(DrawContext::Opaque, DrawContext::Base, MaterialShader::PP_Velocity);
|
||||
DrawList(display_lists[0], dc);
|
||||
}
|
||||
|
||||
// Vector field blur.
|
||||
#if 0
|
||||
float k_blur = 0.5;
|
||||
Render::Texture *t_pp_0[] = { t_fx[0], t_fx[1] };
|
||||
ApplyDirectionalBlur(t_pp_0, nVector2(k_blur, 0), 0.975f);
|
||||
Render::Texture *t_pp_1[] = { t_fx[1], t_fx[0] };
|
||||
ApplyDirectionalBlur(t_pp_1, nVector2(0, k_blur), 0.975f);
|
||||
#endif
|
||||
|
||||
// Apply velocity field.
|
||||
fx_fbo->SetDepthTexture(NULL);
|
||||
|
||||
// Quality: 0 - No PP, 1 - Lores blur, 2 - Hires blur.
|
||||
if (quality == 1)
|
||||
{
|
||||
fx_fbo->SetColorTexture(t_fx[1]);
|
||||
SetCurrentFBO(fx_fbo);
|
||||
SetShaderProgram(single_texture_program);
|
||||
RenderFullscreenQuad(*single_texture_program, 1, 1, t_in);
|
||||
}
|
||||
else
|
||||
{
|
||||
fx_fbo->SetColorTexture(t_out);
|
||||
SetCurrentFBO(fx_fbo);
|
||||
SetViewport(old_viewport);
|
||||
}
|
||||
|
||||
ShaderInput *u_strength = motion_blur_program->GetInput("u_strength"),
|
||||
*u_pow = motion_blur_program->GetInput("u_pow"),
|
||||
*u_max = motion_blur_program->GetInput("u_max"),
|
||||
*u_source = motion_blur_program->GetInput("u_source"),
|
||||
*u_velocity = motion_blur_program->GetInput("u_velocity");
|
||||
|
||||
SetShaderProgram(motion_blur_program);
|
||||
const float k = 1.f; // stats.bench_fps.GetFps() / 60.f; // Normalize to 60fps.
|
||||
|
||||
u_strength->SetValue(strength * 32.f * k);
|
||||
u_pow->SetValue(2.f);
|
||||
u_max->SetValue(1.f / 128.f); // Works in normalized space, does not need to adjust for variable resolution.
|
||||
|
||||
motion_blur_program->Set(*u_velocity->location, *t_fx[0], u_velocity->index);
|
||||
|
||||
if (quality == 1) // low-res blur path
|
||||
{
|
||||
fx_fbo->SetColorTexture(t_fx[2]);
|
||||
SetCurrentFBO(fx_fbo);
|
||||
u_source->SetValue(t_fx[1].c_ptr());
|
||||
RenderFullscreenQuad(*motion_blur_program, 1, 1);
|
||||
|
||||
fx_fbo->SetColorTexture(t_in);
|
||||
SetCurrentFBO(fx_fbo);
|
||||
SetViewport(old_viewport);
|
||||
|
||||
EnableBlending(true);
|
||||
SetBlendFunc(BlendSrcAlpha, BlendOneMinusSrcAlpha);
|
||||
SetShaderProgram(single_texture_program);
|
||||
RenderFullscreenQuad(*single_texture_program, k_u, k_v, t_fx[2]);
|
||||
EnableBlending(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
u_source->SetValue(t_in);
|
||||
RenderFullscreenQuad(*motion_blur_program, viewport.GetWidth() / (float)dimensions.x, viewport.GetHeight() / (float)dimensions.y);
|
||||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
Render::Texture *Renderer::ApplyPostProcessChain(const Stack <RenderPrimitive *> display_lists[2])
|
||||
{
|
||||
ScopedBenchmark bench(stats.bench_post_process);
|
||||
ScopedPerfEvent event(this, "Apply Post-Processing Chain", Color::Green);
|
||||
|
||||
if (!gpu_config.use_rtt)
|
||||
return t_compose[0];
|
||||
|
||||
normal_depth_updated = false;
|
||||
|
||||
NML::Tag *post_process_registry = view_registry ? view_registry->GetTag("PostProcess") : NULL;
|
||||
if (!post_process_registry)
|
||||
return t_compose[0];
|
||||
NML::Tag *exclusion_key = registry.GetTag("PostProcess:Exclusion");
|
||||
|
||||
fRect old_clipping = GetClippingRect();
|
||||
SetClippingRect(NULL);
|
||||
|
||||
uint i_compose = 0;
|
||||
NML::Tag *tag;
|
||||
|
||||
// SSAO.
|
||||
#if !(__PLATFORM_ANDROID_NDK__ || __PLATFORM_IOS__)
|
||||
if (((tag = post_process_registry->GetTag("SSAO")) != NULL) && !IsPostProcessExcluded(exclusion_key, "SSAO"))
|
||||
if (ApplySSAOFilter
|
||||
(
|
||||
t_compose[i_compose],
|
||||
t_compose[1 - i_compose],
|
||||
display_lists,
|
||||
view_registry->GetReal("PostProcess:SSAO:Strength", 1),
|
||||
view_registry->GetReal("PostProcess:SSAO:Radius", 2),
|
||||
view_registry->GetReal("PostProcess:SSAO:DistanceScale", 0.5),
|
||||
view_registry->GetReal("PostProcess:SSAO:BlurRadius", 8)
|
||||
))
|
||||
i_compose = 1 - i_compose;
|
||||
#endif
|
||||
|
||||
// Sharpen.
|
||||
if (((tag = post_process_registry->GetTag("Sharpen")) != NULL) && !IsPostProcessExcluded(exclusion_key, "Sharpen"))
|
||||
if (ApplySharpenFilter
|
||||
(
|
||||
t_compose[i_compose],
|
||||
t_compose[1 - i_compose],
|
||||
view_registry->GetReal("PostProcess:Sharpen:Strength", 0.5f)
|
||||
))
|
||||
i_compose = 1 - i_compose;
|
||||
|
||||
// SSAA.
|
||||
if (render_technique == TechniqueDeferred)
|
||||
if (registry.GetBool("Antialiasing:Enable", false))
|
||||
if (ApplySSAAFilter
|
||||
(
|
||||
t_compose[i_compose],
|
||||
t_compose[1 - i_compose]
|
||||
))
|
||||
i_compose = 1 - i_compose;
|
||||
|
||||
#if !(__PLATFORM_ANDROID_NDK__ || __PLATFORM_IOS__)
|
||||
// Motion blur.
|
||||
if (((tag = post_process_registry->GetTag("MotionBlur")) != NULL) && !IsPostProcessExcluded(exclusion_key, "MotionBlur"))
|
||||
if (ApplyMotionBlur
|
||||
(
|
||||
t_compose[i_compose],
|
||||
t_compose[1 - i_compose],
|
||||
display_lists,
|
||||
view_registry->GetReal("PostProcess:MotionBlur:Strength", 0.5),
|
||||
registry.GetInteger("PostProcess:MotionBlur:Quality", 2)
|
||||
))
|
||||
i_compose = 1 - i_compose;
|
||||
#endif
|
||||
|
||||
// Radial blur.
|
||||
if (((tag = post_process_registry->GetTag("RadialBlur")) != NULL) && !IsPostProcessExcluded(exclusion_key, "RadialBlur"))
|
||||
if (ApplyRadialBlur
|
||||
(
|
||||
t_compose[i_compose],
|
||||
t_compose[1 - i_compose],
|
||||
view_registry->GetReal("PostProcess:RadialBlur:Strength", 0.5),
|
||||
view_registry->GetReal("PostProcess:RadialBlur:CenterX", 0.5),
|
||||
view_registry->GetReal("PostProcess:RadialBlur:CenterY", 0.5)
|
||||
))
|
||||
i_compose = 1 - i_compose;
|
||||
|
||||
// Bloom.
|
||||
if (((tag = post_process_registry->GetTag("Bloom")) != NULL) && !IsPostProcessExcluded(exclusion_key, "Bloom"))
|
||||
ApplyBloomFilter
|
||||
(
|
||||
t_compose[i_compose],
|
||||
view_registry->GetReal("PostProcess:Bloom:Strength", 1),
|
||||
view_registry->GetReal("PostProcess:Bloom:Threshold", 0.95f),
|
||||
view_registry->GetReal("PostProcess:Bloom:Exponent", 4),
|
||||
view_registry->GetReal("PostProcess:Bloom:Radius", 12),
|
||||
view_registry->GetReal("PostProcess:Sharpen:Strength", 0.5f)
|
||||
);
|
||||
|
||||
// Noise.
|
||||
#if !(__PLATFORM_ANDROID_NDK__ || __PLATFORM_IOS__)
|
||||
// TODO mobile version of this.
|
||||
if (((tag = post_process_registry->GetTag("Noise")) != NULL) && !IsPostProcessExcluded(exclusion_key, "Noise"))
|
||||
if (ApplyNoiseFilter
|
||||
(
|
||||
t_compose[i_compose],
|
||||
t_compose[1 - i_compose],
|
||||
view_registry->GetReal("PostProcess:Noise:Strength", 0.25f),
|
||||
view_registry->GetReal("PostProcess:Noise:Monochromatic", 0.f),
|
||||
view_registry->GetReal("PostProcess:Noise:LumaBias", 0.5f)
|
||||
) )
|
||||
i_compose = 1 - i_compose;
|
||||
#endif
|
||||
|
||||
// HSL.
|
||||
if (((tag = post_process_registry->GetTag("HueSaturation")) != NULL) && !IsPostProcessExcluded(exclusion_key, "HueSaturation"))
|
||||
if (ApplyHSL
|
||||
(
|
||||
t_compose[i_compose],
|
||||
t_compose[1 - i_compose],
|
||||
view_registry->GetReal("PostProcess:HueSaturation:H", 1),
|
||||
view_registry->GetReal("PostProcess:HueSaturation:S", 1),
|
||||
view_registry->GetReal("PostProcess:HueSaturation:L", 1)
|
||||
) )
|
||||
i_compose = 1 - i_compose;
|
||||
|
||||
// Chromatic dispersion.
|
||||
if (((tag = post_process_registry->GetTag("ChromDisp")) != NULL) && !IsPostProcessExcluded(exclusion_key, "ChromDisp"))
|
||||
if (ApplyChromaticDispersion
|
||||
(
|
||||
t_compose[i_compose],
|
||||
t_compose[1 - i_compose],
|
||||
view_registry->GetReal("PostProcess:ChromDisp:Width", 1)
|
||||
) )
|
||||
i_compose = 1 - i_compose;
|
||||
|
||||
SetBlendFunc(BlendSrcAlpha, BlendOneMinusSrcAlpha);
|
||||
|
||||
SetClippingRect(&old_clipping);
|
||||
|
||||
SetIndexSource(NULL);
|
||||
SetVertexSource(NULL, 0);
|
||||
return t_compose[i_compose];
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
Reference in New Issue
Block a user