fixes, configurable framebuffers quality

This commit is contained in:
milek7
2018-10-14 21:52:37 +02:00
parent d8b902a364
commit dd0a9b1d77
24 changed files with 289 additions and 141 deletions

View File

@@ -668,12 +668,12 @@ global_settings::ConfigParse(cParser &Parser) {
else if (token == "gfx.framebuffer.width")
{
Parser.getTokens(1, false);
Parser >> render_width;
Parser >> gfx_framebuffer_width;
}
else if (token == "gfx.framebuffer.height")
{
Parser.getTokens(1, false);
Parser >> render_height;
Parser >> gfx_framebuffer_height;
}
else if (token == "gfx.shadowmap.enabled")
{
@@ -695,6 +695,49 @@ global_settings::ConfigParse(cParser &Parser) {
Parser.getTokens(1);
Parser >> gfx_postfx_motionblur_shutter;
}
else if (token == "gfx.postfx.motionblur.format")
{
Parser.getTokens(1);
std::string token;
Parser >> token;
if (token == "rg16f")
gfx_postfx_motionblur_format = GL_RG16F;
else if (token == "rg32f")
gfx_postfx_motionblur_format = GL_RG32F;
}
else if (token == "gfx.format.color")
{
Parser.getTokens(1);
std::string token;
Parser >> token;
if (token == "rgb8")
gfx_format_color = GL_RGB8;
else if (token == "rgb16f")
gfx_format_color = GL_RGB16F;
else if (token == "rgb32f")
gfx_format_color = GL_RGB32F;
else if (token == "r11f_g11f_b10f")
gfx_format_color = GL_R11F_G11F_B10F;
}
else if (token == "gfx.format.depth")
{
Parser.getTokens(1);
std::string token;
Parser >> token;
if (token == "z16")
gfx_format_depth = GL_DEPTH_COMPONENT16;
else if (token == "z24")
gfx_format_depth = GL_DEPTH_COMPONENT24;
else if (token == "z32")
gfx_format_depth = GL_DEPTH_COMPONENT32;
else if (token == "z32f")
gfx_format_depth = GL_DEPTH_COMPONENT32F;
}
else if (token == "gfx.skippipeline")
{
Parser.getTokens(1);
Parser >> gfx_skippipeline;
}
else if (token == "map.enabled")
{
Parser.getTokens(1);

View File

@@ -100,8 +100,7 @@ struct global_settings {
// gfx
int iWindowWidth{ 800 };
int iWindowHeight{ 600 };
int render_width = -1;
int render_height = -1;
float fDistanceFactor{ iWindowHeight / 768.f }; // baza do przeliczania odległości dla LoD
bool bFullScreen{ false };
bool VSync{ false };
@@ -177,10 +176,16 @@ struct global_settings {
bool dds_upper_origin = false;
bool captureonstart = true;
int gfx_framebuffer_width = -1;
int gfx_framebuffer_height = -1;
bool gfx_shadowmap_enabled = true;
bool gfx_envmap_enabled = true;
bool gfx_postfx_motionblur_enabled = true;
float gfx_postfx_motionblur_shutter = 0.01f;
GLenum gfx_postfx_motionblur_format = GL_RG16F;
GLenum gfx_format_color = GL_RGB16F;
GLenum gfx_format_depth = GL_DEPTH_COMPONENT32F;
bool gfx_skippipeline = false;
bool map_enabled = true;

View File

@@ -27,20 +27,13 @@ void render_task::run() {
if( output != nullptr ) {
auto *outputwidth { PyObject_CallMethod( m_renderer, "get_width", nullptr ) };
auto *outputheight { PyObject_CallMethod( m_renderer, "get_height", nullptr ) };
opengl_texture &tex = GfxRenderer.Texture( m_target );
// upload texture data
if( ( outputwidth != nullptr )
&& ( outputheight != nullptr ) ) {
&& ( outputheight != nullptr )
&& tex.id != -1) {
::glBindTexture( GL_TEXTURE_2D, tex.id );
::glBindTexture( GL_TEXTURE_2D, GfxRenderer.Texture( m_target ).id );
// setup texture parameters
::glTexParameteri( GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE );
::glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
::glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR );
if( GLEW_EXT_texture_filter_anisotropic ) {
// anisotropic filtering
::glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, Global.AnisotropicFiltering );
}
::glTexEnvf( GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, -1.0 );
// build texture
glTexImage2D(
GL_TEXTURE_2D, 0,
@@ -76,6 +69,8 @@ auto python_taskqueue::init() -> bool {
Py_Initialize();
PyEval_InitThreads();
m_initialized = true;
PyObject *stringiomodule { nullptr };
PyObject *stringioclassname { nullptr };
PyObject *stringioobject { nullptr };
@@ -133,12 +128,16 @@ release_and_exit:
// shuts down the module
void python_taskqueue::exit() {
if (!m_initialized)
return;
// let the workers know we're done with them
m_exit = true;
m_condition.notify_all();
// let them free up their shit before we proceed
for( auto const &worker : m_workers ) {
worker->join();
if (worker)
worker->join();
}
// get rid of the leftover tasks
// with the workers dead we don't have to worry about concurrent access anymore

View File

@@ -93,6 +93,7 @@ private:
std::atomic<bool> m_exit { false }; // signals the workers to quit
std::unordered_map<std::string, PyObject *> m_renderers; // cache of python classes
rendertask_sequence m_tasks;
bool m_initialized { false };
};
#endif

View File

@@ -747,7 +747,7 @@ opengl_texture::create() {
glTexParameterfv(target, GL_TEXTURE_BORDER_COLOR, borderColor);
}
if (target == GL_TEXTURE_2D)
glTexImage2D(target, 0, data_format, data_width, data_height, 0, data_components, data_type, nullptr);
glTexImage2D(target, 0, data_format, data_width, data_height, 0, data_components, GL_BYTE, nullptr);
else if (target == GL_TEXTURE_2D_MULTISAMPLE)
glTexImage2DMultisample(target, samples, data_format, data_width, data_height, GL_FALSE);
}
@@ -867,13 +867,12 @@ opengl_texture::release() {
return;
}
void opengl_texture::alloc_rendertarget(GLint format, GLint components, GLint type, int width, int height, int s)
void opengl_texture::alloc_rendertarget(GLint format, GLint components, int width, int height, int s)
{
data_width = width;
data_height = height;
data_format = format;
data_components = components;
data_type = type;
data_mapcount = 1;
is_rendertarget = true;
samples = s;

View File

@@ -43,7 +43,7 @@ struct opengl_texture {
height() const {
return data_height; }
void alloc_rendertarget(GLint format, GLint components, GLint type, int width, int height, int samples = 1);
void alloc_rendertarget(GLint format, GLint components, int width, int height, int samples = 1);
void set_components_hint(GLint hint);
static void reset_unit_cache();

View File

@@ -5,7 +5,7 @@ namespace gl
template <typename T>
class bindable
{
private:
protected:
static bindable<T>* active;
public:

View File

@@ -8,6 +8,7 @@ void gl::glsl_common_setup()
"#define SHADOWMAP_ENABLED " + std::to_string((int)Global.gfx_shadowmap_enabled) + "\n" +
"#define ENVMAP_ENABLED " + std::to_string((int)Global.gfx_envmap_enabled) + "\n" +
"#define MOTIONBLUR_ENABLED " + std::to_string((int)Global.gfx_postfx_motionblur_enabled) + "\n" +
"#define POSTFX_ENABLED " + std::to_string((int)!Global.gfx_skippipeline) + "\n" +
"const uint MAX_LIGHTS = " + std::to_string(MAX_LIGHTS) + "U;\n" +
"const uint MAX_PARAMS = " + std::to_string(MAX_PARAMS) + "U;\n" +
R"STRING(

View File

@@ -13,6 +13,7 @@ gl::ubo::ubo(int size, int idx, GLenum hint)
void gl::ubo::bind_uniform()
{
glBindBufferBase(GL_UNIFORM_BUFFER, index, *this);
active = this;
}
gl::ubo::~ubo()

View File

@@ -175,59 +175,63 @@ bool opengl_renderer::Init(GLFWwindow *Window)
int samples = 1 << Global.iMultisampling;
if (samples > 1)
glEnable(GL_MULTISAMPLE);
m_msaa_rbc = std::make_unique<gl::renderbuffer>();
m_msaa_rbc->alloc(GL_RGB16F, Global.render_width, Global.render_height, samples);
m_msaa_rbd = std::make_unique<gl::renderbuffer>();
m_msaa_rbd->alloc(GL_DEPTH_COMPONENT32F, Global.render_width, Global.render_height, samples);
m_msaa_fb = std::make_unique<gl::framebuffer>();
m_msaa_fb->attach(*m_msaa_rbc, GL_COLOR_ATTACHMENT0);
m_msaa_fb->attach(*m_msaa_rbd, GL_DEPTH_ATTACHMENT);
if (Global.gfx_postfx_motionblur_enabled)
if (!Global.gfx_skippipeline)
{
m_msaa_rbv = std::make_unique<gl::renderbuffer>();
m_msaa_rbv->alloc(GL_RG16F, Global.render_width, Global.render_height, samples);
m_msaa_fb->attach(*m_msaa_rbv, GL_COLOR_ATTACHMENT1);
m_msaa_rbc = std::make_unique<gl::renderbuffer>();
m_msaa_rbc->alloc(Global.gfx_format_color, Global.gfx_framebuffer_width, Global.gfx_framebuffer_height, samples);
m_main_tex = std::make_unique<opengl_texture>();
m_main_tex->alloc_rendertarget(GL_RGB16F, GL_RGB, GL_FLOAT, Global.render_width, Global.render_height);
m_msaa_rbd = std::make_unique<gl::renderbuffer>();
m_msaa_rbd->alloc(Global.gfx_format_depth, Global.gfx_framebuffer_width, Global.gfx_framebuffer_height, samples);
m_main_fb = std::make_unique<gl::framebuffer>();
m_main_fb->attach(*m_main_tex, GL_COLOR_ATTACHMENT0);
m_msaa_fb = std::make_unique<gl::framebuffer>();
m_msaa_fb->attach(*m_msaa_rbc, GL_COLOR_ATTACHMENT0);
m_msaa_fb->attach(*m_msaa_rbd, GL_DEPTH_ATTACHMENT);
m_main_texv = std::make_unique<opengl_texture>();
m_main_texv->alloc_rendertarget(GL_RG16F, GL_RG, GL_FLOAT, Global.render_width, Global.render_height);
m_main_fb->attach(*m_main_texv, GL_COLOR_ATTACHMENT1);
m_main_fb->setup_drawing(2);
if (Global.gfx_postfx_motionblur_enabled)
{
m_msaa_rbv = std::make_unique<gl::renderbuffer>();
m_msaa_rbv->alloc(Global.gfx_postfx_motionblur_format, Global.gfx_framebuffer_width, Global.gfx_framebuffer_height, samples);
m_msaa_fb->attach(*m_msaa_rbv, GL_COLOR_ATTACHMENT1);
if (!m_main_fb->is_complete())
m_main_tex = std::make_unique<opengl_texture>();
m_main_tex->alloc_rendertarget(Global.gfx_format_color, GL_RGB, Global.gfx_framebuffer_width, Global.gfx_framebuffer_height);
m_main_fb = std::make_unique<gl::framebuffer>();
m_main_fb->attach(*m_main_tex, GL_COLOR_ATTACHMENT0);
m_main_texv = std::make_unique<opengl_texture>();
m_main_texv->alloc_rendertarget(Global.gfx_postfx_motionblur_format, GL_RG, Global.gfx_framebuffer_width, Global.gfx_framebuffer_height);
m_main_fb->attach(*m_main_texv, GL_COLOR_ATTACHMENT1);
m_main_fb->setup_drawing(2);
if (!m_main_fb->is_complete())
return false;
m_pfx_motionblur = std::make_unique<gl::postfx>("motionblur");
WriteLog("motion blur enabled");
}
if (!m_msaa_fb->is_complete())
return false;
m_pfx_motionblur = std::make_unique<gl::postfx>("motionblur");
m_main2_tex = std::make_unique<opengl_texture>();
m_main2_tex->alloc_rendertarget(Global.gfx_format_color, GL_RGB, Global.gfx_framebuffer_width, Global.gfx_framebuffer_height);
WriteLog("motion blur enabled");
m_main2_fb = std::make_unique<gl::framebuffer>();
m_main2_fb->attach(*m_main2_tex, GL_COLOR_ATTACHMENT0);
if (!m_main2_fb->is_complete())
return false;
m_pfx_tonemapping = std::make_unique<gl::postfx>("tonemapping");
}
if (!m_msaa_fb->is_complete())
return false;
m_main2_tex = std::make_unique<opengl_texture>();
m_main2_tex->alloc_rendertarget(GL_RGB16F, GL_RGB, GL_FLOAT, Global.render_width, Global.render_height);
m_main2_fb = std::make_unique<gl::framebuffer>();
m_main2_fb->attach(*m_main2_tex, GL_COLOR_ATTACHMENT0);
if (!m_main2_fb->is_complete())
return false;
m_pfx_tonemapping = std::make_unique<gl::postfx>("tonemapping");
if (Global.gfx_shadowmap_enabled)
{
m_shadow_fb = std::make_unique<gl::framebuffer>();
m_shadow_tex = std::make_unique<opengl_texture>();
m_shadow_tex->alloc_rendertarget(GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, GL_FLOAT, m_shadowbuffersize, m_shadowbuffersize);
m_shadow_tex->alloc_rendertarget(Global.gfx_format_depth, GL_DEPTH_COMPONENT, m_shadowbuffersize, m_shadowbuffersize);
m_shadow_fb->attach(*m_shadow_tex, GL_DEPTH_ATTACHMENT);
if (!m_shadow_fb->is_complete())
@@ -235,7 +239,7 @@ bool opengl_renderer::Init(GLFWwindow *Window)
m_cabshadows_fb = std::make_unique<gl::framebuffer>();
m_cabshadows_tex = std::make_unique<opengl_texture>();
m_cabshadows_tex->alloc_rendertarget(GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, GL_FLOAT, m_shadowbuffersize, m_shadowbuffersize);
m_cabshadows_tex->alloc_rendertarget(Global.gfx_format_depth, GL_DEPTH_COMPONENT, m_shadowbuffersize, m_shadowbuffersize);
m_cabshadows_fb->attach(*m_cabshadows_tex, GL_DEPTH_ATTACHMENT);
if (!m_cabshadows_fb->is_complete())
@@ -245,9 +249,9 @@ bool opengl_renderer::Init(GLFWwindow *Window)
}
m_pick_tex = std::make_unique<opengl_texture>();
m_pick_tex->alloc_rendertarget(GL_RGB8, GL_RGB, GL_UNSIGNED_BYTE, EU07_PICKBUFFERSIZE, EU07_PICKBUFFERSIZE);
m_pick_tex->alloc_rendertarget(GL_RGB8, GL_RGB, EU07_PICKBUFFERSIZE, EU07_PICKBUFFERSIZE);
m_pick_rb = std::make_unique<gl::renderbuffer>();
m_pick_rb->alloc(GL_DEPTH_COMPONENT32F, EU07_PICKBUFFERSIZE, EU07_PICKBUFFERSIZE);
m_pick_rb->alloc(Global.gfx_format_depth, EU07_PICKBUFFERSIZE, EU07_PICKBUFFERSIZE);
m_pick_fb = std::make_unique<gl::framebuffer>();
m_pick_fb->attach(*m_pick_tex, GL_COLOR_ATTACHMENT0);
m_pick_fb->attach(*m_pick_rb, GL_DEPTH_ATTACHMENT);
@@ -258,11 +262,11 @@ bool opengl_renderer::Init(GLFWwindow *Window)
if (Global.gfx_envmap_enabled)
{
m_env_rb = std::make_unique<gl::renderbuffer>();
m_env_rb->alloc(GL_DEPTH_COMPONENT32F, gl::ENVMAP_SIZE, gl::ENVMAP_SIZE);
m_env_rb->alloc(Global.gfx_format_depth, gl::ENVMAP_SIZE, gl::ENVMAP_SIZE);
m_env_tex = std::make_unique<gl::cubemap>();
m_env_tex->alloc(GL_RGB16F, gl::ENVMAP_SIZE, gl::ENVMAP_SIZE, GL_RGB, GL_FLOAT);
m_env_tex->alloc(Global.gfx_format_color, gl::ENVMAP_SIZE, gl::ENVMAP_SIZE, GL_RGB, GL_FLOAT);
m_empty_cubemap = std::make_unique<gl::cubemap>();
m_empty_cubemap->alloc(GL_RGB16F, 16, 16, GL_RGB, GL_FLOAT);
m_empty_cubemap->alloc(Global.gfx_format_color, 16, 16, GL_RGB, GL_FLOAT);
m_env_fb = std::make_unique<gl::framebuffer>();
@@ -423,19 +427,29 @@ void opengl_renderer::Render_pass(rendermode const Mode)
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
// setup
m_msaa_fb->bind();
if (!Global.gfx_skippipeline)
{
m_msaa_fb->bind();
if (Global.gfx_postfx_motionblur_enabled)
m_msaa_fb->setup_drawing(2);
if (Global.gfx_postfx_motionblur_enabled)
m_msaa_fb->setup_drawing(2);
else
m_msaa_fb->setup_drawing(1);
glViewport(0, 0, Global.gfx_framebuffer_width, Global.gfx_framebuffer_height);
m_msaa_fb->clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}
else
m_msaa_fb->setup_drawing(1);
{
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glEnable(GL_FRAMEBUFFER_SRGB);
glViewport(0, 0, Global.iWindowWidth, Global.iWindowHeight);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}
glViewport(0, 0, Global.render_width, Global.render_height);
glEnable(GL_DEPTH_TEST);
m_msaa_fb->clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
setup_matrices();
setup_drawing(true);
@@ -511,27 +525,31 @@ void opengl_renderer::Render_pass(rendermode const Mode)
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
if (Global.gfx_postfx_motionblur_enabled)
if (!Global.gfx_skippipeline)
{
m_main_fb->clear(GL_COLOR_BUFFER_BIT);
m_msaa_fb->blit_to(*m_main_fb.get(), Global.render_width, Global.render_height, GL_COLOR_BUFFER_BIT, GL_COLOR_ATTACHMENT0);
m_msaa_fb->blit_to(*m_main_fb.get(), Global.render_width, Global.render_height, GL_COLOR_BUFFER_BIT, GL_COLOR_ATTACHMENT1);
if (Global.gfx_postfx_motionblur_enabled)
{
m_main_fb->clear(GL_COLOR_BUFFER_BIT);
m_msaa_fb->blit_to(*m_main_fb.get(), Global.gfx_framebuffer_width, Global.gfx_framebuffer_height, GL_COLOR_BUFFER_BIT, GL_COLOR_ATTACHMENT0);
m_msaa_fb->blit_to(*m_main_fb.get(), Global.gfx_framebuffer_width, Global.gfx_framebuffer_height, GL_COLOR_BUFFER_BIT, GL_COLOR_ATTACHMENT1);
model_ubs.param[0].x = m_framerate / (1.0 / Global.gfx_postfx_motionblur_shutter);
model_ubo->update(model_ubs);
m_pfx_motionblur->apply({m_main_tex.get(), m_main_texv.get()}, m_main2_fb.get());
}
else
{
m_main2_fb->clear(GL_COLOR_BUFFER_BIT);
m_msaa_fb->blit_to(*m_main2_fb.get(), Global.render_width, Global.render_height, GL_COLOR_BUFFER_BIT, GL_COLOR_ATTACHMENT0);
model_ubs.param[0].x = m_framerate / (1.0 / Global.gfx_postfx_motionblur_shutter);
model_ubo->update(model_ubs);
m_pfx_motionblur->apply({m_main_tex.get(), m_main_texv.get()}, m_main2_fb.get());
}
else
{
m_main2_fb->clear(GL_COLOR_BUFFER_BIT);
m_msaa_fb->blit_to(*m_main2_fb.get(), Global.gfx_framebuffer_width, Global.gfx_framebuffer_height, GL_COLOR_BUFFER_BIT, GL_COLOR_ATTACHMENT0);
}
glEnable(GL_FRAMEBUFFER_SRGB);
glViewport(0, 0, Global.iWindowWidth, Global.iWindowHeight);
m_pfx_tonemapping->apply(*m_main2_tex, nullptr);
opengl_texture::reset_unit_cache();
}
glEnable(GL_FRAMEBUFFER_SRGB);
glViewport(0, 0, Global.iWindowWidth, Global.iWindowHeight);
m_pfx_tonemapping->apply(*m_main2_tex, nullptr);
opengl_texture::reset_unit_cache();
glDisable(GL_FRAMEBUFFER_SRGB);
glDisable(GL_FRAMEBUFFER_SRGB);
glDebug("uilayer render");
Application.render_ui();
@@ -3488,7 +3506,7 @@ void opengl_renderer::Update_Lights(light_array &Lights)
else
model_ubs.fog_density = 0.0f;
model_ubo->update(model_ubs);
model_ubo->update(model_ubs);
light_ubo->update(light_ubs);
}
@@ -3560,12 +3578,12 @@ bool opengl_renderer::Init_caps()
WriteLog("using multisampling x" + std::to_string(1 << Global.iMultisampling));
}
if (Global.render_width == -1)
Global.render_width = Global.iWindowWidth;
if (Global.render_height == -1)
Global.render_height = Global.iWindowHeight;
if (Global.gfx_framebuffer_width == -1)
Global.gfx_framebuffer_width = Global.iWindowWidth;
if (Global.gfx_framebuffer_height == -1)
Global.gfx_framebuffer_height = Global.iWindowHeight;
WriteLog("rendering at " + std::to_string(Global.render_width) + "x" + std::to_string(Global.render_height));
WriteLog("rendering at " + std::to_string(Global.gfx_framebuffer_width) + "x" + std::to_string(Global.gfx_framebuffer_height));
return true;
}

View File

@@ -7,11 +7,16 @@ in vec2 f_coord;
uniform sampler2D tex1;
#include <common>
#include <tonemapping.glsl>
void main()
{
vec4 tex_color = texture(tex1, f_coord);
#if POSTFX_ENABLED
gl_FragData[0] = tex_color * param[0];
#else
gl_FragData[0] = tonemap(tex_color * param[0]);
#endif
#if MOTIONBLUR_ENABLED
gl_FragData[1] = vec4(0.0f);
#endif

View File

@@ -3,10 +3,15 @@
in vec3 f_color;
#include <common>
#include <tonemapping.glsl>
void main()
{
#if POSTFX_ENABLED
gl_FragData[0] = vec4(f_color, 1.0f);
#else
gl_FragData[0] = tonemap(vec4(f_color, 1.0f));
#endif
#if MOTIONBLUR_ENABLED
gl_FragData[1] = vec4(0.0f);
#endif

View File

@@ -1,6 +1,7 @@
#version 330
#include <common>
#include <tonemapping.glsl>
in vec4 f_clip_pos;
in vec4 f_clip_future_pos;
@@ -12,7 +13,12 @@ void main()
float dist = sqrt(x * x + y * y);
if (dist > 0.5f)
discard;
gl_FragData[0] = vec4(param[0].rgb * emission, mix(param[0].a, 0.0f, dist * 2.0f));
vec4 color = vec4(param[0].rgb * emission, mix(param[0].a, 0.0f, dist * 2.0f));
#if POSTFX_ENABLED
gl_FragData[0] = color;
#else
gl_FragData[0] = tonemap(color);
#endif
#if MOTIONBLUR_ENABLED
{
vec2 a = (f_clip_future_pos.xy / f_clip_future_pos.w) * 0.5 + 0.5;;

View File

@@ -8,11 +8,16 @@ in vec4 f_pos;
uniform sampler2D tex1;
#include <common>
#include <tonemapping.glsl>
void main()
{
vec4 tex_color = texture(tex1, f_coord);
#if POSTFX_ENABLED
gl_FragData[0] = tex_color * param[0];
#else
gl_FragData[0] = tonemap(tex_color * param[0]);
#endif
#if MOTIONBLUR_ENABLED
gl_FragData[1] = vec4(0.0f);
#endif

View File

@@ -24,6 +24,7 @@ uniform samplerCube envmap;
#endif
#include <light_common.glsl>
#include <tonemapping.glsl>
void main()
{
@@ -61,7 +62,12 @@ void main()
result += light.color * (part.x * param[1].x + part.y * param[1].y);
}
gl_FragData[0] = vec4(apply_fog(result * tex_color.rgb), tex_color.a * alpha_mult);
vec4 color = vec4(apply_fog(result * tex_color.rgb), tex_color.a * alpha_mult);
#if POSTFX_ENABLED
gl_FragData[0] = color;
#else
gl_FragData[0] = tonemap(color);
#endif
#if MOTIONBLUR_ENABLED
{
vec2 a = (f_clip_future_pos.xy / f_clip_future_pos.w) * 0.5 + 0.5;;

View File

@@ -27,6 +27,7 @@ uniform samplerCube envmap;
#endif
#include <light_common.glsl>
#include <tonemapping.glsl>
void main()
{
@@ -67,7 +68,12 @@ void main()
result += light.color * (part.x * param[1].x + part.y * param[1].y);
}
gl_FragData[0] = vec4(apply_fog(result * tex_color.rgb), tex_color.a * alpha_mult);
vec4 color = vec4(apply_fog(result * tex_color.rgb), tex_color.a * alpha_mult);
#if POSTFX_ENABLED
gl_FragData[0] = color;
#else
gl_FragData[0] = tonemap(color);
#endif
#if MOTIONBLUR_ENABLED
{

View File

@@ -1,10 +1,16 @@
#version 330
#include <common>
#include <tonemapping.glsl>
void main()
{
gl_FragData[0] = vec4(1.0, 0.0, 1.0, 1.0);
vec4 color = vec4(1.0, 0.0, 1.0, 1.0);
#if POSTFX_ENABLED
gl_FragData[0] = color;
#else
gl_FragData[0] = tonemap(color);
#endif
#if MOTIONBLUR_ENABLED
gl_FragData[1] = vec4(0.0f);
#endif

View File

@@ -32,6 +32,7 @@ uniform samplerCube envmap;
#define NORMALMAP
#include <light_common.glsl>
#include <tonemapping.glsl>
void main()
{
@@ -72,8 +73,12 @@ void main()
result += light.color * (part.x * param[1].x + part.y * param[1].y);
}
gl_FragData[0] = vec4(apply_fog(result * tex_color.rgb), tex_color.a * alpha_mult);
vec4 color = vec4(apply_fog(result * tex_color.rgb), tex_color.a * alpha_mult);
#if POSTFX_ENABLED
gl_FragData[0] = color;
#else
gl_FragData[0] = tonemap(color);
#endif
#if MOTIONBLUR_ENABLED
{
vec2 a = (f_clip_future_pos.xy / f_clip_future_pos.w) * 0.5 + 0.5;;

View File

@@ -30,6 +30,7 @@ uniform samplerCube envmap;
#endif
#include <light_common.glsl>
#include <tonemapping.glsl>
void main()
{
@@ -70,8 +71,12 @@ void main()
result += light.color * (part.x * param[1].x + part.y * param[1].y);
}
gl_FragData[0] = vec4(apply_fog(result * tex_color.rgb), tex_color.a * alpha_mult);
vec4 color = vec4(apply_fog(result * tex_color.rgb), tex_color.a * alpha_mult);
#if POSTFX_ENABLED
gl_FragData[0] = color;
#else
gl_FragData[0] = tonemap(color);
#endif
#if MOTIONBLUR_ENABLED
{
vec2 a = (f_clip_future_pos.xy / f_clip_future_pos.w) * 0.5 + 0.5;;

View File

@@ -1,6 +1,7 @@
#version 330
#include <common>
#include <tonemapping.glsl>
flat in vec3 f_normal_raw;
@@ -12,8 +13,13 @@ void main()
if (dist2 > 0.5f * 0.5f)
discard;
// color data is shared with normals, ugh
gl_FragData[0] = vec4(f_normal_raw.bgr, 1.0f);
// color data space is shared with normals, ugh
vec4 color = vec4(pow(f_normal_raw.bgr, vec3(2.2)), 1.0f);
#if POSTFX_ENABLED
gl_FragData[0] = color;
#else
gl_FragData[0] = tonemap(color);
#endif
#if MOTIONBLUR_ENABLED
gl_FragData[1] = vec4(0.0f);
#endif

View File

@@ -6,44 +6,13 @@ in vec2 f_coords;
#texture (tex1, 0, RGB)
uniform sampler2D tex1;
vec3 reinhard(vec3 x)
{
return x / (x + vec3(1.0));
}
// https://knarkowicz.wordpress.com/2016/01/06/aces-filmic-tone-mapping-curve/
vec3 ACESFilm(vec3 x)
{
float a = 2.51f;
float b = 0.03f;
float c = 2.43f;
float d = 0.59f;
float e = 0.14f;
return (x*(a*x+b))/(x*(c*x+d)+e);
}
// https://www.slideshare.net/ozlael/hable-john-uncharted2-hdr-lighting
vec3 filmicF(vec3 x)
{
float A = 0.22f;
float B = 0.30f;
float C = 0.10f;
float D = 0.20f;
float E = 0.01f;
float F = 0.30f;
return ((x*(A*x+C*B)+D*E)/(x*(A*x+B)+D*F)) - E/F;
}
vec3 filmic(vec3 x)
{
return filmicF(x) / filmicF(vec3(11.2f));
}
#include <tonemapping.glsl>
void main()
{
vec2 texcoord = f_coords;
vec3 hdr_color = texture(tex1, texcoord).xyz;
vec3 mapped = ACESFilm(hdr_color);
vec3 mapped = tonemap(hdr_color);
gl_FragColor = vec4(mapped, 1.0);
}

View File

@@ -10,10 +10,17 @@ uniform sampler2D tex1;
in vec4 f_clip_pos;
in vec4 f_clip_future_pos;
#include <tonemapping.glsl>
void main()
{
vec4 tex_color = texture(tex1, vec2(f_coord.x, f_coord.y + param[1].x));
gl_FragData[0] = tex_color * param[0];
vec4 color = tex_color * param[0];
#if POSTFX_ENABLED
gl_FragData[0] = color;
#else
gl_FragData[0] = tonemap(color);
#endif
#if MOTIONBLUR_ENABLED
{
vec2 a = (f_clip_future_pos.xy / f_clip_future_pos.w) * 0.5 + 0.5;

42
shaders/tonemapping.glsl Normal file
View File

@@ -0,0 +1,42 @@
vec3 reinhard(vec3 x)
{
return x / (x + vec3(1.0));
}
// https://knarkowicz.wordpress.com/2016/01/06/aces-filmic-tone-mapping-curve/
vec3 ACESFilm(vec3 x)
{
float a = 2.51f;
float b = 0.03f;
float c = 2.43f;
float d = 0.59f;
float e = 0.14f;
return (x*(a*x+b))/(x*(c*x+d)+e);
}
// https://www.slideshare.net/ozlael/hable-john-uncharted2-hdr-lighting
vec3 filmicF(vec3 x)
{
float A = 0.22f;
float B = 0.30f;
float C = 0.10f;
float D = 0.20f;
float E = 0.01f;
float F = 0.30f;
return ((x*(A*x+C*B)+D*E)/(x*(A*x+B)+D*F)) - E/F;
}
vec3 filmic(vec3 x)
{
return filmicF(x) / filmicF(vec3(11.2f));
}
vec3 tonemap(vec3 x)
{
return ACESFilm(x);
}
vec4 tonemap(vec4 x)
{
return vec4(tonemap(x.rgb), x.a);
}

View File

@@ -5,9 +5,17 @@
in vec4 f_clip_pos;
in vec4 f_clip_future_pos;
#include <tonemapping.glsl>
void main()
{
gl_FragData[0] = param[0];
vec4 color = vec4(pow(param[0].rgb, vec3(2.2)), param[0].a);
#if POSTFX_ENABLED
gl_FragData[0] = color;
#else
gl_FragData[0] = tonemap(color);
#endif
#if MOTIONBLUR_ENABLED
{
vec2 a = (f_clip_future_pos.xy / f_clip_future_pos.w) * 0.5 + 0.5;;