- added GZDoom's postprocessing/presentation code.

Compiles but only draws a black screen. Something must be missing but no idea yet what that might be.
This commit is contained in:
Christoph Oelckers 2019-12-28 22:36:47 +01:00
parent f6dee38d28
commit 737bf15ad8
30 changed files with 1243 additions and 110 deletions

View file

@ -9994,9 +9994,6 @@ void videoNextPage(void)
// Draw the console plus debug output on top of everything else. // Draw the console plus debug output on top of everything else.
DrawFullscreenBlends(); DrawFullscreenBlends();
GLInterface.Draw2D(&twod);
videoShowFrame(0); videoShowFrame(0);
videoBeginDrawing(); //{{{ videoBeginDrawing(); //{{{
@ -11417,13 +11414,11 @@ void videoClearScreen(int32_t dacol)
#ifdef USE_OPENGL #ifdef USE_OPENGL
if (videoGetRenderMode() >= REND_POLYMOST) if (videoGetRenderMode() >= REND_POLYMOST)
{ {
palette_t const p = paletteGetColor(dacol); glox1 = -1;
GLInterface.SetViewport(0,0,xdim,ydim); glox1 = -1; palette_t const p = paletteGetColor(dacol);
GLInterface.ClearScreen((float)p.r * (1.f/255.f), PalEntry clearcol = PalEntry(255, p.r, p.g, p.b);
(float)p.g * (1.f/255.f), GLInterface.ClearScreen(clearcol);
(float)p.b * (1.f/255.f),
false);
return; return;
} }
#endif #endif
@ -12008,9 +12003,4 @@ void renderSetRollAngle(int32_t rolla)
} }
#endif #endif
void videoShowFrame(int32_t w)
{
screen->Update();
}

View file

@ -79,7 +79,7 @@ void FGLRenderer::PostProcessScene(int fixedcm, const std::function<void()> &aft
hw_postprocess.Pass1(&renderstate, fixedcm, sceneWidth, sceneHeight); hw_postprocess.Pass1(&renderstate, fixedcm, sceneWidth, sceneHeight);
mBuffers->BindCurrentFB(); mBuffers->BindCurrentFB();
afterBloomDrawEndScene2D(); if (afterBloomDrawEndScene2D) afterBloomDrawEndScene2D();
hw_postprocess.Pass2(&renderstate, fixedcm, sceneWidth, sceneHeight); hw_postprocess.Pass2(&renderstate, fixedcm, sceneWidth, sceneHeight);
} }
@ -132,8 +132,7 @@ void FGLRenderer::Flush()
void FGLRenderer::CopyToBackbuffer(const IntRect *bounds, bool applyGamma) void FGLRenderer::CopyToBackbuffer(const IntRect *bounds, bool applyGamma)
{ {
//screen->Draw2D(); // draw all pending 2D stuff before copying the buffer screen->Draw2D(); // draw all pending 2D stuff before copying the buffer
//screen->Clear2D();
GLPPRenderState renderstate(mBuffers); GLPPRenderState renderstate(mBuffers);

View file

@ -62,7 +62,6 @@ void DoWriteSavePic(FileWriter *file, ESSType ssformat, uint8_t *scr, int width,
namespace OpenGLRenderer namespace OpenGLRenderer
{ {
FGLRenderer* GLRenderer;
//=========================================================================== //===========================================================================
// //
// Renderer interface // Renderer interface

View file

@ -306,7 +306,7 @@ void FPresentShaderBase::Init(const char * vtx_shader_name, const char * program
FString prolog = Uniforms.CreateDeclaration("Uniforms", PresentUniforms::Desc()); FString prolog = Uniforms.CreateDeclaration("Uniforms", PresentUniforms::Desc());
mShader.reset(new FShaderProgram()); mShader.reset(new FShaderProgram());
mShader->Compile(FShaderProgram::Vertex, "shaders/glsl/screenquad.vp", prolog, 330); mShader->Compile(FShaderProgram::Vertex, "engine/shaders/pp/screenquad.vp", prolog, 330);
mShader->Compile(FShaderProgram::Fragment, vtx_shader_name, prolog, 330); mShader->Compile(FShaderProgram::Fragment, vtx_shader_name, prolog, 330);
mShader->Link(program_name); mShader->Link(program_name);
mShader->SetUniformBufferLocation(Uniforms.BindingPoint(), "Uniforms"); mShader->SetUniformBufferLocation(Uniforms.BindingPoint(), "Uniforms");
@ -317,7 +317,7 @@ void FPresentShader::Bind()
{ {
if (!mShader) if (!mShader)
{ {
Init("shaders/glsl/present.fp", "shaders/glsl/present"); Init("engine/shaders/pp/present.fp", "engine/shaders/pp/present");
} }
mShader->Bind(); mShader->Bind();
} }
@ -328,7 +328,7 @@ void FPresent3DCheckerShader::Bind()
{ {
if (!mShader) if (!mShader)
{ {
Init("shaders/glsl/present_checker3d.fp", "shaders/glsl/presentChecker3d"); Init("engine/shaders/pp/present_checker3d.fp", "engine/shaders/pp/presentChecker3d");
} }
mShader->Bind(); mShader->Bind();
} }
@ -337,7 +337,7 @@ void FPresent3DColumnShader::Bind()
{ {
if (!mShader) if (!mShader)
{ {
Init("shaders/glsl/present_column3d.fp", "shaders/glsl/presentColumn3d"); Init("engine/shaders/pp/present_column3d.fp", "engine/shaders/pp/presentColumn3d");
} }
mShader->Bind(); mShader->Bind();
} }
@ -346,7 +346,7 @@ void FPresent3DRowShader::Bind()
{ {
if (!mShader) if (!mShader)
{ {
Init("shaders/glsl/present_row3d.fp", "shaders/glsl/presentRow3d"); Init("engine/shaders/pp/present_row3d.fp", "engine/shaders/pp/presentRow3d");
} }
mShader->Bind(); mShader->Bind();
} }

View file

@ -31,12 +31,13 @@
#include "m_png.h" #include "m_png.h"
#include "printf.h" #include "printf.h"
#include "templates.h" #include "templates.h"
#include "glbackend/glbackend.h"
#include "gl_load/gl_interface.h" #include "gl_load/gl_interface.h"
#include "gl/system/gl_framebuffer.h" #include "gl/system/gl_framebuffer.h"
/*
#include "gl/renderer/gl_renderer.h" #include "gl/renderer/gl_renderer.h"
#include "gl/renderer/gl_renderbuffers.h" #include "gl/renderer/gl_renderbuffers.h"
/*
#include "gl/textures/gl_samplers.h" #include "gl/textures/gl_samplers.h"
#include "hwrenderer/utility/hw_clock.h" #include "hwrenderer/utility/hw_clock.h"
#include "hwrenderer/utility/hw_vrmodes.h" #include "hwrenderer/utility/hw_vrmodes.h"
@ -65,9 +66,7 @@ extern bool vid_hdr_active;
namespace OpenGLRenderer namespace OpenGLRenderer
{ {
#ifdef IMPLEMENT_IT
FGLRenderer *GLRenderer; FGLRenderer *GLRenderer;
#endif
//========================================================================== //==========================================================================
// //
@ -86,28 +85,28 @@ OpenGLFrameBuffer::OpenGLFrameBuffer(void *hMonitor, bool fullscreen) :
// Make sure all global variables tracking OpenGL context state are reset.. // Make sure all global variables tracking OpenGL context state are reset..
FHardwareTexture::InitGlobalState(); FHardwareTexture::InitGlobalState();
gl_RenderState.Reset(); gl_RenderState.Reset();
#endif
GLRenderer = nullptr; GLRenderer = nullptr;
#endif
} }
OpenGLFrameBuffer::~OpenGLFrameBuffer() OpenGLFrameBuffer::~OpenGLFrameBuffer()
{ {
#ifdef IMPLEMENT_IT
PPResource::ResetAll(); PPResource::ResetAll();
#ifdef IMPLEMENT_IT
if (mVertexData != nullptr) delete mVertexData; if (mVertexData != nullptr) delete mVertexData;
if (mSkyData != nullptr) delete mSkyData; if (mSkyData != nullptr) delete mSkyData;
if (mViewpoints != nullptr) delete mViewpoints; if (mViewpoints != nullptr) delete mViewpoints;
if (mLights != nullptr) delete mLights; if (mLights != nullptr) delete mLights;
mShadowMap.Reset(); mShadowMap.Reset();
#endif
if (GLRenderer) if (GLRenderer)
{ {
delete GLRenderer; delete GLRenderer;
GLRenderer = nullptr; GLRenderer = nullptr;
} }
#endif
} }
//========================================================================== //==========================================================================
@ -166,10 +165,10 @@ void OpenGLFrameBuffer::InitializeState()
mSkyData = new FSkyVertexBuffer; mSkyData = new FSkyVertexBuffer;
mViewpoints = new HWViewpointBuffer; mViewpoints = new HWViewpointBuffer;
mLights = new FLightBuffer(); mLights = new FLightBuffer();
#endif
GLRenderer = new FGLRenderer(this); GLRenderer = new FGLRenderer(this);
GLRenderer->Initialize(GetWidth(), GetHeight()); GLRenderer->Initialize(GetWidth(), GetHeight());
#ifdef IMPLEMENT_IT
static_cast<GLDataBuffer*>(mLights->GetBuffer())->BindBase(); static_cast<GLDataBuffer*>(mLights->GetBuffer())->BindBase();
#endif #endif
@ -185,14 +184,14 @@ void OpenGLFrameBuffer::InitializeState()
void OpenGLFrameBuffer::Update() void OpenGLFrameBuffer::Update()
{ {
#ifdef IMPLEMENT_IT #if 0
twoD.Reset(); twoD.Reset();
Flush3D.Reset(); Flush3D.Reset();
Flush3D.Clock(); Flush3D.Clock();
GLRenderer->Flush();
Flush3D.Unclock();
#endif #endif
GLRenderer->Flush();
// Flush3D.Unclock();
Swap(); Swap();
Super::Update(); Super::Update();
@ -305,35 +304,33 @@ IIndexBuffer *OpenGLFrameBuffer::CreateIndexBuffer()
{ {
return new GLIndexBuffer; return new GLIndexBuffer;
} }
#endif
IDataBuffer *OpenGLFrameBuffer::CreateDataBuffer(int bindingpoint, bool ssbo, bool needsresize) IDataBuffer *OpenGLFrameBuffer::CreateDataBuffer(int bindingpoint, bool ssbo, bool needsresize)
{ {
return new GLDataBuffer(bindingpoint, ssbo); return new GLDataBuffer(bindingpoint, ssbo);
} }
#ifdef IMPLEMENT_IT
void OpenGLFrameBuffer::TextureFilterChanged() void OpenGLFrameBuffer::TextureFilterChanged()
{ {
if (GLRenderer != NULL && GLRenderer->mSamplerManager != NULL) GLRenderer->mSamplerManager->SetTextureFilterMode(); if (GLRenderer != NULL && GLRenderer->mSamplerManager != NULL) GLRenderer->mSamplerManager->SetTextureFilterMode();
} }
#endif
void OpenGLFrameBuffer::BlurScene(float amount) void OpenGLFrameBuffer::BlurScene(float amount)
{ {
GLRenderer->BlurScene(amount); GLRenderer->BlurScene(amount);
} }
void OpenGLFrameBuffer::SetViewportRects(IntRect *bounds) #if 0
void OpenGLFrameBuffer::UpdatePalette()
{ {
Super::SetViewportRects(bounds); if (GLRenderer)
if (!bounds) GLRenderer->ClearTonemapPalette();
{
auto vrmode = VRMode::GetVRMode(true);
vrmode->AdjustViewport(this);
}
} }
#endif #endif
//=========================================================================== //===========================================================================
// //
// //
@ -343,6 +340,8 @@ void OpenGLFrameBuffer::SetViewportRects(IntRect *bounds)
void OpenGLFrameBuffer::BeginFrame() void OpenGLFrameBuffer::BeginFrame()
{ {
SetViewportRects(nullptr); SetViewportRects(nullptr);
if (GLRenderer != nullptr)
GLRenderer->BeginFrame();
} }
//=========================================================================== //===========================================================================
@ -401,9 +400,18 @@ TArray<uint8_t> OpenGLFrameBuffer::GetScreenshotBuffer(int &pitch, ESSType &colo
// //
//=========================================================================== //===========================================================================
void OpenGLFrameBuffer::Draw2D()
{
if (GLRenderer != nullptr)
{
GLRenderer->mBuffers->BindCurrentFB();
GLInterface.Draw2D(&twod);
}
}
void OpenGLFrameBuffer::PostProcessScene(int fixedcm, const std::function<void()> &afterBloomDrawEndScene2D) void OpenGLFrameBuffer::PostProcessScene(int fixedcm, const std::function<void()> &afterBloomDrawEndScene2D)
{ {
//GLRenderer->PostProcessScene(fixedcm, afterBloomDrawEndScene2D); GLRenderer->PostProcessScene(fixedcm, afterBloomDrawEndScene2D);
} }

View file

@ -23,6 +23,7 @@ public:
void InitializeState() override; void InitializeState() override;
void Update() override; void Update() override;
void Draw2D() override;
void CleanForRestart() override; void CleanForRestart() override;
const char* DeviceName() const override; const char* DeviceName() const override;
@ -34,13 +35,13 @@ public:
void TextureFilterChanged() override; void TextureFilterChanged() override;
#endif #endif
void BeginFrame() override; void BeginFrame() override;
#ifdef IMPLEMENT_IT //void SetViewportRects(IntRect *bounds) override;
void SetViewportRects(IntRect *bounds) override;
void BlurScene(float amount) override; void BlurScene(float amount) override;
#ifdef IMPLEMENT_IT
IVertexBuffer *CreateVertexBuffer() override; IVertexBuffer *CreateVertexBuffer() override;
IIndexBuffer *CreateIndexBuffer() override; IIndexBuffer *CreateIndexBuffer() override;
IDataBuffer *CreateDataBuffer(int bindingpoint, bool ssbo, bool needsresize) override;
#endif #endif
IDataBuffer *CreateDataBuffer(int bindingpoint, bool ssbo, bool needsresize) override;
// Retrieves a buffer containing image data for a screenshot. // Retrieves a buffer containing image data for a screenshot.
// Hint: Pitch can be negative for upside-down images, in which case buffer // Hint: Pitch can be negative for upside-down images, in which case buffer

View file

@ -372,8 +372,8 @@ void PPFXAA::CreateShaders()
if (LastQuality == gl_fxaa) if (LastQuality == gl_fxaa)
return; return;
FXAALuma = { "shaders/glsl/fxaa.fp", "#define FXAA_LUMA_PASS\n", {} }; FXAALuma = { "engine/shaders/pp/fxaa.fp", "#define FXAA_LUMA_PASS\n", {} };
FXAA = { "shaders/glsl/fxaa.fp", GetDefines(), FXAAUniforms::Desc(), GetMaxVersion() }; FXAA = { "engine/shaders/pp/fxaa.fp", GetDefines(), FXAAUniforms::Desc(), GetMaxVersion() };
LastQuality = gl_fxaa; LastQuality = gl_fxaa;
} }
@ -627,14 +627,14 @@ void PPAmbientOcclusion::CreateShaders()
#define NUM_STEPS %d.0 #define NUM_STEPS %d.0
)", numDirections, numSteps); )", numDirections, numSteps);
LinearDepth = { "shaders/glsl/lineardepth.fp", "", LinearDepthUniforms::Desc() }; LinearDepth = { "engine/shaders/pp/lineardepth.fp", "", LinearDepthUniforms::Desc() };
LinearDepthMS = { "shaders/glsl/lineardepth.fp", "#define MULTISAMPLE\n", LinearDepthUniforms::Desc() }; LinearDepthMS = { "engine/shaders/pp/lineardepth.fp", "#define MULTISAMPLE\n", LinearDepthUniforms::Desc() };
AmbientOcclude = { "shaders/glsl/ssao.fp", defines, SSAOUniforms::Desc() }; AmbientOcclude = { "engine/shaders/pp/ssao.fp", defines, SSAOUniforms::Desc() };
AmbientOccludeMS = { "shaders/glsl/ssao.fp", defines + "\n#define MULTISAMPLE\n", SSAOUniforms::Desc() }; AmbientOccludeMS = { "engine/shaders/pp/ssao.fp", defines + "\n#define MULTISAMPLE\n", SSAOUniforms::Desc() };
BlurVertical = { "shaders/glsl/depthblur.fp", "#define BLUR_VERTICAL\n", DepthBlurUniforms::Desc() }; BlurVertical = { "engine/shaders/pp/depthblur.fp", "#define BLUR_VERTICAL\n", DepthBlurUniforms::Desc() };
BlurHorizontal = { "shaders/glsl/depthblur.fp", "#define BLUR_HORIZONTAL\n", DepthBlurUniforms::Desc() }; BlurHorizontal = { "engine/shaders/pp/depthblur.fp", "#define BLUR_HORIZONTAL\n", DepthBlurUniforms::Desc() };
Combine = { "shaders/glsl/ssaocombine.fp", "", AmbientCombineUniforms::Desc() }; Combine = { "engine/shaders/pp/ssaocombine.fp", "", AmbientCombineUniforms::Desc() };
CombineMS = { "shaders/glsl/ssaocombine.fp", "#define MULTISAMPLE\n", AmbientCombineUniforms::Desc() }; CombineMS = { "engine/shaders/pp/ssaocombine.fp", "#define MULTISAMPLE\n", AmbientCombineUniforms::Desc() };
LastQuality = gl_ssao; LastQuality = gl_ssao;
} }

View file

@ -303,7 +303,7 @@ public:
void ResetBackend() override { Backend.reset(); } void ResetBackend() override { Backend.reset(); }
FString VertexShader = "shaders/glsl/screenquad.vp"; FString VertexShader = "engine/shaders/pp/screenquad.vp";
FString FragmentShader; FString FragmentShader;
FString Defines; FString Defines;
std::vector<UniformFieldDesc> Uniforms; std::vector<UniformFieldDesc> Uniforms;
@ -376,10 +376,10 @@ private:
int lastWidth = 0; int lastWidth = 0;
int lastHeight = 0; int lastHeight = 0;
PPShader BloomCombine = { "shaders/glsl/bloomcombine.fp", "", {} }; PPShader BloomCombine = { "engine/shaders/pp/bloomcombine.fp", "", {} };
PPShader BloomExtract = { "shaders/glsl/bloomextract.fp", "", ExtractUniforms::Desc() }; PPShader BloomExtract = { "engine/shaders/pp/bloomextract.fp", "", ExtractUniforms::Desc() };
PPShader BlurVertical = { "shaders/glsl/blur.fp", "#define BLUR_VERTICAL\n", BlurUniforms::Desc() }; PPShader BlurVertical = { "engine/shaders/pp/blur.fp", "#define BLUR_VERTICAL\n", BlurUniforms::Desc() };
PPShader BlurHorizontal = { "shaders/glsl/blur.fp", "#define BLUR_HORIZONTAL\n", BlurUniforms::Desc() }; PPShader BlurHorizontal = { "engine/shaders/pp/blur.fp", "#define BLUR_HORIZONTAL\n", BlurUniforms::Desc() };
}; };
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
@ -412,7 +412,7 @@ public:
void Render(PPRenderState *renderstate); void Render(PPRenderState *renderstate);
private: private:
PPShader Lens = { "shaders/glsl/lensdistortion.fp", "", LensUniforms::Desc() }; PPShader Lens = { "engine/shaders/pp/lensdistortion.fp", "", LensUniforms::Desc() };
}; };
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
@ -504,9 +504,9 @@ private:
std::vector<PPExposureLevel> ExposureLevels; std::vector<PPExposureLevel> ExposureLevels;
bool FirstExposureFrame = true; bool FirstExposureFrame = true;
PPShader ExposureExtract = { "shaders/glsl/exposureextract.fp", "", ExposureExtractUniforms::Desc() }; PPShader ExposureExtract = { "engine/shaders/pp/exposureextract.fp", "", ExposureExtractUniforms::Desc() };
PPShader ExposureAverage = { "shaders/glsl/exposureaverage.fp", "", {}, 400 }; PPShader ExposureAverage = { "engine/shaders/pp/exposureaverage.fp", "", {}, 400 };
PPShader ExposureCombine = { "shaders/glsl/exposurecombine.fp", "", ExposureCombineUniforms::Desc() }; PPShader ExposureCombine = { "engine/shaders/pp/exposurecombine.fp", "", ExposureCombineUniforms::Desc() };
}; };
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
@ -539,11 +539,11 @@ private:
PPTexture PaletteTexture; PPTexture PaletteTexture;
PPShader LinearShader = { "shaders/glsl/tonemap.fp", "#define LINEAR\n", {} }; PPShader LinearShader = { "engine/shaders/pp/tonemap.fp", "#define LINEAR\n", {} };
PPShader ReinhardShader = { "shaders/glsl/tonemap.fp", "#define REINHARD\n", {} }; PPShader ReinhardShader = { "engine/shaders/pp/tonemap.fp", "#define REINHARD\n", {} };
PPShader HejlDawsonShader = { "shaders/glsl/tonemap.fp", "#define HEJLDAWSON\n", {} }; PPShader HejlDawsonShader = { "engine/shaders/pp/tonemap.fp", "#define HEJLDAWSON\n", {} };
PPShader Uncharted2Shader = { "shaders/glsl/tonemap.fp", "#define UNCHARTED2\n", {} }; PPShader Uncharted2Shader = { "engine/shaders/pp/tonemap.fp", "#define UNCHARTED2\n", {} };
PPShader PaletteShader = { "shaders/glsl/tonemap.fp", "#define PALETTE\n", {} }; PPShader PaletteShader = { "engine/shaders/pp/tonemap.fp", "#define PALETTE\n", {} };
enum TonemapMode enum TonemapMode
{ {
@ -744,10 +744,10 @@ public:
PPTexture Dither; PPTexture Dither;
PPShader Present = { "shaders/glsl/present.fp", "", PresentUniforms::Desc() }; PPShader Present = { "engine/shaders/pp/present.fp", "", PresentUniforms::Desc() };
PPShader Checker3D = { "shaders/glsl/present_checker3d.fp", "", PresentUniforms::Desc() }; PPShader Checker3D = { "engine/shaders/pp/present_checker3d.fp", "", PresentUniforms::Desc() };
PPShader Column3D = { "shaders/glsl/present_column3d.fp", "", PresentUniforms::Desc() }; PPShader Column3D = { "engine/shaders/pp/present_column3d.fp", "", PresentUniforms::Desc() };
PPShader Row3D = { "shaders/glsl/present_row3d.fp", "", PresentUniforms::Desc() }; PPShader Row3D = { "engine/shaders/pp/present_row3d.fp", "", PresentUniforms::Desc() };
}; };
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////

View file

@ -265,31 +265,31 @@ FString RemoveLayoutLocationDecl(FString code, const char *inoutkeyword)
// Note: the MaterialShaderIndex enum in gl_shader.h needs to be updated whenever this array is modified. // Note: the MaterialShaderIndex enum in gl_shader.h needs to be updated whenever this array is modified.
const FDefaultShader defaultshaders[] = const FDefaultShader defaultshaders[] =
{ {
{"Default", "shaders/glsl/func_normal.fp", "shaders/glsl/material_normal.fp", ""}, {"Default", "engine/shaders/pp/func_normal.fp", "engine/shaders/pp/material_normal.fp", ""},
{"Warp 1", "shaders/glsl/func_warp1.fp", "shaders/glsl/material_normal.fp", ""}, {"Warp 1", "engine/shaders/pp/func_warp1.fp", "engine/shaders/pp/material_normal.fp", ""},
{"Warp 2", "shaders/glsl/func_warp2.fp", "shaders/glsl/material_normal.fp", ""}, {"Warp 2", "engine/shaders/pp/func_warp2.fp", "engine/shaders/pp/material_normal.fp", ""},
{"Brightmap","shaders/glsl/func_brightmap.fp", "shaders/glsl/material_normal.fp", "#define BRIGHTMAP\n"}, {"Brightmap","engine/shaders/pp/func_brightmap.fp", "engine/shaders/pp/material_normal.fp", "#define BRIGHTMAP\n"},
{"Specular", "shaders/glsl/func_spec.fp", "shaders/glsl/material_specular.fp", "#define SPECULAR\n#define NORMALMAP\n"}, {"Specular", "engine/shaders/pp/func_spec.fp", "engine/shaders/pp/material_specular.fp", "#define SPECULAR\n#define NORMALMAP\n"},
{"SpecularBrightmap", "shaders/glsl/func_spec.fp", "shaders/glsl/material_specular.fp", "#define SPECULAR\n#define NORMALMAP\n#define BRIGHTMAP\n"}, {"SpecularBrightmap", "engine/shaders/pp/func_spec.fp", "engine/shaders/pp/material_specular.fp", "#define SPECULAR\n#define NORMALMAP\n#define BRIGHTMAP\n"},
{"PBR","shaders/glsl/func_pbr.fp", "shaders/glsl/material_pbr.fp", "#define PBR\n#define NORMALMAP\n"}, {"PBR","engine/shaders/pp/func_pbr.fp", "engine/shaders/pp/material_pbr.fp", "#define PBR\n#define NORMALMAP\n"},
{"PBRBrightmap","shaders/glsl/func_pbr.fp", "shaders/glsl/material_pbr.fp", "#define PBR\n#define NORMALMAP\n#define BRIGHTMAP\n"}, {"PBRBrightmap","engine/shaders/pp/func_pbr.fp", "engine/shaders/pp/material_pbr.fp", "#define PBR\n#define NORMALMAP\n#define BRIGHTMAP\n"},
{"Paletted", "shaders/glsl/func_paletted.fp", "shaders/glsl/material_nolight.fp", ""}, {"Paletted", "engine/shaders/pp/func_paletted.fp", "engine/shaders/pp/material_nolight.fp", ""},
{"No Texture", "shaders/glsl/func_notexture.fp", "shaders/glsl/material_normal.fp", ""}, {"No Texture", "engine/shaders/pp/func_notexture.fp", "engine/shaders/pp/material_normal.fp", ""},
{"Basic Fuzz", "shaders/glsl/fuzz_standard.fp", "shaders/glsl/material_normal.fp", ""}, {"Basic Fuzz", "engine/shaders/pp/fuzz_standard.fp", "engine/shaders/pp/material_normal.fp", ""},
{"Smooth Fuzz", "shaders/glsl/fuzz_smooth.fp", "shaders/glsl/material_normal.fp", ""}, {"Smooth Fuzz", "engine/shaders/pp/fuzz_smooth.fp", "engine/shaders/pp/material_normal.fp", ""},
{"Swirly Fuzz", "shaders/glsl/fuzz_swirly.fp", "shaders/glsl/material_normal.fp", ""}, {"Swirly Fuzz", "engine/shaders/pp/fuzz_swirly.fp", "engine/shaders/pp/material_normal.fp", ""},
{"Translucent Fuzz", "shaders/glsl/fuzz_smoothtranslucent.fp", "shaders/glsl/material_normal.fp", ""}, {"Translucent Fuzz", "engine/shaders/pp/fuzz_smoothtranslucent.fp", "engine/shaders/pp/material_normal.fp", ""},
{"Jagged Fuzz", "shaders/glsl/fuzz_jagged.fp", "shaders/glsl/material_normal.fp", ""}, {"Jagged Fuzz", "engine/shaders/pp/fuzz_jagged.fp", "engine/shaders/pp/material_normal.fp", ""},
{"Noise Fuzz", "shaders/glsl/fuzz_noise.fp", "shaders/glsl/material_normal.fp", ""}, {"Noise Fuzz", "engine/shaders/pp/fuzz_noise.fp", "engine/shaders/pp/material_normal.fp", ""},
{"Smooth Noise Fuzz", "shaders/glsl/fuzz_smoothnoise.fp", "shaders/glsl/material_normal.fp", ""}, {"Smooth Noise Fuzz", "engine/shaders/pp/fuzz_smoothnoise.fp", "engine/shaders/pp/material_normal.fp", ""},
{"Software Fuzz", "shaders/glsl/fuzz_software.fp", "shaders/glsl/material_normal.fp", ""}, {"Software Fuzz", "engine/shaders/pp/fuzz_software.fp", "engine/shaders/pp/material_normal.fp", ""},
{nullptr,nullptr,nullptr,nullptr} {nullptr,nullptr,nullptr,nullptr}
}; };
const FEffectShader effectshaders[] = const FEffectShader effectshaders[] =
{ {
{ "fogboundary", "shaders/glsl/main.vp", "shaders/glsl/fogboundary.fp", nullptr, nullptr, "#define NO_ALPHATEST\n" }, { "fogboundary", "engine/shaders/pp/main.vp", "engine/shaders/pp/fogboundary.fp", nullptr, nullptr, "#define NO_ALPHATEST\n" },
{ "spheremap", "shaders/glsl/main.vp", "shaders/glsl/main.fp", "shaders/glsl/func_normal.fp", "shaders/glsl/material_normal.fp", "#define SPHEREMAP\n#define NO_ALPHATEST\n" }, { "spheremap", "engine/shaders/pp/main.vp", "engine/shaders/pp/main.fp", "engine/shaders/pp/func_normal.fp", "engine/shaders/pp/material_normal.fp", "#define SPHEREMAP\n#define NO_ALPHATEST\n" },
{ "burn", "shaders/glsl/main.vp", "shaders/glsl/burn.fp", nullptr, nullptr, "#define SIMPLE\n#define NO_ALPHATEST\n" }, { "burn", "engine/shaders/pp/main.vp", "engine/shaders/pp/burn.fp", nullptr, nullptr, "#define SIMPLE\n#define NO_ALPHATEST\n" },
{ "stencil", "shaders/glsl/main.vp", "shaders/glsl/stencil.fp", nullptr, nullptr, "#define SIMPLE\n#define NO_ALPHATEST\n" }, { "stencil", "engine/shaders/pp/main.vp", "engine/shaders/pp/stencil.fp", nullptr, nullptr, "#define SIMPLE\n#define NO_ALPHATEST\n" },
}; };

View file

@ -331,6 +331,7 @@ public:
// Report a game restart // Report a game restart
virtual int Backend() { return 0; } virtual int Backend() { return 0; }
virtual const char* DeviceName() const { return "Unknown"; } virtual const char* DeviceName() const { return "Unknown"; }
virtual void Draw2D() {}
// Screen wiping // Screen wiping
virtual FTexture *WipeStartScreen(); virtual FTexture *WipeStartScreen();

View file

@ -45,8 +45,11 @@
#include "imgui_impl_opengl3.h" #include "imgui_impl_opengl3.h"
#include "baselayer.h" #include "baselayer.h"
#include "gl_interface.h" #include "gl_interface.h"
#include "v_2ddrawer.h"
#include "v_video.h"
#include "gl_renderer.h"
extern int ydim; extern int xdim, ydim;
FileReader GetResource(const char* fn) FileReader GetResource(const char* fn)
{ {
@ -149,25 +152,36 @@ void GLInstance::LoadSurfaceShader()
void GLInstance::InitGLState(int fogmode, int multisample) void GLInstance::InitGLState(int fogmode, int multisample)
{ {
glShadeModel(GL_SMOOTH); // GL_FLAT glShadeModel(GL_SMOOTH); // GL_FLAT
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
glDisable(GL_DITHER);
glEnable(GL_TEXTURE_2D); glEnable(GL_TEXTURE_2D);
glHint(GL_FOG_HINT, GL_NICEST);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glPixelStorei(GL_PACK_ALIGNMENT, 1); glPixelStorei(GL_PACK_ALIGNMENT, 1);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glEnable(GL_DEPTH_CLAMP);
if (multisample > 0 ) if (multisample > 0 )
{ {
//glHint(GL_MULTISAMPLE_FILTER_HINT_NV, GL_NICEST); //glHint(GL_MULTISAMPLE_FILTER_HINT_NV, GL_NICEST);
glEnable(GL_MULTISAMPLE); glEnable(GL_MULTISAMPLE);
} }
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize); glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize);
// This is a bad place to call this but without deconstructing the entire render loops in all front ends there is no way to have a well defined spot for this stuff.
// Before doing that the backend needs to work in some fashion, so we have to make sure everything is set up when the first render call is performed.
screen->BeginFrame();
OpenGLRenderer::GLRenderer->mBuffers->BindSceneFB(false);
} }
void videoShowFrame(int32_t w)
{
OpenGLRenderer::GLRenderer->mBuffers->BlitSceneToTexture(); // Copy the resulting scene to the current post process texture
screen->PostProcessScene(0, nullptr); // at the moment this won't work because there's no guarantee that this is a clean buffer what we get here.
screen->Update();
// After finishing the frame, reset everything for the next frame. This needs to be done better.
screen->BeginFrame();
OpenGLRenderer::GLRenderer->mBuffers->BindSceneFB(false);
}
void GLInstance::Deinit() void GLInstance::Deinit()
{ {
#if 0 #if 0
@ -502,6 +516,22 @@ void GLInstance::DrawImGui(ImDrawData* data)
#endif #endif
} }
void GLInstance::ClearScreen(PalEntry color)
{
twod.Clear(); // Since we clear the entire screen, all previous draw operations become redundant, so delete them.
#if 1
SetViewport(0, 0, xdim, ydim);
ClearScreen((float)color.r * (1.f / 255.f),
(float)color.g * (1.f / 255.f),
(float)color.b * (1.f / 255.f),
false);
#else
// This must be synchronized with the rest of the 2D operations.
twod.AddColorOnlyQuad(0, 0, xdim, ydim, );
#endif
}
void PolymostRenderState::Apply(PolymostShader* shader) void PolymostRenderState::Apply(PolymostShader* shader)

View file

@ -300,6 +300,7 @@ public:
void SetPalette(int palette); void SetPalette(int palette);
bool ApplyTextureProps(FTexture *tex, int pal); bool ApplyTextureProps(FTexture *tex, int pal);
void RestoreTextureProps(); void RestoreTextureProps();
void ClearScreen(PalEntry color);
void ReadPixels(int w, int h, uint8_t* buffer); void ReadPixels(int w, int h, uint8_t* buffer);

View file

@ -66,15 +66,10 @@ PFNWGLSWAPINTERVALEXTPROC myWglSwapIntervalExtProc;
// //
// //
//========================================================================== //==========================================================================
#ifndef OFFSCREEN
#define MS 4
#else
#define MS 0
#endif
SystemGLFrameBuffer::SystemGLFrameBuffer(void *hMonitor, bool fullscreen) : SystemBaseFrameBuffer(hMonitor, fullscreen) SystemGLFrameBuffer::SystemGLFrameBuffer(void *hMonitor, bool fullscreen) : SystemBaseFrameBuffer(hMonitor, fullscreen)
{ {
if (!static_cast<Win32GLVideo *>(Video)->InitHardware(Window, MS)) if (!static_cast<Win32GLVideo *>(Video)->InitHardware(Window, 0))
{ {
I_FatalError("Unable to initialize OpenGL"); I_FatalError("Unable to initialize OpenGL");
return; return;

View file

@ -0,0 +1,10 @@
layout(location=0) in vec2 TexCoord;
layout(location=0) out vec4 FragColor;
layout(binding=0) uniform sampler2D Bloom;
void main()
{
FragColor = vec4(texture(Bloom, TexCoord).rgb, 0.0);
}

View file

@ -0,0 +1,12 @@
layout(location=0) in vec2 TexCoord;
layout(location=0) out vec4 FragColor;
layout(binding=0) uniform sampler2D SceneTexture;
layout(binding=1) uniform sampler2D ExposureTexture;
void main()
{
float exposureAdjustment = texture(ExposureTexture, vec2(0.5)).x;
vec4 color = texture(SceneTexture, Offset + TexCoord * Scale);
FragColor = max(vec4((color.rgb + vec3(0.001)) * exposureAdjustment - 1, 1), vec4(0));
}

View file

@ -0,0 +1,28 @@
layout(location=0) in vec2 TexCoord;
layout(location=0) out vec4 FragColor;
layout(binding=0) uniform sampler2D SourceTexture;
void main()
{
#if defined(BLUR_HORIZONTAL)
FragColor =
textureOffset(SourceTexture, TexCoord, ivec2( 0, 0)) * SampleWeights0 +
textureOffset(SourceTexture, TexCoord, ivec2( 1, 0)) * SampleWeights1 +
textureOffset(SourceTexture, TexCoord, ivec2(-1, 0)) * SampleWeights2 +
textureOffset(SourceTexture, TexCoord, ivec2( 2, 0)) * SampleWeights3 +
textureOffset(SourceTexture, TexCoord, ivec2(-2, 0)) * SampleWeights4 +
textureOffset(SourceTexture, TexCoord, ivec2( 3, 0)) * SampleWeights5 +
textureOffset(SourceTexture, TexCoord, ivec2(-3, 0)) * SampleWeights6;
#else
FragColor =
textureOffset(SourceTexture, TexCoord, ivec2(0, 0)) * SampleWeights0 +
textureOffset(SourceTexture, TexCoord, ivec2(0, 1)) * SampleWeights1 +
textureOffset(SourceTexture, TexCoord, ivec2(0,-1)) * SampleWeights2 +
textureOffset(SourceTexture, TexCoord, ivec2(0, 2)) * SampleWeights3 +
textureOffset(SourceTexture, TexCoord, ivec2(0,-2)) * SampleWeights4 +
textureOffset(SourceTexture, TexCoord, ivec2(0, 3)) * SampleWeights5 +
textureOffset(SourceTexture, TexCoord, ivec2(0,-3)) * SampleWeights6;
#endif
}

View file

@ -0,0 +1,13 @@
layout(location=0) in vec2 TexCoord;
layout(location=0) out vec4 FragColor;
layout(binding=0) uniform sampler2D SceneTexture;
void main()
{
vec4 frag = texture(SceneTexture, TexCoord);
float gray = (frag.r * 0.3 + frag.g * 0.56 + frag.b * 0.14);
vec4 cm = uFixedColormapStart + gray * uFixedColormapRange;
FragColor = vec4(clamp(cm.rgb, 0.0, 1.0), frag.a);
}

View file

@ -0,0 +1,54 @@
layout(location=0) in vec2 TexCoord;
layout(location=0) out vec4 FragColor;
layout(binding=0) uniform sampler2D AODepthTexture;
#define KERNEL_RADIUS 3.0
void AddSample(vec2 blurSample, float r, float centerDepth, inout float totalAO, inout float totalW)
{
const float blurSigma = KERNEL_RADIUS * 0.5;
const float blurFalloff = 1.0 / (2.0 * blurSigma * blurSigma);
float ao = blurSample.x;
float z = blurSample.y;
float deltaZ = (z - centerDepth) * BlurSharpness;
float w = exp2(-r * r * blurFalloff - deltaZ * deltaZ);
totalAO += w * ao;
totalW += w;
}
void main()
{
vec2 centerSample = textureOffset(AODepthTexture, TexCoord, ivec2( 0, 0)).xy;
float centerDepth = centerSample.y;
float totalAO = centerSample.x;
float totalW = 1.0;
#if defined(BLUR_HORIZONTAL)
AddSample(textureOffset(AODepthTexture, TexCoord, ivec2(-3, 0)).xy, 3.0, centerDepth, totalAO, totalW);
AddSample(textureOffset(AODepthTexture, TexCoord, ivec2(-2, 0)).xy, 2.0, centerDepth, totalAO, totalW);
AddSample(textureOffset(AODepthTexture, TexCoord, ivec2(-1, 0)).xy, 1.0, centerDepth, totalAO, totalW);
AddSample(textureOffset(AODepthTexture, TexCoord, ivec2( 1, 0)).xy, 1.0, centerDepth, totalAO, totalW);
AddSample(textureOffset(AODepthTexture, TexCoord, ivec2( 2, 0)).xy, 2.0, centerDepth, totalAO, totalW);
AddSample(textureOffset(AODepthTexture, TexCoord, ivec2( 3, 0)).xy, 3.0, centerDepth, totalAO, totalW);
#else
AddSample(textureOffset(AODepthTexture, TexCoord, ivec2(0, -3)).xy, 3.0, centerDepth, totalAO, totalW);
AddSample(textureOffset(AODepthTexture, TexCoord, ivec2(0, -2)).xy, 2.0, centerDepth, totalAO, totalW);
AddSample(textureOffset(AODepthTexture, TexCoord, ivec2(0, -1)).xy, 1.0, centerDepth, totalAO, totalW);
AddSample(textureOffset(AODepthTexture, TexCoord, ivec2(0, 1)).xy, 1.0, centerDepth, totalAO, totalW);
AddSample(textureOffset(AODepthTexture, TexCoord, ivec2(0, 2)).xy, 2.0, centerDepth, totalAO, totalW);
AddSample(textureOffset(AODepthTexture, TexCoord, ivec2(0, 3)).xy, 3.0, centerDepth, totalAO, totalW);
#endif
float fragAO = totalAO / totalW;
#if defined(BLUR_HORIZONTAL)
FragColor = vec4(fragAO, centerDepth, 0.0, 1.0);
#else
FragColor = vec4(pow(clamp(fragAO, 0.0, 1.0), PowExponent), 0.0, 0.0, 1.0);
#endif
}

View file

@ -0,0 +1,22 @@
layout(location=0) in vec2 TexCoord;
layout(location=0) out vec4 FragColor;
layout(binding=0) uniform sampler2D ExposureTexture;
void main()
{
#if __VERSION__ < 400
ivec2 size = textureSize(ExposureTexture, 0);
ivec2 tl = max(ivec2(TexCoord * vec2(size) - 0.5), ivec2(0));
ivec2 br = min(tl + ivec2(1), size - ivec2(1));
vec4 values = vec4(
texelFetch(ExposureTexture, tl, 0).x,
texelFetch(ExposureTexture, ivec2(tl.x, br.y), 0).x,
texelFetch(ExposureTexture, ivec2(br.x, tl.y), 0).x,
texelFetch(ExposureTexture, br, 0).x);
#else
vec4 values = textureGather(ExposureTexture, TexCoord);
#endif
FragColor = vec4((values.x + values.y + values.z + values.w) * 0.25, 0.0, 0.0, 1.0);
}

View file

@ -0,0 +1,12 @@
layout(location=0) in vec2 TexCoord;
layout(location=0) out vec4 FragColor;
layout(binding=0) uniform sampler2D ExposureTexture;
void main()
{
float light = texture(ExposureTexture, TexCoord).x;
float exposureAdjustment = 1.0 / max(ExposureBase + light * ExposureScale, ExposureMin);
FragColor = vec4(exposureAdjustment, 0.0, 0.0, ExposureSpeed);
}

View file

@ -0,0 +1,11 @@
layout(location=0) in vec2 TexCoord;
layout(location=0) out vec4 FragColor;
layout(binding=0) uniform sampler2D SceneTexture;
void main()
{
vec4 color = texture(SceneTexture, Offset + TexCoord * Scale);
FragColor = vec4(max(max(color.r, color.g), color.b), 0.0, 0.0, 1.0);
}

View file

@ -0,0 +1,613 @@
//----------------------------------------------------------------------------------
// File: es3-kepler\FXAA/FXAA3_11.h
// SDK Version: v3.00
// Email: gameworks@nvidia.com
// Site: http://developer.nvidia.com/
//
// Copyright (c) 2014-2015, NVIDIA CORPORATION. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * 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.
// * Neither the name of NVIDIA CORPORATION nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``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 COPYRIGHT OWNER OR
// CONTRIBUTORS 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.
//
//----------------------------------------------------------------------------------
layout(location=0) in vec2 TexCoord;
layout(location=0) out vec4 FragColor;
layout(binding=0) uniform sampler2D InputTexture;
#ifdef FXAA_LUMA_PASS
void main()
{
vec3 tex = texture(InputTexture, TexCoord).rgb;
vec3 luma = vec3(0.299, 0.587, 0.114);
FragColor = vec4(tex, dot(tex, luma));
}
#else // FXAA itself
//============================================================================
// NVIDIA FXAA 3.11 by TIMOTHY LOTTES
//============================================================================
#define FXAA_DISCARD 0
#define FXAA_GREEN_AS_LUMA 0
#define FxaaBool bool
#define FxaaDiscard discard
#define FxaaFloat float
#define FxaaFloat2 vec2
#define FxaaFloat3 vec3
#define FxaaFloat4 vec4
#define FxaaHalf float
#define FxaaHalf2 vec2
#define FxaaHalf3 vec3
#define FxaaHalf4 vec4
#define FxaaInt2 ivec2
#define FxaaSat(x) clamp(x, 0.0, 1.0)
#define FxaaTex sampler2D
#define FxaaTexTop(t, p) textureLod(t, p, 0.0)
#define FxaaTexOff(t, p, o, r) textureLodOffset(t, p, 0.0, o)
#if (FXAA_GATHER4_ALPHA == 1)
#define FxaaTexAlpha4(t, p) textureGather(t, p, 3)
#define FxaaTexOffAlpha4(t, p, o) textureGatherOffset(t, p, o, 3)
#define FxaaTexGreen4(t, p) textureGather(t, p, 1)
#define FxaaTexOffGreen4(t, p, o) textureGatherOffset(t, p, o, 1)
#endif
#if (FXAA_GREEN_AS_LUMA == 0)
FxaaFloat FxaaLuma(FxaaFloat4 rgba) { return rgba.w; }
#else
FxaaFloat FxaaLuma(FxaaFloat4 rgba) { return rgba.y; }
#endif
#if (FXAA_QUALITY__PRESET == 10)
#define FXAA_QUALITY__PS 3
#define FXAA_QUALITY__P0 1.5
#define FXAA_QUALITY__P1 3.0
#define FXAA_QUALITY__P2 12.0
#elif (FXAA_QUALITY__PRESET == 11)
#define FXAA_QUALITY__PS 4
#define FXAA_QUALITY__P0 1.0
#define FXAA_QUALITY__P1 1.5
#define FXAA_QUALITY__P2 3.0
#define FXAA_QUALITY__P3 12.0
#elif (FXAA_QUALITY__PRESET == 12)
#define FXAA_QUALITY__PS 5
#define FXAA_QUALITY__P0 1.0
#define FXAA_QUALITY__P1 1.5
#define FXAA_QUALITY__P2 2.0
#define FXAA_QUALITY__P3 4.0
#define FXAA_QUALITY__P4 12.0
#elif (FXAA_QUALITY__PRESET == 13)
#define FXAA_QUALITY__PS 6
#define FXAA_QUALITY__P0 1.0
#define FXAA_QUALITY__P1 1.5
#define FXAA_QUALITY__P2 2.0
#define FXAA_QUALITY__P3 2.0
#define FXAA_QUALITY__P4 4.0
#define FXAA_QUALITY__P5 12.0
#elif (FXAA_QUALITY__PRESET == 14)
#define FXAA_QUALITY__PS 7
#define FXAA_QUALITY__P0 1.0
#define FXAA_QUALITY__P1 1.5
#define FXAA_QUALITY__P2 2.0
#define FXAA_QUALITY__P3 2.0
#define FXAA_QUALITY__P4 2.0
#define FXAA_QUALITY__P5 4.0
#define FXAA_QUALITY__P6 12.0
#elif (FXAA_QUALITY__PRESET == 15)
#define FXAA_QUALITY__PS 8
#define FXAA_QUALITY__P0 1.0
#define FXAA_QUALITY__P1 1.5
#define FXAA_QUALITY__P2 2.0
#define FXAA_QUALITY__P3 2.0
#define FXAA_QUALITY__P4 2.0
#define FXAA_QUALITY__P5 2.0
#define FXAA_QUALITY__P6 4.0
#define FXAA_QUALITY__P7 12.0
#elif (FXAA_QUALITY__PRESET == 20)
#define FXAA_QUALITY__PS 3
#define FXAA_QUALITY__P0 1.5
#define FXAA_QUALITY__P1 2.0
#define FXAA_QUALITY__P2 8.0
#elif (FXAA_QUALITY__PRESET == 21)
#define FXAA_QUALITY__PS 4
#define FXAA_QUALITY__P0 1.0
#define FXAA_QUALITY__P1 1.5
#define FXAA_QUALITY__P2 2.0
#define FXAA_QUALITY__P3 8.0
#elif (FXAA_QUALITY__PRESET == 22)
#define FXAA_QUALITY__PS 5
#define FXAA_QUALITY__P0 1.0
#define FXAA_QUALITY__P1 1.5
#define FXAA_QUALITY__P2 2.0
#define FXAA_QUALITY__P3 2.0
#define FXAA_QUALITY__P4 8.0
#elif (FXAA_QUALITY__PRESET == 23)
#define FXAA_QUALITY__PS 6
#define FXAA_QUALITY__P0 1.0
#define FXAA_QUALITY__P1 1.5
#define FXAA_QUALITY__P2 2.0
#define FXAA_QUALITY__P3 2.0
#define FXAA_QUALITY__P4 2.0
#define FXAA_QUALITY__P5 8.0
#elif (FXAA_QUALITY__PRESET == 24)
#define FXAA_QUALITY__PS 7
#define FXAA_QUALITY__P0 1.0
#define FXAA_QUALITY__P1 1.5
#define FXAA_QUALITY__P2 2.0
#define FXAA_QUALITY__P3 2.0
#define FXAA_QUALITY__P4 2.0
#define FXAA_QUALITY__P5 3.0
#define FXAA_QUALITY__P6 8.0
#elif (FXAA_QUALITY__PRESET == 25)
#define FXAA_QUALITY__PS 8
#define FXAA_QUALITY__P0 1.0
#define FXAA_QUALITY__P1 1.5
#define FXAA_QUALITY__P2 2.0
#define FXAA_QUALITY__P3 2.0
#define FXAA_QUALITY__P4 2.0
#define FXAA_QUALITY__P5 2.0
#define FXAA_QUALITY__P6 4.0
#define FXAA_QUALITY__P7 8.0
#elif (FXAA_QUALITY__PRESET == 26)
#define FXAA_QUALITY__PS 9
#define FXAA_QUALITY__P0 1.0
#define FXAA_QUALITY__P1 1.5
#define FXAA_QUALITY__P2 2.0
#define FXAA_QUALITY__P3 2.0
#define FXAA_QUALITY__P4 2.0
#define FXAA_QUALITY__P5 2.0
#define FXAA_QUALITY__P6 2.0
#define FXAA_QUALITY__P7 4.0
#define FXAA_QUALITY__P8 8.0
#elif (FXAA_QUALITY__PRESET == 27)
#define FXAA_QUALITY__PS 10
#define FXAA_QUALITY__P0 1.0
#define FXAA_QUALITY__P1 1.5
#define FXAA_QUALITY__P2 2.0
#define FXAA_QUALITY__P3 2.0
#define FXAA_QUALITY__P4 2.0
#define FXAA_QUALITY__P5 2.0
#define FXAA_QUALITY__P6 2.0
#define FXAA_QUALITY__P7 2.0
#define FXAA_QUALITY__P8 4.0
#define FXAA_QUALITY__P9 8.0
#elif (FXAA_QUALITY__PRESET == 28)
#define FXAA_QUALITY__PS 11
#define FXAA_QUALITY__P0 1.0
#define FXAA_QUALITY__P1 1.5
#define FXAA_QUALITY__P2 2.0
#define FXAA_QUALITY__P3 2.0
#define FXAA_QUALITY__P4 2.0
#define FXAA_QUALITY__P5 2.0
#define FXAA_QUALITY__P6 2.0
#define FXAA_QUALITY__P7 2.0
#define FXAA_QUALITY__P8 2.0
#define FXAA_QUALITY__P9 4.0
#define FXAA_QUALITY__P10 8.0
#elif (FXAA_QUALITY__PRESET == 29)
#define FXAA_QUALITY__PS 12
#define FXAA_QUALITY__P0 1.0
#define FXAA_QUALITY__P1 1.5
#define FXAA_QUALITY__P2 2.0
#define FXAA_QUALITY__P3 2.0
#define FXAA_QUALITY__P4 2.0
#define FXAA_QUALITY__P5 2.0
#define FXAA_QUALITY__P6 2.0
#define FXAA_QUALITY__P7 2.0
#define FXAA_QUALITY__P8 2.0
#define FXAA_QUALITY__P9 2.0
#define FXAA_QUALITY__P10 4.0
#define FXAA_QUALITY__P11 8.0
#elif (FXAA_QUALITY__PRESET == 39)
#define FXAA_QUALITY__PS 12
#define FXAA_QUALITY__P0 1.0
#define FXAA_QUALITY__P1 1.0
#define FXAA_QUALITY__P2 1.0
#define FXAA_QUALITY__P3 1.0
#define FXAA_QUALITY__P4 1.0
#define FXAA_QUALITY__P5 1.5
#define FXAA_QUALITY__P6 2.0
#define FXAA_QUALITY__P7 2.0
#define FXAA_QUALITY__P8 2.0
#define FXAA_QUALITY__P9 2.0
#define FXAA_QUALITY__P10 4.0
#define FXAA_QUALITY__P11 8.0
#endif
FxaaFloat4 FxaaPixelShader(FxaaFloat2 pos, FxaaTex tex, FxaaFloat2 fxaaQualityRcpFrame,
FxaaFloat fxaaQualitySubpix, FxaaFloat fxaaQualityEdgeThreshold, FxaaFloat fxaaQualityEdgeThresholdMin)
{
FxaaFloat2 posM;
posM.x = pos.x;
posM.y = pos.y;
#if (FXAA_GATHER4_ALPHA == 1)
#if (FXAA_DISCARD == 0)
FxaaFloat4 rgbyM = FxaaTexTop(tex, posM);
#if (FXAA_GREEN_AS_LUMA == 0)
#define lumaM rgbyM.w
#else
#define lumaM rgbyM.y
#endif
#endif
#if (FXAA_GREEN_AS_LUMA == 0)
FxaaFloat4 luma4A = FxaaTexAlpha4(tex, posM);
FxaaFloat4 luma4B = FxaaTexOffAlpha4(tex, posM, FxaaInt2(-1, -1));
#else
FxaaFloat4 luma4A = FxaaTexGreen4(tex, posM);
FxaaFloat4 luma4B = FxaaTexOffGreen4(tex, posM, FxaaInt2(-1, -1));
#endif
#if (FXAA_DISCARD == 1)
#define lumaM luma4A.w
#endif
#define lumaE luma4A.z
#define lumaS luma4A.x
#define lumaSE luma4A.y
#define lumaNW luma4B.w
#define lumaN luma4B.z
#define lumaW luma4B.x
#else
FxaaFloat4 rgbyM = FxaaTexTop(tex, posM);
#if (FXAA_GREEN_AS_LUMA == 0)
#define lumaM rgbyM.w
#else
#define lumaM rgbyM.y
#endif
FxaaFloat lumaS = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 0, 1), fxaaQualityRcpFrame.xy));
FxaaFloat lumaE = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 1, 0), fxaaQualityRcpFrame.xy));
FxaaFloat lumaN = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 0,-1), fxaaQualityRcpFrame.xy));
FxaaFloat lumaW = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(-1, 0), fxaaQualityRcpFrame.xy));
#endif
/*--------------------------------------------------------------------------*/
FxaaFloat maxSM = max(lumaS, lumaM);
FxaaFloat minSM = min(lumaS, lumaM);
FxaaFloat maxESM = max(lumaE, maxSM);
FxaaFloat minESM = min(lumaE, minSM);
FxaaFloat maxWN = max(lumaN, lumaW);
FxaaFloat minWN = min(lumaN, lumaW);
FxaaFloat rangeMax = max(maxWN, maxESM);
FxaaFloat rangeMin = min(minWN, minESM);
FxaaFloat rangeMaxScaled = rangeMax * fxaaQualityEdgeThreshold;
FxaaFloat range = rangeMax - rangeMin;
FxaaFloat rangeMaxClamped = max(fxaaQualityEdgeThresholdMin, rangeMaxScaled);
FxaaBool earlyExit = range < rangeMaxClamped;
/*--------------------------------------------------------------------------*/
if(earlyExit)
#if (FXAA_DISCARD == 1)
FxaaDiscard;
#else
return rgbyM;
#endif
/*--------------------------------------------------------------------------*/
#if (FXAA_GATHER4_ALPHA == 0)
FxaaFloat lumaNW = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(-1,-1), fxaaQualityRcpFrame.xy));
FxaaFloat lumaSE = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 1, 1), fxaaQualityRcpFrame.xy));
FxaaFloat lumaNE = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 1,-1), fxaaQualityRcpFrame.xy));
FxaaFloat lumaSW = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(-1, 1), fxaaQualityRcpFrame.xy));
#else
FxaaFloat lumaNE = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(1, -1), fxaaQualityRcpFrame.xy));
FxaaFloat lumaSW = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(-1, 1), fxaaQualityRcpFrame.xy));
#endif
/*--------------------------------------------------------------------------*/
FxaaFloat lumaNS = lumaN + lumaS;
FxaaFloat lumaWE = lumaW + lumaE;
FxaaFloat subpixRcpRange = 1.0/range;
FxaaFloat subpixNSWE = lumaNS + lumaWE;
FxaaFloat edgeHorz1 = (-2.0 * lumaM) + lumaNS;
FxaaFloat edgeVert1 = (-2.0 * lumaM) + lumaWE;
/*--------------------------------------------------------------------------*/
FxaaFloat lumaNESE = lumaNE + lumaSE;
FxaaFloat lumaNWNE = lumaNW + lumaNE;
FxaaFloat edgeHorz2 = (-2.0 * lumaE) + lumaNESE;
FxaaFloat edgeVert2 = (-2.0 * lumaN) + lumaNWNE;
/*--------------------------------------------------------------------------*/
FxaaFloat lumaNWSW = lumaNW + lumaSW;
FxaaFloat lumaSWSE = lumaSW + lumaSE;
FxaaFloat edgeHorz4 = (abs(edgeHorz1) * 2.0) + abs(edgeHorz2);
FxaaFloat edgeVert4 = (abs(edgeVert1) * 2.0) + abs(edgeVert2);
FxaaFloat edgeHorz3 = (-2.0 * lumaW) + lumaNWSW;
FxaaFloat edgeVert3 = (-2.0 * lumaS) + lumaSWSE;
FxaaFloat edgeHorz = abs(edgeHorz3) + edgeHorz4;
FxaaFloat edgeVert = abs(edgeVert3) + edgeVert4;
/*--------------------------------------------------------------------------*/
FxaaFloat subpixNWSWNESE = lumaNWSW + lumaNESE;
FxaaFloat lengthSign = fxaaQualityRcpFrame.x;
FxaaBool horzSpan = edgeHorz >= edgeVert;
FxaaFloat subpixA = subpixNSWE * 2.0 + subpixNWSWNESE;
/*--------------------------------------------------------------------------*/
if(!horzSpan) lumaN = lumaW;
if(!horzSpan) lumaS = lumaE;
if(horzSpan) lengthSign = fxaaQualityRcpFrame.y;
FxaaFloat subpixB = (subpixA * (1.0/12.0)) - lumaM;
/*--------------------------------------------------------------------------*/
FxaaFloat gradientN = lumaN - lumaM;
FxaaFloat gradientS = lumaS - lumaM;
FxaaFloat lumaNN = lumaN + lumaM;
FxaaFloat lumaSS = lumaS + lumaM;
FxaaBool pairN = abs(gradientN) >= abs(gradientS);
FxaaFloat gradient = max(abs(gradientN), abs(gradientS));
if(pairN) lengthSign = -lengthSign;
FxaaFloat subpixC = FxaaSat(abs(subpixB) * subpixRcpRange);
/*--------------------------------------------------------------------------*/
FxaaFloat2 posB;
posB.x = posM.x;
posB.y = posM.y;
FxaaFloat2 offNP;
offNP.x = (!horzSpan) ? 0.0 : fxaaQualityRcpFrame.x;
offNP.y = ( horzSpan) ? 0.0 : fxaaQualityRcpFrame.y;
if(!horzSpan) posB.x += lengthSign * 0.5;
if( horzSpan) posB.y += lengthSign * 0.5;
/*--------------------------------------------------------------------------*/
FxaaFloat2 posN;
posN.x = posB.x - offNP.x * FXAA_QUALITY__P0;
posN.y = posB.y - offNP.y * FXAA_QUALITY__P0;
FxaaFloat2 posP;
posP.x = posB.x + offNP.x * FXAA_QUALITY__P0;
posP.y = posB.y + offNP.y * FXAA_QUALITY__P0;
FxaaFloat subpixD = ((-2.0)*subpixC) + 3.0;
FxaaFloat lumaEndN = FxaaLuma(FxaaTexTop(tex, posN));
FxaaFloat subpixE = subpixC * subpixC;
FxaaFloat lumaEndP = FxaaLuma(FxaaTexTop(tex, posP));
/*--------------------------------------------------------------------------*/
if(!pairN) lumaNN = lumaSS;
FxaaFloat gradientScaled = gradient * 1.0/4.0;
FxaaFloat lumaMM = lumaM - lumaNN * 0.5;
FxaaFloat subpixF = subpixD * subpixE;
FxaaBool lumaMLTZero = lumaMM < 0.0;
/*--------------------------------------------------------------------------*/
lumaEndN -= lumaNN * 0.5;
lumaEndP -= lumaNN * 0.5;
FxaaBool doneN = abs(lumaEndN) >= gradientScaled;
FxaaBool doneP = abs(lumaEndP) >= gradientScaled;
if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P1;
if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P1;
FxaaBool doneNP = (!doneN) || (!doneP);
if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P1;
if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P1;
/*--------------------------------------------------------------------------*/
if(doneNP) {
if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
doneN = abs(lumaEndN) >= gradientScaled;
doneP = abs(lumaEndP) >= gradientScaled;
if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P2;
if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P2;
doneNP = (!doneN) || (!doneP);
if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P2;
if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P2;
/*--------------------------------------------------------------------------*/
#if (FXAA_QUALITY__PS > 3)
if(doneNP) {
if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
doneN = abs(lumaEndN) >= gradientScaled;
doneP = abs(lumaEndP) >= gradientScaled;
if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P3;
if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P3;
doneNP = (!doneN) || (!doneP);
if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P3;
if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P3;
/*--------------------------------------------------------------------------*/
#if (FXAA_QUALITY__PS > 4)
if(doneNP) {
if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
doneN = abs(lumaEndN) >= gradientScaled;
doneP = abs(lumaEndP) >= gradientScaled;
if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P4;
if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P4;
doneNP = (!doneN) || (!doneP);
if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P4;
if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P4;
/*--------------------------------------------------------------------------*/
#if (FXAA_QUALITY__PS > 5)
if(doneNP) {
if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
doneN = abs(lumaEndN) >= gradientScaled;
doneP = abs(lumaEndP) >= gradientScaled;
if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P5;
if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P5;
doneNP = (!doneN) || (!doneP);
if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P5;
if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P5;
/*--------------------------------------------------------------------------*/
#if (FXAA_QUALITY__PS > 6)
if(doneNP) {
if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
doneN = abs(lumaEndN) >= gradientScaled;
doneP = abs(lumaEndP) >= gradientScaled;
if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P6;
if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P6;
doneNP = (!doneN) || (!doneP);
if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P6;
if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P6;
/*--------------------------------------------------------------------------*/
#if (FXAA_QUALITY__PS > 7)
if(doneNP) {
if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
doneN = abs(lumaEndN) >= gradientScaled;
doneP = abs(lumaEndP) >= gradientScaled;
if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P7;
if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P7;
doneNP = (!doneN) || (!doneP);
if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P7;
if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P7;
/*--------------------------------------------------------------------------*/
#if (FXAA_QUALITY__PS > 8)
if(doneNP) {
if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
doneN = abs(lumaEndN) >= gradientScaled;
doneP = abs(lumaEndP) >= gradientScaled;
if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P8;
if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P8;
doneNP = (!doneN) || (!doneP);
if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P8;
if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P8;
/*--------------------------------------------------------------------------*/
#if (FXAA_QUALITY__PS > 9)
if(doneNP) {
if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
doneN = abs(lumaEndN) >= gradientScaled;
doneP = abs(lumaEndP) >= gradientScaled;
if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P9;
if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P9;
doneNP = (!doneN) || (!doneP);
if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P9;
if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P9;
/*--------------------------------------------------------------------------*/
#if (FXAA_QUALITY__PS > 10)
if(doneNP) {
if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
doneN = abs(lumaEndN) >= gradientScaled;
doneP = abs(lumaEndP) >= gradientScaled;
if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P10;
if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P10;
doneNP = (!doneN) || (!doneP);
if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P10;
if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P10;
/*--------------------------------------------------------------------------*/
#if (FXAA_QUALITY__PS > 11)
if(doneNP) {
if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
doneN = abs(lumaEndN) >= gradientScaled;
doneP = abs(lumaEndP) >= gradientScaled;
if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P11;
if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P11;
doneNP = (!doneN) || (!doneP);
if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P11;
if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P11;
/*--------------------------------------------------------------------------*/
#if (FXAA_QUALITY__PS > 12)
if(doneNP) {
if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
doneN = abs(lumaEndN) >= gradientScaled;
doneP = abs(lumaEndP) >= gradientScaled;
if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P12;
if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P12;
doneNP = (!doneN) || (!doneP);
if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P12;
if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P12;
/*--------------------------------------------------------------------------*/
}
#endif
/*--------------------------------------------------------------------------*/
}
#endif
/*--------------------------------------------------------------------------*/
}
#endif
/*--------------------------------------------------------------------------*/
}
#endif
/*--------------------------------------------------------------------------*/
}
#endif
/*--------------------------------------------------------------------------*/
}
#endif
/*--------------------------------------------------------------------------*/
}
#endif
/*--------------------------------------------------------------------------*/
}
#endif
/*--------------------------------------------------------------------------*/
}
#endif
/*--------------------------------------------------------------------------*/
}
#endif
/*--------------------------------------------------------------------------*/
}
/*--------------------------------------------------------------------------*/
FxaaFloat dstN = posM.x - posN.x;
FxaaFloat dstP = posP.x - posM.x;
if(!horzSpan) dstN = posM.y - posN.y;
if(!horzSpan) dstP = posP.y - posM.y;
/*--------------------------------------------------------------------------*/
FxaaBool goodSpanN = (lumaEndN < 0.0) != lumaMLTZero;
FxaaFloat spanLength = (dstP + dstN);
FxaaBool goodSpanP = (lumaEndP < 0.0) != lumaMLTZero;
FxaaFloat spanLengthRcp = 1.0/spanLength;
/*--------------------------------------------------------------------------*/
FxaaBool directionN = dstN < dstP;
FxaaFloat dst = min(dstN, dstP);
FxaaBool goodSpan = directionN ? goodSpanN : goodSpanP;
FxaaFloat subpixG = subpixF * subpixF;
FxaaFloat pixelOffset = (dst * (-spanLengthRcp)) + 0.5;
FxaaFloat subpixH = subpixG * fxaaQualitySubpix;
/*--------------------------------------------------------------------------*/
FxaaFloat pixelOffsetGood = goodSpan ? pixelOffset : 0.0;
FxaaFloat pixelOffsetSubpix = max(pixelOffsetGood, subpixH);
if(!horzSpan) posM.x += pixelOffsetSubpix * lengthSign;
if( horzSpan) posM.y += pixelOffsetSubpix * lengthSign;
#if (FXAA_DISCARD == 1)
return FxaaTexTop(tex, posM);
#else
return FxaaFloat4(FxaaTexTop(tex, posM).xyz, lumaM);
#endif
}
void main()
{
FragColor = FxaaPixelShader(TexCoord, InputTexture, ReciprocalResolution, 0.75f, 0.166f, 0.0833f);
}
#endif // FXAA_LUMA_PASS

View file

@ -0,0 +1,54 @@
/*
Original Lens Distortion Algorithm from SSontech
http://www.ssontech.com/content/lensalg.htm
If (u,v) are the coordinates of a feature in the undistorted perfect
image plane, then (u', v') are the coordinates of the feature on the
distorted image plate, ie the scanned or captured image from the
camera. The distortion occurs radially away from the image center,
with correction for the image aspect ratio (image_aspect = physical
image width/height), as follows:
r2 = image_aspect*image_aspect*u*u + v*v
f = 1 + r2*(k + kcube*sqrt(r2))
u' = f*u
v' = f*v
The constant k is the distortion coefficient that appears on the lens
panel and through Sizzle. It is generally a small positive or negative
number under 1%. The constant kcube is the cubic distortion value found
on the image preprocessor's lens panel: it can be used to undistort or
redistort images, but it does not affect or get computed by the solver.
When no cubic distortion is needed, neither is the square root, saving
time.
Chromatic Aberration example,
using red distord channel with green and blue undistord channel:
k = vec3(-0.15, 0.0, 0.0);
kcube = vec3(0.15, 0.0, 0.0);
*/
layout(location=0) in vec2 TexCoord;
layout(location=0) out vec4 FragColor;
layout(binding=0) uniform sampler2D InputTexture;
void main()
{
vec2 position = (TexCoord - vec2(0.5));
vec2 p = vec2(position.x * Aspect, position.y);
float r2 = dot(p, p);
vec3 f = vec3(1.0) + r2 * (k.rgb + kcube.rgb * sqrt(r2));
vec3 x = f * position.x * Scale + 0.5;
vec3 y = f * position.y * Scale + 0.5;
vec3 c;
c.r = texture(InputTexture, vec2(x.r, y.r)).r;
c.g = texture(InputTexture, vec2(x.g, y.g)).g;
c.b = texture(InputTexture, vec2(x.b, y.b)).b;
FragColor = vec4(c, 1.0);
}

View file

@ -0,0 +1,38 @@
layout(location=0) in vec2 TexCoord;
layout(location=0) out vec4 FragColor;
#if defined(MULTISAMPLE)
layout(binding=0) uniform sampler2DMS DepthTexture;
layout(binding=1) uniform sampler2DMS ColorTexture;
#else
layout(binding=0) uniform sampler2D DepthTexture;
layout(binding=1) uniform sampler2D ColorTexture;
#endif
float normalizeDepth(float depth)
{
float normalizedDepth = clamp(InverseDepthRangeA * depth + InverseDepthRangeB, 0.0, 1.0);
return 1.0 / (normalizedDepth * LinearizeDepthA + LinearizeDepthB);
}
void main()
{
vec2 uv = Offset + TexCoord * Scale;
#if defined(MULTISAMPLE)
ivec2 texSize = textureSize(DepthTexture);
#else
ivec2 texSize = textureSize(DepthTexture, 0);
#endif
ivec2 ipos = ivec2(max(uv * vec2(texSize), vec2(0.0)));
#if defined(MULTISAMPLE)
float depth = normalizeDepth(texelFetch(ColorTexture, ipos, SampleIndex).a != 0.0 ? texelFetch(DepthTexture, ipos, SampleIndex).x : 1.0);
#else
float depth = normalizeDepth(texelFetch(ColorTexture, ipos, 0).a != 0.0 ? texelFetch(DepthTexture, ipos, 0).x : 1.0);
#endif
FragColor = vec4(depth, 0.0, 0.0, 1.0);
}

View file

@ -0,0 +1,48 @@
layout(location=0) in vec2 TexCoord;
layout(location=0) out vec4 FragColor;
layout(binding=0) uniform sampler2D InputTexture;
layout(binding=1) uniform sampler2D DitherTexture;
vec4 ApplyGamma(vec4 c)
{
c.rgb = min(c.rgb, vec3(2.0)); // for HDR mode - prevents stacked translucent sprites (such as plasma) producing way too bright light
vec3 valgray;
if (GrayFormula == 0)
valgray = vec3(c.r + c.g + c.b) * (1 - Saturation) / 3 + c.rgb * Saturation;
else
valgray = mix(vec3(dot(c.rgb, vec3(0.3,0.56,0.14))), c.rgb, Saturation);
vec3 val = valgray * Contrast - (Contrast - 1.0) * 0.5;
val += Brightness * 0.5;
val = pow(max(val, vec3(0.0)), vec3(InvGamma));
return vec4(val, c.a);
}
vec4 Dither(vec4 c)
{
if (ColorScale == 0.0)
return c;
vec2 texSize = vec2(textureSize(DitherTexture, 0));
float threshold = texture(DitherTexture, gl_FragCoord.xy / texSize).r;
return vec4(floor(c.rgb * ColorScale + threshold) / ColorScale, c.a);
}
vec4 sRGBtoLinear(vec4 c)
{
return vec4(mix(pow((c.rgb + 0.055) / 1.055, vec3(2.4)), c.rgb / 12.92, step(c.rgb, vec3(0.04045))), c.a);
}
vec4 ApplyHdrMode(vec4 c)
{
if (HdrMode == 0)
return c;
else
return sRGBtoLinear(c);
}
void main()
{
FragColor = Dither(ApplyHdrMode(ApplyGamma(texture(InputTexture, UVOffset + TexCoord * UVScale))));
}

View file

@ -0,0 +1,33 @@
layout(location=0) in vec2 TexCoord;
layout(location=0) out vec4 FragColor;
layout(binding=0) uniform sampler2D LeftEyeTexture;
layout(binding=1) uniform sampler2D RightEyeTexture;
vec4 ApplyGamma(vec4 c)
{
vec3 val = c.rgb * Contrast - (Contrast - 1.0) * 0.5;
val += Brightness * 0.5;
val = pow(max(val, vec3(0.0)), vec3(InvGamma));
return vec4(val, c.a);
}
void main()
{
int thisVerticalPixel = int(gl_FragCoord.y); // Bottom row is typically the right eye, when WindowHeight is even
int thisHorizontalPixel = int(gl_FragCoord.x); // column
bool isLeftEye = (thisVerticalPixel // because we want to alternate eye view on each row
+ thisHorizontalPixel // and each column
+ WindowPositionParity // because the window might not be aligned to the screen
) % 2 == 0;
vec4 inputColor;
if (isLeftEye) {
inputColor = texture(LeftEyeTexture, UVOffset + TexCoord * UVScale);
}
else {
// inputColor = vec4(0, 1, 0, 1);
inputColor = texture(RightEyeTexture, UVOffset + TexCoord * UVScale);
}
FragColor = ApplyGamma(inputColor);
}

View file

@ -0,0 +1,31 @@
layout(location=0) in vec2 TexCoord;
layout(location=0) out vec4 FragColor;
layout(binding=0) uniform sampler2D LeftEyeTexture;
layout(binding=1) uniform sampler2D RightEyeTexture;
vec4 ApplyGamma(vec4 c)
{
vec3 val = c.rgb * Contrast - (Contrast - 1.0) * 0.5;
val += Brightness * 0.5;
val = pow(max(val, vec3(0.0)), vec3(InvGamma));
return vec4(val, c.a);
}
void main()
{
int thisHorizontalPixel = int(gl_FragCoord.x); // zero-based column index from left
bool isLeftEye = (thisHorizontalPixel // because we want to alternate eye view on each column
+ WindowPositionParity // because the window might not be aligned to the screen
) % 2 == 0;
vec4 inputColor;
if (isLeftEye) {
inputColor = texture(LeftEyeTexture, UVOffset + TexCoord * UVScale);
}
else {
// inputColor = vec4(0, 1, 0, 1);
inputColor = texture(RightEyeTexture, UVOffset + TexCoord * UVScale);
}
FragColor = ApplyGamma(inputColor);
}

View file

@ -0,0 +1,31 @@
layout(location=0) in vec2 TexCoord;
layout(location=0) out vec4 FragColor;
layout(binding=0) uniform sampler2D LeftEyeTexture;
layout(binding=1) uniform sampler2D RightEyeTexture;
vec4 ApplyGamma(vec4 c)
{
vec3 val = c.rgb * Contrast - (Contrast - 1.0) * 0.5;
val += Brightness * 0.5;
val = pow(max(val, vec3(0.0)), vec3(InvGamma));
return vec4(val, c.a);
}
void main()
{
int thisVerticalPixel = int(gl_FragCoord.y); // Bottom row is typically the right eye, when WindowHeight is even
bool isLeftEye = (thisVerticalPixel // because we want to alternate eye view on each row
+ WindowPositionParity // because the window might not be aligned to the screen
) % 2 == 0;
vec4 inputColor;
if (isLeftEye) {
inputColor = texture(LeftEyeTexture, UVOffset + TexCoord * UVScale);
}
else {
// inputColor = vec4(0, 1, 0, 1);
inputColor = texture(RightEyeTexture, UVOffset + TexCoord * UVScale);
}
FragColor = ApplyGamma(inputColor);
}

View file

@ -0,0 +1,10 @@
layout(location = 0) in vec4 PositionInProjection;
layout(location = 1) in vec2 UV;
layout(location = 0) out vec2 TexCoord;
void main()
{
gl_Position = PositionInProjection;
TexCoord = UV;
}

View file

@ -0,0 +1,89 @@
layout(location=0) in vec2 TexCoord;
layout(location=0) out vec4 FragColor;
layout(binding=0) uniform sampler2D InputTexture;
vec3 Linear(vec3 c)
{
//c = max(c, vec3(0.0));
//return pow(c, 2.2);
return c * c; // cheaper, but assuming gamma of 2.0 instead of 2.2
}
vec3 sRGB(vec3 c)
{
c = max(c, vec3(0.0));
//return pow(c, vec3(1.0 / 2.2));
return sqrt(c); // cheaper, but assuming gamma of 2.0 instead of 2.2
}
#if defined(LINEAR)
vec3 Tonemap(vec3 color)
{
return sRGB(color);
}
#elif defined(REINHARD)
vec3 Tonemap(vec3 color)
{
color = color / (1 + color);
return sRGB(color);
}
#elif defined(HEJLDAWSON)
vec3 Tonemap(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
}
#elif defined(UNCHARTED2)
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 Tonemap(vec3 color)
{
float W = 11.2;
vec3 curr = Uncharted2Tonemap(color);
vec3 whiteScale = vec3(1) / Uncharted2Tonemap(vec3(W));
return sRGB(curr * whiteScale);
}
#elif defined(PALETTE)
layout(binding=1) uniform sampler2D PaletteLUT;
vec3 Tonemap(vec3 color)
{
ivec3 c = ivec3(clamp(color.rgb, vec3(0.0), vec3(1.0)) * 63.0 + 0.5);
int index = (c.r * 64 + c.g) * 64 + c.b;
int tx = index % 512;
int ty = index / 512;
return texelFetch(PaletteLUT, ivec2(tx, ty), 0).rgb;
}
#else
#error Tonemap mode define is missing
#endif
void main()
{
vec3 color = texture(InputTexture, TexCoord).rgb;
#ifndef PALETTE
color = Linear(color); // needed because gzdoom's scene texture is not linear at the moment
#endif
FragColor = vec4(Tonemap(color), 1.0);
}