fix blur rendertask

This commit is contained in:
Green Sky 2020-10-01 23:01:45 +02:00
parent 95d1530c6d
commit 3c3afb1fcc
5 changed files with 148 additions and 50 deletions

View File

@ -108,7 +108,7 @@ uint32_t Shader::compile(uint32_t type, const std::string& source) {
glGetShaderiv(id, GL_INFO_LOG_LENGTH, &length);
char* msg = (char*) alloca(length * sizeof(char));
glGetShaderInfoLog(id, length, &length, msg);
LOG_ERROR("failed to compile {} Shader: {}", type == GL_VERTEX_SHADER ? "vertex" : "fragment", msg);
LOG_ERROR("failed to compile {} Shader: {}\n source: {}", type == GL_VERTEX_SHADER ? "vertex" : "fragment", msg, source);
return 0;
}

View File

@ -36,8 +36,10 @@ Blur::Blur(Engine& engine) {
_vao->unbind();
setupShaderFiles();
_shader = Shader::createF(engine, vertexPath, fragmentPath);
assert(_shader != nullptr);
_hShader = Shader::createF(engine, vertexPath, fragmentHPath);
assert(_hShader != nullptr);
_vShader = Shader::createF(engine, vertexPath, fragmentVPath);
assert(_vShader != nullptr);
}
Blur::~Blur(void) {
@ -46,33 +48,47 @@ Blur::~Blur(void) {
void Blur::render(Services::OpenGLRenderer& rs, Engine&) {
ZoneScopedN("MM::OpenGL::RenderTasks::Blur::render");
rs.targets[target_fbo]->bind(FrameBufferObject::W);
rs.targets[io_fbo]->bind(FrameBufferObject::W);
glDisable(GL_DEPTH_TEST);
glDisable(GL_BLEND); // TODO: test
_shader->bind();
_vertexBuffer->bind(GL_ARRAY_BUFFER);
_vao->bind();
auto& rm_t = MM::ResourceManager<MM::OpenGL::Texture>::ref();
auto tex_io = rm_t.get(entt::hashed_string::value(io_tex.c_str())); // TODO: perf problems
auto tex_temp = rm_t.get(entt::hashed_string::value(temp_tex.c_str())); // TODO: perf problems
rs.targets[src_fbo]->bind(FrameBufferObject::W);
{
_shader->setUniform1i("horizontal", 1);
rs.targets[src_fbo]->_texAttachments.front()->bind(0);
{ // horizontal
rs.targets[temp_fbo]->bind(FrameBufferObject::W);
_hShader->bind();
_vertexBuffer->bind(GL_ARRAY_BUFFER);
_vao->bind();
glViewport(0, 0, tex_temp->width, tex_temp->height);
tex_io->bind(0); // read
_hShader->setUniform2f("tex_offset", tex_offset);
glDrawArrays(GL_TRIANGLES, 0, 6);
}
rs.targets[target_fbo]->bind(FrameBufferObject::W);
{
_shader->setUniform1i("horizontal", 0);
{ // vertical
rs.targets[io_fbo]->bind(FrameBufferObject::W);
_vShader->bind();
_vertexBuffer->bind(GL_ARRAY_BUFFER);
_vao->bind();
glViewport(0, 0, tex_io->width, tex_io->height);
tex_temp->bind(0); // read
_vShader->setUniform2f("tex_offset", tex_offset);
glDrawArrays(GL_TRIANGLES, 0, 6);
}
_vao->unbind();
_vertexBuffer->unbind(GL_ARRAY_BUFFER);
_shader->unbind();
rs.targets[src_fbo]->clear(0.f, 0.f, 0.f, 1.f);
_vShader->unbind();
}
void Blur::setupShaderFiles(void) {
@ -84,14 +100,16 @@ R"(
#endif
in vec2 _vertexPosition;
out vec2 _tex;
out vec2 _tex_uv;
void main() {
gl_Position = vec4(_vertexPosition, 0, 1);
_tex = vec2(_vertexPosition.x * 0.5 + 0.5, _vertexPosition.y * 0.5 + 0.5);
_tex_uv = _vertexPosition * 0.5 + 0.5;
})")
FS_CONST_MOUNT_FILE(fragmentPath,
// TODO: deduplicate
FS_CONST_MOUNT_FILE(fragmentHPath,
GLSL_VERSION_STRING
R"(
#ifdef GL_ES
@ -99,35 +117,70 @@ R"(
#endif
uniform sampler2D tex0;
in vec2 _tex_uv;
in vec2 _tex;
uniform bool horizontal;
//uniform bool horizontal;
const bool horizontal = true;
uniform vec2 tex_offset;
const float weight[5] = float[] (0.227027, 0.1945946, 0.1216216, 0.054054, 0.016216);
out vec4 _out_color;
void main() {
vec2 tex_offset = vec2(1.0) / vec2(textureSize(tex0, 0)); // gets size of single texel
vec3 result = texture(tex0, _tex).rgb * weight[0]; // current fragment's contribution
//vec2 tex_offset = vec2(1.0) / vec2(textureSize(tex0, 0)); // gets size of single texel
vec3 result = texture(tex0, _tex_uv).rgb * weight[0]; // current fragment's contribution
if (horizontal) {
for (int i = 1; i < 5; i++) {
result += texture(tex0, _tex + vec2(tex_offset.x * float(i), 0.0)).rgb * weight[i];
result += texture(tex0, _tex - vec2(tex_offset.x * float(i), 0.0)).rgb * weight[i];
result += texture(tex0, _tex_uv + vec2(tex_offset.x * float(i), 0.0)).rgb * weight[i];
result += texture(tex0, _tex_uv - vec2(tex_offset.x * float(i), 0.0)).rgb * weight[i];
}
} else {
for (int i = 1; i < 5; i++) {
result += texture(tex0, _tex + vec2(0.0, tex_offset.y * float(i))).rgb * weight[i];
result += texture(tex0, _tex - vec2(0.0, tex_offset.y * float(i))).rgb * weight[i];
result += texture(tex0, _tex_uv + vec2(0.0, tex_offset.y * float(i))).rgb * weight[i];
result += texture(tex0, _tex_uv - vec2(0.0, tex_offset.y * float(i))).rgb * weight[i];
}
}
_out_color = vec4(result, 1.0);
})")
//float brightness = dot(gl_FragColor.rgb, vec3(0.2126, 0.7152, 0.0722));
//if (brightness > 1.0)
FS_CONST_MOUNT_FILE(fragmentVPath,
GLSL_VERSION_STRING
R"(
#ifdef GL_ES
precision mediump float;
#endif
uniform sampler2D tex0;
in vec2 _tex_uv;
//uniform bool horizontal;
const bool horizontal = false;
uniform vec2 tex_offset;
const float weight[5] = float[] (0.227027, 0.1945946, 0.1216216, 0.054054, 0.016216);
out vec4 _out_color;
void main() {
//vec2 tex_offset = vec2(1.0) / vec2(textureSize(tex0, 0)); // gets size of single texel
vec3 result = texture(tex0, _tex_uv).rgb * weight[0]; // current fragment's contribution
if (horizontal) {
for (int i = 1; i < 5; i++) {
result += texture(tex0, _tex_uv + vec2(tex_offset.x * float(i), 0.0)).rgb * weight[i];
result += texture(tex0, _tex_uv - vec2(tex_offset.x * float(i), 0.0)).rgb * weight[i];
}
} else {
for (int i = 1; i < 5; i++) {
result += texture(tex0, _tex_uv + vec2(0.0, tex_offset.y * float(i))).rgb * weight[i];
result += texture(tex0, _tex_uv - vec2(0.0, tex_offset.y * float(i))).rgb * weight[i];
}
}
_out_color = vec4(result, 1.0);
})")
}

View File

@ -3,6 +3,8 @@
#include "../render_task.hpp"
#include <mm/services/opengl_renderer.hpp>
#include <glm/vec2.hpp>
// fwd
namespace MM::OpenGL {
class Shader;
@ -12,9 +14,11 @@ namespace MM::OpenGL {
namespace MM::OpenGL::RenderTasks {
// this task expects to read and write to textures
class Blur : public RenderTask {
private:
std::shared_ptr<Shader> _shader;
std::shared_ptr<Shader> _hShader;
std::shared_ptr<Shader> _vShader;
std::unique_ptr<Buffer> _vertexBuffer;
std::unique_ptr<VertexArrayObject> _vao;
@ -26,10 +30,18 @@ namespace MM::OpenGL::RenderTasks {
public:
const char* vertexPath = "shader/blur_render_task/vert.glsl";
const char* fragmentPath = "shader/blur_render_task/frag.glsl";
const char* fragmentHPath = "shader/blur_render_task/frag_h.glsl";
const char* fragmentVPath = "shader/blur_render_task/frag_v.glsl";
std::string target_fbo = "blur_out";
std::string src_fbo = "blur_in";
std::string io_fbo = "blur_io";
std::string temp_fbo = "blur_temp";
// bc of it beeing a 2 pass, we need to flipflop
std::string io_tex = "blur_io";
std::string temp_tex = "blur_temp";
// determines the kernel lookup offset. "ideal" is 1/tex_size
glm::vec2 tex_offset {0.001f, 0.001f};
private:
void setupShaderFiles(void);

View File

@ -107,6 +107,8 @@ target_link_libraries(blur_render_task_test
simple_scene
simple_rect_render_task
blur_render_task
copy_to_fb_render_task
clear_render_task
imgui_service
imgui_render_task

View File

@ -1,3 +1,5 @@
#include "mm/opengl/render_tasks/clear.hpp"
#include "mm/opengl/render_tasks/copy_to_fb.hpp"
#include <gtest/gtest.h>
#include <mm/engine.hpp>
@ -20,6 +22,7 @@
#include <mm/systems/simple_velocity_system2d.hpp>
#include <mm/opengl/fbo_builder.hpp>
#include <mm/opengl/texture_loader.hpp>
#include <imgui/imgui.h>
@ -51,28 +54,56 @@ TEST(blur_render_task, it) {
auto& rs = engine.addService<MM::Services::OpenGLRenderer>();
ASSERT_TRUE(engine.enableService<MM::Services::OpenGLRenderer>());
rs.addRenderTask<MM::OpenGL::RenderTasks::SimpleRect>(engine).target_fbo = "game_view";
//rs.addRenderTask<MM::OpenGL::RenderTasks::SimpleRect>(engine).target_fbo = "game_view";
MM::OpenGL::RenderTasks::SimpleRect* bsrr_rend_ptr = &rs.addRenderTask<MM::OpenGL::RenderTasks::SimpleRect>(engine);
bsrr_rend_ptr->target_fbo = "blur_in";
rs.addRenderTask<MM::OpenGL::RenderTasks::Clear>(engine).target_fbo = "blur_io";
MM::OpenGL::RenderTasks::Blur* blur_rend_ptr = &rs.addRenderTask<MM::OpenGL::RenderTasks::Blur>(engine);
blur_rend_ptr->target_fbo = "display";
MM::OpenGL::RenderTasks::SimpleRect& bsrr_rend = rs.addRenderTask<MM::OpenGL::RenderTasks::SimpleRect>(engine);
bsrr_rend.target_fbo = "blur_io";
MM::OpenGL::RenderTasks::Blur& blur_rend = rs.addRenderTask<MM::OpenGL::RenderTasks::Blur>(engine);
blur_rend.io_tex = "blur_io";
blur_rend.temp_tex = "blur_temp";
blur_rend.io_fbo = "blur_io";
blur_rend.temp_fbo = "blur_temp";
// render to display
auto& ctfb = rs.addRenderTask<MM::OpenGL::RenderTasks::CopyToFB>(engine);
ctfb.src_tex = "blur_io";
ctfb.target_fbo = "display";
rs.addRenderTask<MM::OpenGL::RenderTasks::ImGuiRT>(engine);
auto [w, h] = sdl_ss.getWindowSize();
auto& rm_t = MM::ResourceManager<MM::OpenGL::Texture>::ref();
{ // setup textures
rm_t.load<MM::OpenGL::TextureLoaderEmpty>(
"blur_io",
GL_RGB,
w, h,
GL_RGB, GL_UNSIGNED_BYTE
);
{
auto [w, h] = sdl_ss.getWindowSize();
rm_t.load<MM::OpenGL::TextureLoaderEmpty>(
"blur_temp",
GL_RGB,
w, h,
GL_RGB, GL_UNSIGNED_BYTE
);
}
rs.targets["game_view"] = MM::OpenGL::FBOBuilder::start()
.attachTexture(MM::OpenGL::Texture::createEmpty(GL_RGB, w, h, GL_RGB, GL_UNSIGNED_BYTE))
{ // setup fbo s
//rs.targets["game_view"] = MM::OpenGL::FBOBuilder::start()
//.attachTexture(MM::OpenGL::Texture::createEmpty(GL_RGB, w, h, GL_RGB, GL_UNSIGNED_BYTE))
//.finish();
rs.targets["blur_io"] = MM::OpenGL::FBOBuilder::start()
.attachTexture(rm_t.get("blur_io"_hs))
.setResize(true)
.finish();
rs.targets["blur_in"] = MM::OpenGL::FBOBuilder::start()
.attachTexture(MM::OpenGL::Texture::createEmpty(GL_RGB, w, h, GL_RGB, GL_UNSIGNED_BYTE))
.finish();
rs.targets["blur_out"] = MM::OpenGL::FBOBuilder::start()
.attachTexture(MM::OpenGL::Texture::createEmpty(GL_RGB, w, h, GL_RGB, GL_UNSIGNED_BYTE))
rs.targets["blur_temp"] = MM::OpenGL::FBOBuilder::start()
.attachTexture(rm_t.get("blur_temp"_hs))
.setResize(true)
.finish();
}
@ -103,7 +134,7 @@ TEST(blur_render_task, it) {
engine.addUpdate(
[&](MM::Engine&) {
ImGui::ColorEdit4("rect_col", &bsrr_rend_ptr->default_color[0]);
ImGui::ColorEdit4("rect_col", &bsrr_rend.default_color[0]);
}
);