Commit 44aaf0d7 authored by Johannes Braun's avatar Johannes Braun
Browse files

Added easer gbuffer post processing because reasons.

parent 640017d7
......@@ -3,12 +3,14 @@
#extension GL_ARB_shading_language_include : require
#extension GL_ARB_bindless_texture : require
sampler2DMS rgb_color_texture;
uniform sampler2DMS rgb_color_texture;
uniform uint u_sample_count;
uniform uint axis;
uniform int steps = 6;
uniform int skip = 1;
const float weights[4] = {2.0, 3.0, 2.0, 1.0};
const float weights[6] = {3.0, 5.0, 4.0, 3.0, 2.0, 1.0};
layout(location=0) out vec4 output_color;
......@@ -26,14 +28,17 @@ void main() {
{
vec4 color = vec4(0);
vec2 diff = axisVector(axis);
float factor = steps;
color += steps * texelFetch(rgb_color_texture, pixel, s);
for(int i=0; i<4; ++i)
for(int i=1; i<steps; ++i)
{
color += weights[i] * texelFetch(rgb_color_texture, ivec2(pixel + i*diff), s);
color += weights[i] * texelFetch(rgb_color_texture, ivec2(pixel - i*diff), s);
factor += 2 * (steps - i);
color += (steps - i) * texelFetch(rgb_color_texture, ivec2(pixel + skip*i*diff), s);
color += (steps - i) * texelFetch(rgb_color_texture, ivec2(pixel - skip*i*diff), s);
}
output_color += color/16.f;
output_color += color/factor;
}
output_color /= u_sample_count;
}
#version 430
#extension GL_ARB_shading_language_include : require
#extension GL_ARB_bindless_texture : require
uniform float cutoff = 0.8f;
uniform sampler2D source_texture;
layout(location=0) out vec4 output_color;
const vec3 luma = vec3(0.2126, 0.7152, 0.0722);
void main() {
ivec2 pixel = ivec2(gl_FragCoord.xy);
vec4 color = texelFetch(source_texture, pixel, 0);
float grayscale = dot(color.rgb, luma);
output_color = grayscale > cutoff ? color : vec4(0, 0, 0, 1);
}
......@@ -9,7 +9,7 @@
//in vec2 out_texcoord;
uniform sampler2D u_ssao_texture;
//uniform sampler2D u_ssao_texture;
uniform samplerCube environment;
uniform vec3 camera_position;
uniform mat4 u_view;
......@@ -89,5 +89,5 @@ void main()
out_final_color += final_color_part;
}
out_final_color /= u_samples;
out_final_color *= vec4(texelFetch(u_ssao_texture, pixel, 0).rgb, 1);
//out_final_color *= vec4(texelFetch(u_ssao_texture, pixel, 0).rgb, 1);
}
#version 430
#extension GL_ARB_shading_language_include : require
#extension GL_ARB_bindless_texture : require
uniform sampler2D texture_one;
uniform sampler2D texture_other;
layout(location=0) out vec4 output_color;
void main() {
ivec2 pixel = ivec2(gl_FragCoord.xy);
vec4 color1 = texelFetch(texture_one, pixel, 0);
vec4 color2 = texelFetch(texture_other, pixel, 0);
output_color = color1 + color2;
}
#version 430
#extension GL_ARB_shading_language_include : require
#extension GL_ARB_bindless_texture : require
uniform sampler2D texture_one;
uniform sampler2D texture_other;
layout(location=0) out vec4 output_color;
void main() {
ivec2 pixel = ivec2(gl_FragCoord.xy);
vec4 color1 = texelFetch(texture_one, pixel, 0);
vec4 color2 = texelFetch(texture_other, pixel, 0);
output_color = color1 * color2;
}
......@@ -9,8 +9,8 @@ uniform mat4 projection_matrix;
uniform float radius = 0.15f;
uniform float quality = 8;
sampler2DMS screen_space_positions;
sampler2DMS screen_space_normals;
uniform sampler2DMS screen_space_positions;
uniform sampler2DMS screen_space_normals;
uniform uint u_sample_count;
uniform vec2 screen_size;
......
......@@ -17,7 +17,7 @@ int main(int argc, char* argv[])
core::Context::createAsCurrent(files::asset("/preferences/default.xml"));
// Load a scene and attach it to the constant root
core::Context::current().graph()->attach(core::global_resources::scenes.get(files::asset("meshes/scenery/cbox.dae"), 1.0f));
core::Context::current().graph()->attach(core::global_resources::scenes.get(files::asset("meshes/scenery/House.dae"), 1.0f));
// Create a skybox
core::Context::current().skybox()->reset(files::asset("textures/ryfjallet/"));
......
......@@ -25,8 +25,10 @@ namespace glare::core
m_last_enable_scissor_test = gl::isEnabled(gl::EnableParameter::eScissorTest);
}
CaptureGlState::~CaptureGlState()
void CaptureGlState::release()
{
if (!m_released) m_released = true;
else return;
// Restore modified GL state
gl::useProgram(m_last_program);
gl::bindTexture(gl::TextureType::e2D, m_last_texture);
......@@ -42,4 +44,9 @@ namespace glare::core
gl::setEnabled(gl::EnableParameter::eScissorTest, m_last_enable_scissor_test);
gl::viewport(m_last_viewport[0], m_last_viewport[1], static_cast<unsigned>(m_last_viewport[2]), static_cast<unsigned>(m_last_viewport[3]));
}
CaptureGlState::~CaptureGlState()
{
release();
}
}
......@@ -8,8 +8,10 @@ namespace glare::core
public:
CaptureGlState();
~CaptureGlState();
void release();
private:
bool m_released = false;
int m_last_program = 0;
int m_last_texture = 0;
int m_last_array_buffer = 0;
......
......@@ -12,12 +12,12 @@ namespace glare::core
{
}
GBuffer::GBuffer(unsigned int width, unsigned int height, unsigned samples)
: GBuffer()
{
initialize(width, height, samples);
}
GBuffer::GBuffer(unsigned int width, unsigned int height, unsigned samples)
: GBuffer()
{
initialize(width, height, samples);
}
void GBuffer::initialize(unsigned width, unsigned height, unsigned samples)
{
m_width = width;
......@@ -36,10 +36,80 @@ namespace glare::core
m_gbuffer_framebuffer->attach(gl::Attachment::eColor5);
m_gbuffer_framebuffer->attach(gl::Attachment::eDepth);
m_temporary_framebuffer_01 = std::make_shared<Framebuffer>(static_cast<unsigned>(mode->width), static_cast<unsigned>(mode->height));
m_temporary_framebuffer_01->attach(gl::Attachment::eColor0);
m_temporary_framebuffer_02 = std::make_shared<Framebuffer>(static_cast<unsigned>(mode->width), static_cast<unsigned>(mode->height));
m_temporary_framebuffer_02->attach(gl::Attachment::eColor0);
m_composite_framebuffer = std::make_shared<Framebuffer>(static_cast<unsigned>(mode->width), static_cast<unsigned>(mode->height));
m_composite_framebuffer->attach(gl::Attachment::eColor0);
m_post_process = std::make_unique<PostProcess>(mode->width, mode->height);
m_post_process->render_passes.push_back({
[](const GBuffer& gbuffer, const Texture& composite_texture, PostProcess& post_process)
{
static auto ssao_renderer = TextureRenderer::make(files::shader("screenshader/ssao/ssao.frag"));
ssao_renderer->shader().uniform("projection_matrix", core::Context::current().camera()->projectionMatrix());
ssao_renderer->shader().uniform("screen_space_positions", gbuffer.framebuffer().attachment(gl::Attachment::eColor3).textureAddress());
ssao_renderer->shader().uniform("screen_space_normals", gbuffer.framebuffer().attachment(gl::Attachment::eColor5).textureAddress());
ssao_renderer->shader().uniform("u_gbuffer.depth", gbuffer.framebuffer().attachment(gl::Attachment::eDepth).textureAddress());
ssao_renderer->shader().uniform("screen_size", glm::vec2(gbuffer.width(), gbuffer.height()));
ssao_renderer->draw();
post_process.bufferSwap();
static auto blur_1d = TextureRenderer::make(files::shader("screenshader/blur/blur_1d.frag"));
blur_1d->shader().uniform("steps", 6);
blur_1d->shader().uniform("skip", 2);
blur_1d->shader().uniform("rgb_color_texture", post_process.currentBuffer().attachment(gl::Attachment::eColor0).textureAddress());
blur_1d->shader().uniform("axis", 0u);
blur_1d->draw();
post_process.bufferSwap();
blur_1d->shader().uniform("rgb_color_texture", post_process.currentBuffer().attachment(gl::Attachment::eColor0).textureAddress());
blur_1d->shader().uniform("axis", 1u);
blur_1d->draw();
post_process.bufferSwap();
static auto mult = TextureRenderer::make(files::shader("screenshader/op/mult.frag"));
mult->shader().uniform("texture_one", post_process.currentBuffer().attachment(gl::Attachment::eColor0).textureAddress());
mult->shader().uniform("texture_other", composite_texture.textureAddress());
mult->draw();
}
});
m_post_process->render_passes.push_back({
[](const GBuffer& gbuffer, const Texture& composite_texture, PostProcess& post_process)
{
static auto cutoff = TextureRenderer::make(files::shader("screenshader/cutoff/cutoff.frag"));
cutoff->shader().uniform("source_texture", composite_texture.textureAddress());
cutoff->shader().uniform("cutoff", 0.99f);
cutoff->draw();
post_process.bufferSwap();
static auto blur_1d = TextureRenderer::make(files::shader("screenshader/blur/blur_1d.frag"));
blur_1d->shader().uniform("steps", 8);
blur_1d->shader().uniform("skip", 2);
blur_1d->shader().uniform("rgb_color_texture", post_process.currentBuffer().attachment(gl::Attachment::eColor0).textureAddress());
blur_1d->shader().uniform("axis", 0u);
blur_1d->draw();
post_process.bufferSwap();
blur_1d->shader().uniform("rgb_color_texture", post_process.currentBuffer().attachment(gl::Attachment::eColor0).textureAddress());
blur_1d->shader().uniform("axis", 1u);
blur_1d->draw();
post_process.bufferSwap();
static auto add = TextureRenderer::make(files::shader("screenshader/op/add.frag"));
add->shader().uniform("texture_one", composite_texture.textureAddress());
add->shader().uniform("texture_other", post_process.currentBuffer().attachment(gl::Attachment::eColor0).textureAddress());
add->draw();
}
});
m_lights_buffer = std::make_unique<Buffer>();
......@@ -82,49 +152,24 @@ namespace glare::core
}
void GBuffer::draw() const
{
{
m_lights_buffer->upload<LightShadow>(core::Context::current().lights().get(), gl::BufferUsage::eDynamicDraw);
m_temporary_framebuffer_01->activate();
static auto ssao_renderer = TextureRenderer::make(files::shader("screenshader/ssao/ssao.frag"));
ssao_renderer->shader().uniform("projection_matrix", core::Context::current().camera()->projectionMatrix());
ssao_renderer->shader().uniform("screen_space_positions", m_gbuffer_framebuffer->attachment(gl::Attachment::eColor3).textureAddress());
ssao_renderer->shader().uniform("screen_space_normals", m_gbuffer_framebuffer->attachment(gl::Attachment::eColor5).textureAddress());
ssao_renderer->shader().uniform("u_gbuffer.depth", m_gbuffer_framebuffer->attachment(gl::Attachment::eDepth).textureAddress());
ssao_renderer->shader().uniform("screen_size", glm::vec2(m_width, m_height));
ssao_renderer->draw();
m_temporary_framebuffer_01->deactivate();
m_temporary_framebuffer_02->activate();
static auto blur_1d = TextureRenderer::make(files::shader("screenshader/blur/blur_1d.frag"));
blur_1d->shader().uniform("rgb_color_texture", m_temporary_framebuffer_01->attachment(gl::Attachment::eColor0).textureAddress());
blur_1d->shader().uniform("axis", 0u);
blur_1d->draw();
m_temporary_framebuffer_02->deactivate();
m_temporary_framebuffer_01->activate();
blur_1d->shader().uniform("rgb_color_texture", m_temporary_framebuffer_02->attachment(gl::Attachment::eColor0).textureAddress());
blur_1d->shader().uniform("axis", 1u);
blur_1d->draw();
m_temporary_framebuffer_01->deactivate();
deactivate();
m_composite_framebuffer->activate();
gl::setEnabled(gl::EnableParameter::eDepthTest, false);
m_texture_renderer->shader().use();
m_texture_renderer->shader().storageBuffer("lightsBuffer", *m_lights_buffer);
if (m_skybox->isInitialized())
m_texture_renderer->shader().uniform("environment", m_skybox->texture().textureAddress());
m_texture_renderer->shader().uniform("u_ssao_texture", m_temporary_framebuffer_01->attachment(gl::Attachment::eColor0).textureAddress());
if (m_skybox->isInitialized()) m_texture_renderer->shader().uniform("environment", m_skybox->texture().textureAddress());
m_texture_renderer->shader().uniform("u_view", core::Context::current().camera()->viewMatrix());
m_texture_renderer->shader().uniform("u_projection", core::Context::current().camera()->projectionMatrix());
m_texture_renderer->shader().uniform("camera_position", glm::vec3(core::Context::current().camera()->owner()->worldTransform().position));
m_texture_renderer->draw();
gl::setEnabled(gl::EnableParameter::eDepthTest, true);
m_composite_framebuffer->deactivate();
m_post_process->run(*this, m_composite_framebuffer->attachment(gl::Attachment::eColor0));
}
std::shared_ptr<Skybox> GBuffer::getSkybox() const
{
return m_skybox;
......@@ -140,6 +185,16 @@ namespace glare::core
return *m_gbuffer_framebuffer;
}
int GBuffer::width() const
{
return m_width;
}
int GBuffer::height() const
{
return m_height;
}
void GBuffer::updateSize(unsigned width, unsigned height)
{
updateSize(width, height, m_gbuffer_framebuffer->samples());
......
......@@ -8,7 +8,8 @@
#include <core/objects/skybox.h>
#include <core/objects/light.h>
#include "texture_renderer.h"
#include "texture_renderer.h"
#include "post_process.h"
namespace glare::core
{
......@@ -32,6 +33,8 @@ namespace glare::core
const Framebuffer& framebuffer() const;
int width() const;
int height() const;
void updateSize(unsigned width, unsigned height);
void updateSize(unsigned width, unsigned height, unsigned samples);
......@@ -45,8 +48,8 @@ namespace glare::core
std::vector<LightShadow> m_lights;
std::shared_ptr<Skybox> m_skybox;
std::shared_ptr<Framebuffer> m_gbuffer_framebuffer;
std::shared_ptr<Framebuffer> m_temporary_framebuffer_01;
std::shared_ptr<Framebuffer> m_temporary_framebuffer_02;
std::shared_ptr<Framebuffer> m_composite_framebuffer;
std::unique_ptr<PostProcess> m_post_process;
std::shared_ptr<TextureRenderer> m_texture_renderer;
};
}
......
#include "post_process.h"
#include "gbuffer.h"
#include <core/base/gl_state.h>
namespace glare::core
{
PostProcess::PostProcess(int initial_width, int initial_height)
{
m_framebuffers = {
std::make_unique<Framebuffer>(initial_width, initial_height),
std::make_unique<Framebuffer>(initial_width, initial_height)
};
m_renderbuffer = std::make_unique<Framebuffer>(initial_width, initial_height);
m_renderbuffer->attach(gl::Attachment::eColor0);
for (auto&& framebuffer : m_framebuffers)
framebuffer->attach(gl::Attachment::eColor0);
m_renderer = TextureRenderer::makeSimple();
}
void PostProcess::run(const core::GBuffer& gbuffer, const Texture& input)
{
CaptureGlState captured_state;
for(int i = 0; i < render_passes.size(); ++i)
{
auto&& pass = render_passes[i];
if(i==render_passes.size()-1)
{
// Last pass. Render to screen/last framebuffer before running PP.
bufferSwap();
pass.pass(gbuffer, render_passes.size() > 1 ? m_renderbuffer->attachment(gl::Attachment::eColor0) : input, *this);
bufferSwap();
activeBuffer().deactivate();
captured_state.release();
m_renderer->draw(currentBuffer().attachment(gl::Attachment::eColor0));
}
else
{
bufferSwap();
pass.pass(gbuffer, i != 0 ? m_renderbuffer->attachment(gl::Attachment::eColor0) : input, *this);
m_renderbuffer->activate();
m_renderer->draw(activeBuffer().attachment(gl::Attachment::eColor0));
bufferSwap();
}
}
}
void PostProcess::bufferSwap()
{
m_framebuffers[m_current_framebuffer]->activate();
m_current_framebuffer = (m_current_framebuffer + 1) % m_framebuffers.size();
}
const Framebuffer& PostProcess::activeBuffer() const
{
return *(m_framebuffers[(m_current_framebuffer - 1) % m_framebuffers.size()]);
}
const Framebuffer& PostProcess::currentBuffer() const
{
return *(m_framebuffers[m_current_framebuffer]);
}
}
#ifndef INCLUDE_POST_PROCESS_H
#define INCLUDE_POST_PROCESS_H
#include <functional>
#include <core/base/framebuffer.h>
#include <core/rendering/texture_renderer.h>
namespace glare::core
{
class GBuffer;
class PostProcess
{
public:
struct Pass;
PostProcess(int initial_width, int initial_height);
void run(const GBuffer&, const Texture& input);
void bufferSwap();
const Framebuffer& currentBuffer() const;
std::vector<Pass> render_passes;
private:
const Framebuffer& activeBuffer() const;
std::unique_ptr<TextureRenderer> m_renderer;
std::array<std::unique_ptr<Framebuffer>, 2> m_framebuffers;
std::unique_ptr<Framebuffer> m_renderbuffer;
int m_current_framebuffer = 0;
};
struct PostProcess::Pass
{
using PassFunction = std::function<void(const GBuffer& gbuffer, const Texture& composite_texture, PostProcess& post_process)>;
PassFunction pass;
};
}
#endif //!INCLUDE_POST_PROCESS_H
\ No newline at end of file
......@@ -35,7 +35,7 @@ namespace glare::raytrace
generate(collector, max_subdivisions, generator);
}
void Linespace::generate(const LocalCollector &collector, int max_subdivisions, const Platform generator = Platform::eCPU)
void Linespace::generate(const LocalCollector &collector, int max_subdivisions, const Platform generator)
{
generate(collector, 1, 0, max_subdivisions, generator);
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment