From 860aec7bfaabbad139d27dd7f4738984276e6676 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Fri, 12 Feb 2021 01:03:16 +0200 Subject: [PATCH] Use samplers in effects and postprocessors --- source/ambientocclusion.cpp | 14 +++++++------- source/ambientocclusion.h | 2 ++ source/bloom.cpp | 11 ++++++----- source/bloom.h | 2 ++ source/colorcurve.cpp | 11 +++++------ source/colorcurve.h | 2 ++ source/effect.cpp | 16 ++++++++++++++++ source/effect.h | 10 ++++++++++ source/environmentmap.cpp | 5 ++--- source/environmentmap.h | 1 + source/postprocessor.cpp | 32 ++++++++++++++++++++++++++++++-- source/postprocessor.h | 6 ++++++ source/shadowmap.cpp | 16 ++++++++++++---- source/shadowmap.h | 3 +++ 14 files changed, 104 insertions(+), 27 deletions(-) diff --git a/source/ambientocclusion.cpp b/source/ambientocclusion.cpp index 17e4789d..8c1dd616 100644 --- a/source/ambientocclusion.cpp +++ b/source/ambientocclusion.cpp @@ -15,14 +15,14 @@ AmbientOcclusion::AmbientOcclusion(unsigned w, unsigned h, float): occlude_target(w, h, (RENDER_COLOR,R8)), occlude_shader("ambientocclusion_occlude.glsl"), combine_shader("ambientocclusion_combine.glsl"), - quad(get_fullscreen_quad()) + quad(get_fullscreen_quad()), + linear_sampler(get_linear_sampler()), + nearest_sampler(get_nearest_sampler()) { - occlude_target.set_texture_filter(LINEAR); - texturing.attach(2, occlude_target.get_target_texture(RENDER_COLOR)); + texturing.attach(2, occlude_target.get_target_texture(RENDER_COLOR), linear_sampler.get()); unsigned seed = 1; rotate_lookup.storage(RGBA8, 4, 4, 1); - rotate_lookup.get_default_sampler().set_filter(NEAREST); unsigned char data[64]; for(unsigned i=0; i<16; ++i) { @@ -36,7 +36,7 @@ AmbientOcclusion::AmbientOcclusion(unsigned w, unsigned h, float): } rotate_lookup.image(0, data); - texturing.attach(3, rotate_lookup); + texturing.attach(3, rotate_lookup, nearest_sampler.get()); shdata.uniform("source", 0); shdata.uniform("depth", 1); @@ -91,8 +91,8 @@ void AmbientOcclusion::set_edge_depth_threshold(float edt) void AmbientOcclusion::render(Renderer &renderer, const Texture2D &color, const Texture2D &depth) { - texturing.attach(0, color); - texturing.attach(1, depth); + texturing.attach(0, color, nearest_sampler.get()); + texturing.attach(1, depth, nearest_sampler.get()); if(renderer.get_camera()) shdata.uniform("inverse_projection", invert(renderer.get_camera()->get_projection_matrix())); diff --git a/source/ambientocclusion.h b/source/ambientocclusion.h index 5a779979..6c2c5d7e 100644 --- a/source/ambientocclusion.h +++ b/source/ambientocclusion.h @@ -47,6 +47,8 @@ private: Program combine_shader; mutable ProgramData shdata; RefPtr quad; + RefPtr linear_sampler; + RefPtr nearest_sampler; public: AmbientOcclusion(unsigned, unsigned, float = 1.0f); diff --git a/source/bloom.cpp b/source/bloom.cpp index c7bfd467..ee7c76c3 100644 --- a/source/bloom.cpp +++ b/source/bloom.cpp @@ -16,19 +16,20 @@ namespace GL { Bloom::Bloom(unsigned w, unsigned h): blur_shader("bloom_blur.glsl"), combine_shader("bloom_combine.glsl"), - quad(get_fullscreen_quad()) + quad(get_fullscreen_quad()), + nearest_sampler(get_nearest_sampler()), + linear_sampler(get_linear_sampler()) { blur_shdata[0].uniform("delta", 1.0f/w, 0.0f); blur_shdata[1].uniform("delta", 0.0f, 1.0f/h); for(unsigned i=0; i<2; ++i) target[i] = new RenderTarget(w, h, (RENDER_COLOR,RGB16F)); - target[1]->set_texture_filter(LINEAR); common_shdata.uniform("source", 0); common_shdata.uniform("blurred", 1); - combine_texturing.attach(1, target[1]->get_target_texture(RENDER_COLOR)); + combine_texturing.attach(1, target[1]->get_target_texture(RENDER_COLOR), linear_sampler.get()); set_radius(2.0f); set_strength(0.2f); @@ -74,12 +75,12 @@ void Bloom::render(Renderer &renderer, const Texture2D &src, const Texture2D &) { BindRestore bind_fbo(target[i]->get_framebuffer()); Renderer::Push push2(renderer); - renderer.set_texture(i ? &target[0]->get_target_texture(RENDER_COLOR) : &src); + renderer.set_texture(i ? &target[0]->get_target_texture(RENDER_COLOR) : &src, nearest_sampler.get()); renderer.add_shader_data(blur_shdata[i]); quad->draw(renderer); } - combine_texturing.attach(0, src); + combine_texturing.attach(0, src, nearest_sampler.get()); renderer.set_texturing(&combine_texturing); renderer.set_shader_program(&combine_shader); quad->draw(renderer); diff --git a/source/bloom.h b/source/bloom.h index ddf46fe9..6b10195b 100644 --- a/source/bloom.h +++ b/source/bloom.h @@ -48,6 +48,8 @@ private: Program combine_shader; Texturing combine_texturing; RefPtr quad; + RefPtr nearest_sampler; + RefPtr linear_sampler; public: Bloom(unsigned, unsigned); diff --git a/source/colorcurve.cpp b/source/colorcurve.cpp index 0b62583f..8811b065 100644 --- a/source/colorcurve.cpp +++ b/source/colorcurve.cpp @@ -13,16 +13,15 @@ namespace GL { ColorCurve::ColorCurve(): shprog("colorcurve.glsl"), - quad(get_fullscreen_quad()) + quad(get_fullscreen_quad()), + linear_sampler(get_linear_sampler()), + nearest_sampler(get_nearest_sampler()) { shdata.uniform("source", 0); shdata.uniform("curve", 1); curve.storage(LUMINANCE8, 256, 1); - Sampler &sampler = curve.get_default_sampler(); - sampler.set_min_filter(LINEAR); - sampler.set_wrap(CLAMP_TO_EDGE); - texturing.attach(1, curve); + texturing.attach(1, curve, linear_sampler.get()); set_exposure_adjust(0.0f); set_brightness_response(0.4f); @@ -72,7 +71,7 @@ void ColorCurve::set_linear() void ColorCurve::render(Renderer &renderer, const Texture2D &color_buf, const Texture2D &) { - texturing.attach(0, color_buf); + texturing.attach(0, color_buf, nearest_sampler.get()); Renderer::Push push(renderer); renderer.set_shader_program(&shprog, &shdata); diff --git a/source/colorcurve.h b/source/colorcurve.h index 87d43353..3f65b049 100644 --- a/source/colorcurve.h +++ b/source/colorcurve.h @@ -50,6 +50,8 @@ private: Texture1D curve; Texturing texturing; RefPtr quad; + RefPtr linear_sampler; + RefPtr nearest_sampler; public: ColorCurve(); diff --git a/source/effect.cpp b/source/effect.cpp index 36a50bc3..ad789af0 100644 --- a/source/effect.cpp +++ b/source/effect.cpp @@ -1,8 +1,11 @@ #include "effect.h" +#include "sampler.h" namespace Msp { namespace GL { +WeakPtr Effect::linear_sampler; + Effect::Effect(Renderable &r): renderable(r) { @@ -19,5 +22,18 @@ void Effect::disable_for_pass(const Tag &tag) enabled_passes.erase(tag); } +RefPtr Effect::get_linear_sampler() +{ + RefPtr sampler = linear_sampler; + if(!sampler) + { + sampler = new Sampler; + sampler->set_filter(LINEAR); + sampler->set_wrap(CLAMP_TO_EDGE); + linear_sampler = sampler; + } + return sampler; +} + } // namespace GL } // namespace Msp diff --git a/source/effect.h b/source/effect.h index c55aebf9..bc9e19ec 100644 --- a/source/effect.h +++ b/source/effect.h @@ -2,11 +2,14 @@ #define MSP_GL_EFFECT_H_ #include +#include #include "renderable.h" namespace Msp { namespace GL { +class Sampler; + /** Effects are used to wrap other renderables and give them additional visual properties. An Effect's render method should set up the necessary state, call @@ -18,6 +21,10 @@ protected: Renderable &renderable; std::set enabled_passes; +private: + static WeakPtr linear_sampler; + +protected: Effect(Renderable &); public: virtual ~Effect() { } @@ -30,6 +37,9 @@ public: virtual void setup_frame(Renderer &r) { renderable.setup_frame(r); } virtual void finish_frame() { renderable.finish_frame(); } + +protected: + static RefPtr get_linear_sampler(); }; } // namespace GL diff --git a/source/environmentmap.cpp b/source/environmentmap.cpp index f4000c76..3902eb8c 100644 --- a/source/environmentmap.cpp +++ b/source/environmentmap.cpp @@ -13,14 +13,12 @@ EnvironmentMap::EnvironmentMap(unsigned s, Renderable &r, Renderable &e): Effect(r), size(s), environment(e), + sampler(get_linear_sampler()), rendered(false), update_interval(1), update_delay(0) { env_tex.storage(RGB8, size, 1); - Sampler &env_samp = env_tex.get_default_sampler(); - env_samp.set_wrap(CLAMP_TO_EDGE); - env_samp.set_min_filter(LINEAR); depth_buf.storage(DEPTH_COMPONENT32F, size, size); for(unsigned i=0; i<6; ++i) { @@ -109,6 +107,7 @@ void EnvironmentMap::render(Renderer &renderer, const Tag &tag) const unsigned unit = renderer.allocate_effect_texunit(); shdata.uniform("environment", static_cast(unit)); + Bind _bind_sampler(*sampler, unit); Bind _bind_env(env_tex, unit); const Matrix &camera_matrix = renderer.get_camera()->get_object_matrix(); diff --git a/source/environmentmap.h b/source/environmentmap.h index 6fdd3749..c54968de 100644 --- a/source/environmentmap.h +++ b/source/environmentmap.h @@ -32,6 +32,7 @@ private: TextureCube env_tex; Renderbuffer depth_buf; Framebuffer fbo[6]; + RefPtr sampler; Camera camera; mutable ProgramData shdata; bool rendered; diff --git a/source/postprocessor.cpp b/source/postprocessor.cpp index ffc753e4..6af069e9 100644 --- a/source/postprocessor.cpp +++ b/source/postprocessor.cpp @@ -1,12 +1,15 @@ #include "mesh.h" #include "meshbuilder.h" #include "postprocessor.h" +#include "sampler.h" #include "shader.h" namespace Msp { namespace GL { WeakPtr PostProcessor::fullscreen_quad; +WeakPtr PostProcessor::nearest_sampler; +WeakPtr PostProcessor::linear_sampler; void PostProcessor::render(Renderer &, const Texture2D &color, const Texture2D &depth) { @@ -15,8 +18,7 @@ void PostProcessor::render(Renderer &, const Texture2D &color, const Texture2D & RefPtr PostProcessor::get_fullscreen_quad() { - RefPtr mesh; - mesh = fullscreen_quad; + RefPtr mesh = fullscreen_quad; if(!mesh) { mesh = new Mesh(VERTEX2); @@ -32,6 +34,32 @@ RefPtr PostProcessor::get_fullscreen_quad() return mesh; } +RefPtr PostProcessor::get_nearest_sampler() +{ + RefPtr sampler = nearest_sampler; + if(!sampler) + { + sampler = new Sampler; + sampler->set_filter(NEAREST); + sampler->set_wrap(CLAMP_TO_EDGE); + nearest_sampler = sampler; + } + return sampler; +} + +RefPtr PostProcessor::get_linear_sampler() +{ + RefPtr sampler = linear_sampler; + if(!sampler) + { + sampler = new Sampler; + sampler->set_filter(LINEAR); + sampler->set_wrap(CLAMP_TO_EDGE); + linear_sampler = sampler; + } + return sampler; +} + PostProcessor::Template::Template(): size_divisor(1) diff --git a/source/postprocessor.h b/source/postprocessor.h index daaf434e..c107d885 100644 --- a/source/postprocessor.h +++ b/source/postprocessor.h @@ -8,6 +8,7 @@ namespace GL { class Mesh; class Renderer; +class Sampler; class Shader; class Texture2D; @@ -37,6 +38,8 @@ public: private: static WeakPtr fullscreen_quad; + static WeakPtr nearest_sampler; + static WeakPtr linear_sampler; protected: PostProcessor() { } @@ -52,6 +55,9 @@ protected: /** Returns a mesh consisting of a single quad, covering the entire screen. The vertices are in normalized device coordinates. */ static RefPtr get_fullscreen_quad(); + + static RefPtr get_nearest_sampler(); + static RefPtr get_linear_sampler(); }; } // namespace GL diff --git a/source/shadowmap.cpp b/source/shadowmap.cpp index 6250f899..eaf6e137 100644 --- a/source/shadowmap.cpp +++ b/source/shadowmap.cpp @@ -12,6 +12,8 @@ using namespace std; namespace Msp { namespace GL { +WeakPtr ShadowMap::shadow_sampler; + ShadowMap::ShadowMap(unsigned s, Renderable &r, const Light &l): Effect(r), size(s), @@ -20,10 +22,15 @@ ShadowMap::ShadowMap(unsigned s, Renderable &r, const Light &l): depth_bias(4), rendered(false) { - Sampler &depth_samp = depth_buf.get_default_sampler(); - depth_samp.set_min_filter(LINEAR); - depth_samp.set_compare(LEQUAL); - depth_samp.set_wrap(CLAMP_TO_EDGE); + sampler = shadow_sampler; + if(!sampler) + { + sampler = new Sampler; + sampler->set_filter(LINEAR); + sampler->set_compare(LEQUAL); + sampler->set_wrap(CLAMP_TO_EDGE); + shadow_sampler = sampler; + } depth_buf.storage(DEPTH_COMPONENT32F, size, size, 1); fbo.attach(DEPTH_ATTACHMENT, depth_buf, 0); fbo.require_complete(); @@ -101,6 +108,7 @@ void ShadowMap::render(Renderer &renderer, const Tag &tag) const int iunit = unit; shdata.uniform("shadow_map", iunit); + Bind _bind_sampler(*sampler, unit); Bind _bind_depth(depth_buf, unit); if(const Camera *camera = renderer.get_camera()) diff --git a/source/shadowmap.h b/source/shadowmap.h index fe36fca0..e142fc8c 100644 --- a/source/shadowmap.h +++ b/source/shadowmap.h @@ -27,12 +27,15 @@ private: Framebuffer fbo; Matrix shadow_matrix; Texture2D depth_buf; + RefPtr sampler; Vector3 target; float radius; float depth_bias; mutable ProgramData shdata; bool rendered; + static WeakPtr shadow_sampler; + public: ShadowMap(unsigned, Renderable &, const Light &); -- 2.43.0