mirror of
https://github.com/ZDoom/qzdoom-gpl.git
synced 2024-11-23 12:22:45 +00:00
Added tonemapping and sector based exposure control
This commit is contained in:
parent
69f52cc898
commit
0efee85bd8
12 changed files with 284 additions and 30 deletions
|
@ -1108,6 +1108,7 @@ set( FASTMATH_SOURCES
|
|||
gl/shaders/gl_presentshader.cpp
|
||||
gl/shaders/gl_bloomshader.cpp
|
||||
gl/shaders/gl_blurshader.cpp
|
||||
gl/shaders/gl_tonemapshader.cpp
|
||||
gl/system/gl_interface.cpp
|
||||
gl/system/gl_framebuffer.cpp
|
||||
gl/system/gl_menu.cpp
|
||||
|
|
|
@ -97,10 +97,16 @@ void FGLRenderBuffers::Clear()
|
|||
glDeleteTextures(1, &mSceneTexture);
|
||||
if (mSceneDepthStencil != 0)
|
||||
glDeleteRenderbuffers(1, &mSceneDepthStencil);
|
||||
if (mHudFB != 0)
|
||||
glDeleteFramebuffers(1, &mHudFB);
|
||||
if (mHudTexture != 0)
|
||||
glDeleteTextures(1, &mHudTexture);
|
||||
|
||||
mSceneFB = 0;
|
||||
mSceneTexture = 0;
|
||||
mSceneDepthStencil = 0;
|
||||
mHudFB = 0;
|
||||
mHudTexture = 0;
|
||||
mWidth = 0;
|
||||
mHeight = 0;
|
||||
}
|
||||
|
@ -122,7 +128,9 @@ void FGLRenderBuffers::Setup(int width, int height)
|
|||
glActiveTexture(GL_TEXTURE0);
|
||||
|
||||
glGenFramebuffers(1, &mSceneFB);
|
||||
glGenFramebuffers(1, &mHudFB);
|
||||
glGenTextures(1, &mSceneTexture);
|
||||
glGenTextures(1, &mHudTexture);
|
||||
glGenRenderbuffers(1, &mSceneDepthStencil);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, mSceneTexture);
|
||||
|
@ -139,6 +147,16 @@ void FGLRenderBuffers::Setup(int width, int height)
|
|||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mSceneTexture, 0);
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, mSceneDepthStencil);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, mHudTexture);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16, width, height, 0, GL_RGBA, GL_UNSIGNED_SHORT, nullptr);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, mHudFB);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mHudTexture, 0);
|
||||
|
||||
int bloomWidth = MAX(width / 2, 1);
|
||||
int bloomHeight = MAX(height / 2, 1);
|
||||
for (int i = 0; i < NumBloomLevels; i++)
|
||||
|
@ -191,6 +209,17 @@ void FGLRenderBuffers::BindSceneFB()
|
|||
glBindFramebuffer(GL_FRAMEBUFFER, mSceneFB);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Makes the 2D/HUD frame buffer active
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FGLRenderBuffers::BindHudFB()
|
||||
{
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, mHudFB);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Makes the screen frame buffer active
|
||||
|
@ -213,3 +242,15 @@ void FGLRenderBuffers::BindSceneTexture(int index)
|
|||
glActiveTexture(GL_TEXTURE0 + index);
|
||||
glBindTexture(GL_TEXTURE_2D, mSceneTexture);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Binds the 2D/HUD frame buffer texture to the specified texture unit
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FGLRenderBuffers::BindHudTexture(int index)
|
||||
{
|
||||
glActiveTexture(GL_TEXTURE0 + index);
|
||||
glBindTexture(GL_TEXTURE_2D, mHudTexture);
|
||||
}
|
||||
|
|
|
@ -22,8 +22,10 @@ public:
|
|||
|
||||
void Setup(int width, int height);
|
||||
void BindSceneFB();
|
||||
void BindHudFB();
|
||||
void BindOutputFB();
|
||||
void BindSceneTexture(int index);
|
||||
void BindHudTexture(int index);
|
||||
|
||||
static bool IsSupported() { return gl.version >= 3.3f; }
|
||||
|
||||
|
@ -39,6 +41,8 @@ private:
|
|||
GLuint mSceneTexture = 0;
|
||||
GLuint mSceneDepthStencil = 0;
|
||||
GLuint mSceneFB = 0;
|
||||
GLuint mHudTexture = 0;
|
||||
GLuint mHudFB = 0;
|
||||
GLuint mOutputFB = 0;
|
||||
};
|
||||
|
||||
|
|
|
@ -64,6 +64,7 @@
|
|||
#include "gl/shaders/gl_shader.h"
|
||||
#include "gl/shaders/gl_bloomshader.h"
|
||||
#include "gl/shaders/gl_blurshader.h"
|
||||
#include "gl/shaders/gl_tonemapshader.h"
|
||||
#include "gl/shaders/gl_presentshader.h"
|
||||
#include "gl/textures/gl_texture.h"
|
||||
#include "gl/textures/gl_translate.h"
|
||||
|
@ -115,6 +116,7 @@ void FGLRenderer::Initialize()
|
|||
mBloomExtractShader = new FBloomExtractShader();
|
||||
mBloomCombineShader = new FBloomCombineShader();
|
||||
mBlurShader = new FBlurShader();
|
||||
mTonemapShader = new FTonemapShader();
|
||||
mPresentShader = new FPresentShader();
|
||||
|
||||
// Only needed for the core profile, because someone decided it was a good idea to remove the default VAO.
|
||||
|
@ -168,6 +170,7 @@ FGLRenderer::~FGLRenderer()
|
|||
if (mBloomExtractShader) delete mBloomExtractShader;
|
||||
if (mBloomCombineShader) delete mBloomCombineShader;
|
||||
if (mBlurShader) delete mBlurShader;
|
||||
if (mTonemapShader) delete mTonemapShader;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -235,7 +238,10 @@ void FGLRenderer::Begin2D()
|
|||
if (FGLRenderBuffers::IsSupported())
|
||||
{
|
||||
mBuffers->Setup(framebuffer->GetWidth(), framebuffer->GetHeight());
|
||||
mBuffers->BindSceneFB();
|
||||
if (mDrawingScene2D)
|
||||
mBuffers->BindSceneFB();
|
||||
else
|
||||
mBuffers->BindHudFB();
|
||||
glViewport(0, 0, mOutputViewport.width, mOutputViewport.height);
|
||||
}
|
||||
else
|
||||
|
|
|
@ -22,6 +22,7 @@ class FGLRenderBuffers;
|
|||
class FBloomExtractShader;
|
||||
class FBloomCombineShader;
|
||||
class FBlurShader;
|
||||
class FTonemapShader;
|
||||
class FPresentShader;
|
||||
|
||||
inline float DEG2RAD(float deg)
|
||||
|
@ -88,6 +89,7 @@ public:
|
|||
FBloomExtractShader *mBloomExtractShader;
|
||||
FBloomCombineShader *mBloomCombineShader;
|
||||
FBlurShader *mBlurShader;
|
||||
FTonemapShader *mTonemapShader;
|
||||
FPresentShader *mPresentShader;
|
||||
|
||||
FTexture *gllight;
|
||||
|
@ -106,6 +108,8 @@ public:
|
|||
|
||||
GL_IRECT mOutputViewportLB;
|
||||
GL_IRECT mOutputViewport;
|
||||
bool mDrawingScene2D = false;
|
||||
float mCameraExposure = 1.0f;
|
||||
|
||||
FGLRenderer(OpenGLFrameBuffer *fb);
|
||||
~FGLRenderer() ;
|
||||
|
@ -154,6 +158,7 @@ public:
|
|||
void WriteSavePic (player_t *player, FILE *file, int width, int height);
|
||||
void EndDrawScene(sector_t * viewsector);
|
||||
void BloomScene();
|
||||
void TonemapScene();
|
||||
void Flush();
|
||||
|
||||
void SetProjection(float fov, float ratio, float fovratio);
|
||||
|
|
|
@ -74,6 +74,7 @@
|
|||
#include "gl/shaders/gl_shader.h"
|
||||
#include "gl/shaders/gl_bloomshader.h"
|
||||
#include "gl/shaders/gl_blurshader.h"
|
||||
#include "gl/shaders/gl_tonemapshader.h"
|
||||
#include "gl/shaders/gl_presentshader.h"
|
||||
#include "gl/stereo3d/gl_stereo3d.h"
|
||||
#include "gl/stereo3d/scoped_view_shifter.h"
|
||||
|
@ -219,11 +220,9 @@ void FGLRenderer::BloomScene()
|
|||
|
||||
const float blurAmount = 4.0f;
|
||||
int sampleCount = 5; // Note: must be uneven number 3 to 15
|
||||
float exposure = 2.0f;
|
||||
float exposure = mCameraExposure;
|
||||
|
||||
auto vbo = GLRenderer->mVBO;
|
||||
|
||||
// TODO: Need a better way to share state with other parts of the pipeline
|
||||
// TBD: Maybe need a better way to share state with other parts of the pipeline
|
||||
GLboolean blendEnabled, scissorEnabled;
|
||||
GLint currentProgram, blendEquationRgb, blendEquationAlpha, blendSrcRgb, blendSrcAlpha, blendDestRgb, blendDestAlpha;
|
||||
glGetBooleanv(GL_BLEND, &blendEnabled);
|
||||
|
@ -251,12 +250,12 @@ void FGLRenderer::BloomScene()
|
|||
mBloomExtractShader->SceneTexture.Set(0);
|
||||
mBloomExtractShader->Exposure.Set(exposure);
|
||||
{
|
||||
FFlatVertex *ptr = vbo->GetBuffer();
|
||||
FFlatVertex *ptr = mVBO->GetBuffer();
|
||||
ptr->Set(-1.0f, -1.0f, 0, 0.0f, 0.0f); ptr++;
|
||||
ptr->Set(-1.0f, 1.0f, 0, 0.0f, 1.0f); ptr++;
|
||||
ptr->Set(1.0f, -1.0f, 0, 1.0f, 0.0f); ptr++;
|
||||
ptr->Set(1.0f, 1.0f, 0, 1.0f, 1.0f); ptr++;
|
||||
vbo->RenderCurrent(ptr, GL_TRIANGLE_STRIP);
|
||||
mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP);
|
||||
}
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
|
@ -266,8 +265,8 @@ void FGLRenderer::BloomScene()
|
|||
{
|
||||
const auto &level = mBuffers->BloomLevels[i];
|
||||
const auto &next = mBuffers->BloomLevels[i + 1];
|
||||
mBlurShader->BlurHorizontal(vbo, blurAmount, sampleCount, level.VTexture, level.HFramebuffer, level.Width, level.Height);
|
||||
mBlurShader->BlurVertical(vbo, blurAmount, sampleCount, level.HTexture, next.VFramebuffer, next.Width, next.Height);
|
||||
mBlurShader->BlurHorizontal(mVBO, blurAmount, sampleCount, level.VTexture, level.HFramebuffer, level.Width, level.Height);
|
||||
mBlurShader->BlurVertical(mVBO, blurAmount, sampleCount, level.HTexture, next.VFramebuffer, next.Width, next.Height);
|
||||
}
|
||||
|
||||
// Blur and upscale:
|
||||
|
@ -276,8 +275,8 @@ void FGLRenderer::BloomScene()
|
|||
const auto &level = mBuffers->BloomLevels[i];
|
||||
const auto &next = mBuffers->BloomLevels[i - 1];
|
||||
|
||||
mBlurShader->BlurHorizontal(vbo, blurAmount, sampleCount, level.VTexture, level.HFramebuffer, level.Width, level.Height);
|
||||
mBlurShader->BlurVertical(vbo, blurAmount, sampleCount, level.HTexture, level.VFramebuffer, level.Width, level.Height);
|
||||
mBlurShader->BlurHorizontal(mVBO, blurAmount, sampleCount, level.VTexture, level.HFramebuffer, level.Width, level.Height);
|
||||
mBlurShader->BlurVertical(mVBO, blurAmount, sampleCount, level.HTexture, level.VFramebuffer, level.Width, level.Height);
|
||||
|
||||
// Linear upscale:
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, next.VFramebuffer);
|
||||
|
@ -289,17 +288,17 @@ void FGLRenderer::BloomScene()
|
|||
mBloomCombineShader->Bind();
|
||||
mBloomCombineShader->BloomTexture.Set(0);
|
||||
{
|
||||
FFlatVertex *ptr = vbo->GetBuffer();
|
||||
FFlatVertex *ptr = mVBO->GetBuffer();
|
||||
ptr->Set(-1.0f, -1.0f, 0, 0.0f, 0.0f); ptr++;
|
||||
ptr->Set(-1.0f, 1.0f, 0, 0.0f, 1.0f); ptr++;
|
||||
ptr->Set(1.0f, -1.0f, 0, 1.0f, 0.0f); ptr++;
|
||||
ptr->Set(1.0f, 1.0f, 0, 1.0f, 1.0f); ptr++;
|
||||
vbo->RenderCurrent(ptr, GL_TRIANGLE_STRIP);
|
||||
mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP);
|
||||
}
|
||||
}
|
||||
|
||||
mBlurShader->BlurHorizontal(vbo, blurAmount, sampleCount, level0.VTexture, level0.HFramebuffer, level0.Width, level0.Height);
|
||||
mBlurShader->BlurVertical(vbo, blurAmount, sampleCount, level0.HTexture, level0.VFramebuffer, level0.Width, level0.Height);
|
||||
mBlurShader->BlurHorizontal(mVBO, blurAmount, sampleCount, level0.VTexture, level0.HFramebuffer, level0.Width, level0.Height);
|
||||
mBlurShader->BlurVertical(mVBO, blurAmount, sampleCount, level0.HTexture, level0.VFramebuffer, level0.Width, level0.Height);
|
||||
|
||||
// Add bloom back to scene texture:
|
||||
mBuffers->BindSceneFB();
|
||||
|
@ -314,12 +313,12 @@ void FGLRenderer::BloomScene()
|
|||
mBloomCombineShader->Bind();
|
||||
mBloomCombineShader->BloomTexture.Set(0);
|
||||
{
|
||||
FFlatVertex *ptr = vbo->GetBuffer();
|
||||
FFlatVertex *ptr = mVBO->GetBuffer();
|
||||
ptr->Set(-1.0f, -1.0f, 0, 0.0f, 0.0f); ptr++;
|
||||
ptr->Set(-1.0f, 1.0f, 0, 0.0f, 1.0f); ptr++;
|
||||
ptr->Set(1.0f, -1.0f, 0, 1.0f, 0.0f); ptr++;
|
||||
ptr->Set(1.0f, 1.0f, 0, 1.0f, 1.0f); ptr++;
|
||||
vbo->RenderCurrent(ptr, GL_TRIANGLE_STRIP);
|
||||
mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP);
|
||||
}
|
||||
|
||||
if (blendEnabled)
|
||||
|
@ -332,7 +331,41 @@ void FGLRenderer::BloomScene()
|
|||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Run post processing steps and copy to frame buffer
|
||||
// Tonemap scene texture and place the result in the HUD/2D texture
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void FGLRenderer::TonemapScene()
|
||||
{
|
||||
GLboolean blendEnabled, scissorEnabled;
|
||||
glGetBooleanv(GL_BLEND, &blendEnabled);
|
||||
glGetBooleanv(GL_SCISSOR_TEST, &scissorEnabled);
|
||||
|
||||
glDisable(GL_BLEND);
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
|
||||
mBuffers->BindHudFB();
|
||||
mBuffers->BindSceneTexture(0);
|
||||
mTonemapShader->Bind();
|
||||
mTonemapShader->SceneTexture.Set(0);
|
||||
mTonemapShader->Exposure.Set(mCameraExposure);
|
||||
|
||||
FFlatVertex *ptr = mVBO->GetBuffer();
|
||||
ptr->Set(-1.0f, -1.0f, 0, 0.0f, 0.0f); ptr++;
|
||||
ptr->Set(-1.0f, 1.0f, 0, 0.0f, 1.0f); ptr++;
|
||||
ptr->Set(1.0f, -1.0f, 0, 1.0f, 0.0f); ptr++;
|
||||
ptr->Set(1.0f, 1.0f, 0, 1.0f, 1.0f); ptr++;
|
||||
mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP);
|
||||
|
||||
if (blendEnabled)
|
||||
glEnable(GL_BLEND);
|
||||
if (scissorEnabled)
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Gamma correct while copying to frame buffer
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
@ -406,7 +439,7 @@ void FGLRenderer::Flush()
|
|||
mPresentShader->Contrast.Set(clamp<float>(vid_contrast, 0.1f, 3.f));
|
||||
mPresentShader->Brightness.Set(clamp<float>(vid_brightness, -0.8f, 0.8f));
|
||||
}
|
||||
mBuffers->BindSceneTexture(0);
|
||||
mBuffers->BindHudTexture(0);
|
||||
|
||||
FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer();
|
||||
ptr->Set(-1.0f, -1.0f, 0, 0.0f, 0.0f); ptr++;
|
||||
|
@ -938,6 +971,7 @@ void FGLRenderer::EndDrawScene(sector_t * viewsector)
|
|||
glDisable(GL_SCISSOR_TEST);
|
||||
|
||||
BloomScene();
|
||||
TonemapScene();
|
||||
}
|
||||
|
||||
|
||||
|
@ -1042,6 +1076,13 @@ sector_t * FGLRenderer::RenderViewpoint (AActor * camera, GL_IRECT * bounds, flo
|
|||
mViewActor=camera;
|
||||
}
|
||||
|
||||
if (toscreen)
|
||||
{
|
||||
float light = viewsector->lightlevel / 255.0f;
|
||||
float exposure = MAX(1.0f + (1.0f - light * light) * 1.5f, 0.5f);
|
||||
mCameraExposure = mCameraExposure * 0.98f + exposure * 0.02f;
|
||||
}
|
||||
|
||||
// 'viewsector' will not survive the rendering so it cannot be used anymore below.
|
||||
retval = viewsector;
|
||||
|
||||
|
@ -1056,6 +1097,7 @@ sector_t * FGLRenderer::RenderViewpoint (AActor * camera, GL_IRECT * bounds, flo
|
|||
// TODO: stereo specific viewport - needed when implementing side-by-side modes etc.
|
||||
SetOutputViewport(bounds);
|
||||
Set3DViewport();
|
||||
mDrawingScene2D = true;
|
||||
mCurrentFoV = fov;
|
||||
// Stereo mode specific perspective projection
|
||||
SetProjection( eye->GetProjection(fov, ratio, fovratio) );
|
||||
|
@ -1073,6 +1115,7 @@ sector_t * FGLRenderer::RenderViewpoint (AActor * camera, GL_IRECT * bounds, flo
|
|||
|
||||
ProcessScene(toscreen);
|
||||
if (mainview) EndDrawScene(retval); // do not call this for camera textures.
|
||||
mDrawingScene2D = false;
|
||||
eye->TearDown();
|
||||
}
|
||||
stereo3dMode.TearDown();
|
||||
|
|
|
@ -80,32 +80,29 @@ void FBlurShader::BlurHorizontal(FFlatVertexBuffer *vbo, float blurAmount, int s
|
|||
|
||||
void FBlurShader::Blur(FFlatVertexBuffer *vbo, float blurAmount, int sampleCount, GLuint inputTexture, GLuint outputFrameBuffer, int width, int height, bool vertical)
|
||||
{
|
||||
int error = glGetError();
|
||||
BlurSetup *setup = GetSetup(blurAmount, sampleCount);
|
||||
error = glGetError();
|
||||
if (vertical)
|
||||
setup->VerticalShader->Bind();
|
||||
else
|
||||
setup->HorizontalShader->Bind();
|
||||
error = glGetError();
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, inputTexture);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
error = glGetError();
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, outputFrameBuffer);
|
||||
glViewport(0, 0, width, height);
|
||||
glDisable(GL_BLEND);
|
||||
error = glGetError();
|
||||
|
||||
FFlatVertex *ptr = vbo->GetBuffer();
|
||||
ptr->Set(-1.0f, -1.0f, 0, 0.0f, 0.0f); ptr++;
|
||||
ptr->Set(-1.0f, 1.0f, 0, 0.0f, 1.0f); ptr++;
|
||||
ptr->Set(1.0f, -1.0f, 0, 1.0f, 0.0f); ptr++;
|
||||
ptr->Set(1.0f, 1.0f, 0, 1.0f, 1.0f); ptr++;
|
||||
vbo->RenderCurrent(ptr, GL_TRIANGLE_STRIP);
|
||||
error = glGetError();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -138,9 +135,7 @@ FBlurShader::BlurSetup *FBlurShader::GetSetup(float blurAmount, int sampleCount)
|
|||
blurSetup.VerticalShader->SetAttribLocation(0, "PositionInProjection");
|
||||
blurSetup.VerticalShader->Link("vertical blur");
|
||||
blurSetup.VerticalShader->Bind();
|
||||
int error = glGetError();
|
||||
glUniform1i(glGetUniformLocation(*blurSetup.VerticalShader.get(), "SourceTexture"), 0);
|
||||
error = glGetError();
|
||||
|
||||
blurSetup.HorizontalShader = std::make_shared<FShaderProgram>();
|
||||
blurSetup.HorizontalShader->Compile(FShaderProgram::Vertex, "horizontal blur vertex shader", vertexCode);
|
||||
|
|
65
src/gl/shaders/gl_tonemapshader.cpp
Normal file
65
src/gl/shaders/gl_tonemapshader.cpp
Normal file
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
** gl_tonemapshader.cpp
|
||||
** Converts a HDR texture to 0-1 range by applying a tonemap operator
|
||||
**
|
||||
**---------------------------------------------------------------------------
|
||||
** Copyright 2016 Magnus Norddahl
|
||||
** All rights reserved.
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions
|
||||
** are met:
|
||||
**
|
||||
** 1. Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** 2. Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in the
|
||||
** documentation and/or other materials provided with the distribution.
|
||||
** 3. The name of the author may not be used to endorse or promote products
|
||||
** derived from this software without specific prior written permission.
|
||||
** 4. When not used as part of GZDoom or a GZDoom derivative, this code will be
|
||||
** covered by the terms of the GNU Lesser General Public License as published
|
||||
** by the Free Software Foundation; either version 2.1 of the License, or (at
|
||||
** your option) any later version.
|
||||
** 5. Full disclosure of the entire project's source code, except for third
|
||||
** party libraries is mandatory. (NOTE: This clause is non-negotiable!)
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**---------------------------------------------------------------------------
|
||||
**
|
||||
*/
|
||||
|
||||
#include "gl/system/gl_system.h"
|
||||
#include "files.h"
|
||||
#include "m_swap.h"
|
||||
#include "v_video.h"
|
||||
#include "gl/gl_functions.h"
|
||||
#include "vectors.h"
|
||||
#include "gl/system/gl_interface.h"
|
||||
#include "gl/system/gl_framebuffer.h"
|
||||
#include "gl/system/gl_cvars.h"
|
||||
#include "gl/shaders/gl_tonemapshader.h"
|
||||
|
||||
void FTonemapShader::Bind()
|
||||
{
|
||||
if (!mShader)
|
||||
{
|
||||
mShader.Compile(FShaderProgram::Vertex, "shaders/glsl/tonemap.vp");
|
||||
mShader.Compile(FShaderProgram::Fragment, "shaders/glsl/tonemap.fp");
|
||||
mShader.SetFragDataLocation(0, "FragColor");
|
||||
mShader.Link("shaders/glsl/tonemap");
|
||||
mShader.SetAttribLocation(0, "PositionInProjection");
|
||||
SceneTexture.Init(mShader, "InputTexture");
|
||||
Exposure.Init(mShader, "ExposureAdjustment");
|
||||
}
|
||||
mShader.Bind();
|
||||
}
|
18
src/gl/shaders/gl_tonemapshader.h
Normal file
18
src/gl/shaders/gl_tonemapshader.h
Normal file
|
@ -0,0 +1,18 @@
|
|||
#ifndef __GL_TONEMAPSHADER_H
|
||||
#define __GL_TONEMAPSHADER_H
|
||||
|
||||
#include "gl_shaderprogram.h"
|
||||
|
||||
class FTonemapShader
|
||||
{
|
||||
public:
|
||||
void Bind();
|
||||
|
||||
FBufferedUniform1i SceneTexture;
|
||||
FBufferedUniform1f Exposure;
|
||||
|
||||
private:
|
||||
FShaderProgram mShader;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -158,7 +158,7 @@ bool OpenGLFrameBuffer::WipeStartScreen(int type)
|
|||
|
||||
if (FGLRenderBuffers::IsSupported())
|
||||
{
|
||||
GLRenderer->mBuffers->BindSceneFB();
|
||||
GLRenderer->mBuffers->BindHudFB();
|
||||
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, Width, Height);
|
||||
}
|
||||
else
|
||||
|
@ -193,7 +193,7 @@ void OpenGLFrameBuffer::WipeEndScreen()
|
|||
wipeendscreen->Bind(0, false, false);
|
||||
|
||||
if (FGLRenderBuffers::IsSupported())
|
||||
GLRenderer->mBuffers->BindSceneFB();
|
||||
GLRenderer->mBuffers->BindHudFB();
|
||||
|
||||
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, Width, Height);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
|
@ -232,7 +232,7 @@ bool OpenGLFrameBuffer::WipeDo(int ticks)
|
|||
|
||||
if (FGLRenderBuffers::IsSupported())
|
||||
{
|
||||
GLRenderer->mBuffers->BindSceneFB();
|
||||
GLRenderer->mBuffers->BindHudFB();
|
||||
glViewport(0, 0, GLRenderer->mOutputViewport.width, GLRenderer->mOutputViewport.height);
|
||||
}
|
||||
|
||||
|
|
65
wadsrc/static/shaders/glsl/tonemap.fp
Normal file
65
wadsrc/static/shaders/glsl/tonemap.fp
Normal file
|
@ -0,0 +1,65 @@
|
|||
|
||||
#version 330
|
||||
|
||||
in vec2 TexCoord;
|
||||
out vec4 FragColor;
|
||||
|
||||
uniform sampler2D InputTexture;
|
||||
uniform float ExposureAdjustment;
|
||||
|
||||
vec3 Linear(vec3 c)
|
||||
{
|
||||
//return pow(c, 2.2);
|
||||
return c * c; // cheaper, but assuming gamma of 2.0 instead of 2.2
|
||||
}
|
||||
|
||||
vec3 sRGB(vec3 c)
|
||||
{
|
||||
//return pow(c, vec3(1.0 / 2.2));
|
||||
return sqrt(c); // cheaper, but assuming gamma of 2.0 instead of 2.2
|
||||
}
|
||||
|
||||
vec3 TonemapLinear(vec3 color)
|
||||
{
|
||||
return sRGB(color);
|
||||
}
|
||||
|
||||
vec3 TonemapReinhard(vec3 color)
|
||||
{
|
||||
color = color / (1 + color);
|
||||
return sRGB(color);
|
||||
}
|
||||
|
||||
vec3 TonemapHejlDawson(vec3 color)
|
||||
{
|
||||
vec3 x = max(vec3(0), color - 0.004);
|
||||
return (x * (6.2 * x + 0.5)) / (x * (6.2 * x + 1.7) + 0.06); // no sRGB needed
|
||||
}
|
||||
|
||||
vec3 Uncharted2Tonemap(vec3 x)
|
||||
{
|
||||
float A = 0.15;
|
||||
float B = 0.50;
|
||||
float C = 0.10;
|
||||
float D = 0.20;
|
||||
float E = 0.02;
|
||||
float F = 0.30;
|
||||
return ((x * (A * x + C * B) + D * E) / (x * (A * x + B) + D * F)) - E / F;
|
||||
}
|
||||
|
||||
vec3 TonemapUncharted2(vec3 color)
|
||||
{
|
||||
float W = 11.2;
|
||||
float ExposureBias = 2.0;
|
||||
vec3 curr = Uncharted2Tonemap(ExposureBias * color);
|
||||
vec3 whiteScale = vec3(1) / Uncharted2Tonemap(vec3(W));
|
||||
return sRGB(curr * whiteScale);
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec3 color = texture(InputTexture, TexCoord).rgb;
|
||||
color = color * ExposureAdjustment;
|
||||
color = Linear(color); // needed because gzdoom's scene texture is not linear at the moment
|
||||
FragColor = vec4(TonemapUncharted2(color), 1.0);
|
||||
}
|
11
wadsrc/static/shaders/glsl/tonemap.vp
Normal file
11
wadsrc/static/shaders/glsl/tonemap.vp
Normal file
|
@ -0,0 +1,11 @@
|
|||
|
||||
#version 330
|
||||
|
||||
in vec4 PositionInProjection;
|
||||
out vec2 TexCoord;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = PositionInProjection;
|
||||
TexCoord = PositionInProjection.xy * 0.5 + 0.5;
|
||||
}
|
Loading…
Reference in a new issue