diff --git a/source/build/src/engine.cpp b/source/build/src/engine.cpp index 56a56e654..9bfd237eb 100644 --- a/source/build/src/engine.cpp +++ b/source/build/src/engine.cpp @@ -9994,9 +9994,6 @@ void videoNextPage(void) // Draw the console plus debug output on top of everything else. DrawFullscreenBlends(); - GLInterface.Draw2D(&twod); - - videoShowFrame(0); videoBeginDrawing(); //{{{ @@ -11417,13 +11414,11 @@ void videoClearScreen(int32_t dacol) #ifdef USE_OPENGL if (videoGetRenderMode() >= REND_POLYMOST) { - palette_t const p = paletteGetColor(dacol); + glox1 = -1; - GLInterface.SetViewport(0,0,xdim,ydim); glox1 = -1; - GLInterface.ClearScreen((float)p.r * (1.f/255.f), - (float)p.g * (1.f/255.f), - (float)p.b * (1.f/255.f), - false); + palette_t const p = paletteGetColor(dacol); + PalEntry clearcol = PalEntry(255, p.r, p.g, p.b); + GLInterface.ClearScreen(clearcol); return; } #endif @@ -12008,9 +12003,4 @@ void renderSetRollAngle(int32_t rolla) } #endif -void videoShowFrame(int32_t w) -{ - screen->Update(); -} - diff --git a/source/common/rendering/gl/renderer/gl_postprocess.cpp b/source/common/rendering/gl/renderer/gl_postprocess.cpp index 9d092756f..722cdcfc8 100644 --- a/source/common/rendering/gl/renderer/gl_postprocess.cpp +++ b/source/common/rendering/gl/renderer/gl_postprocess.cpp @@ -79,7 +79,7 @@ void FGLRenderer::PostProcessScene(int fixedcm, const std::function &aft hw_postprocess.Pass1(&renderstate, fixedcm, sceneWidth, sceneHeight); mBuffers->BindCurrentFB(); - afterBloomDrawEndScene2D(); + if (afterBloomDrawEndScene2D) afterBloomDrawEndScene2D(); hw_postprocess.Pass2(&renderstate, fixedcm, sceneWidth, sceneHeight); } @@ -132,8 +132,7 @@ void FGLRenderer::Flush() void FGLRenderer::CopyToBackbuffer(const IntRect *bounds, bool applyGamma) { - //screen->Draw2D(); // draw all pending 2D stuff before copying the buffer - //screen->Clear2D(); + screen->Draw2D(); // draw all pending 2D stuff before copying the buffer GLPPRenderState renderstate(mBuffers); diff --git a/source/common/rendering/gl/renderer/gl_renderer.cpp b/source/common/rendering/gl/renderer/gl_renderer.cpp index e672ebfcc..23dfd3fad 100644 --- a/source/common/rendering/gl/renderer/gl_renderer.cpp +++ b/source/common/rendering/gl/renderer/gl_renderer.cpp @@ -62,7 +62,6 @@ void DoWriteSavePic(FileWriter *file, ESSType ssformat, uint8_t *scr, int width, namespace OpenGLRenderer { - FGLRenderer* GLRenderer; //=========================================================================== // // Renderer interface diff --git a/source/common/rendering/gl/shaders/gl_shaderprogram.cpp b/source/common/rendering/gl/shaders/gl_shaderprogram.cpp index 8e80b2b1f..40c35f518 100644 --- a/source/common/rendering/gl/shaders/gl_shaderprogram.cpp +++ b/source/common/rendering/gl/shaders/gl_shaderprogram.cpp @@ -306,7 +306,7 @@ void FPresentShaderBase::Init(const char * vtx_shader_name, const char * program FString prolog = Uniforms.CreateDeclaration("Uniforms", PresentUniforms::Desc()); 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->Link(program_name); mShader->SetUniformBufferLocation(Uniforms.BindingPoint(), "Uniforms"); @@ -317,7 +317,7 @@ void FPresentShader::Bind() { if (!mShader) { - Init("shaders/glsl/present.fp", "shaders/glsl/present"); + Init("engine/shaders/pp/present.fp", "engine/shaders/pp/present"); } mShader->Bind(); } @@ -328,7 +328,7 @@ void FPresent3DCheckerShader::Bind() { if (!mShader) { - Init("shaders/glsl/present_checker3d.fp", "shaders/glsl/presentChecker3d"); + Init("engine/shaders/pp/present_checker3d.fp", "engine/shaders/pp/presentChecker3d"); } mShader->Bind(); } @@ -337,7 +337,7 @@ void FPresent3DColumnShader::Bind() { if (!mShader) { - Init("shaders/glsl/present_column3d.fp", "shaders/glsl/presentColumn3d"); + Init("engine/shaders/pp/present_column3d.fp", "engine/shaders/pp/presentColumn3d"); } mShader->Bind(); } @@ -346,7 +346,7 @@ void FPresent3DRowShader::Bind() { if (!mShader) { - Init("shaders/glsl/present_row3d.fp", "shaders/glsl/presentRow3d"); + Init("engine/shaders/pp/present_row3d.fp", "engine/shaders/pp/presentRow3d"); } mShader->Bind(); } diff --git a/source/common/rendering/gl/system/gl_framebuffer.cpp b/source/common/rendering/gl/system/gl_framebuffer.cpp index 9eac61bc2..cd7815670 100644 --- a/source/common/rendering/gl/system/gl_framebuffer.cpp +++ b/source/common/rendering/gl/system/gl_framebuffer.cpp @@ -31,12 +31,13 @@ #include "m_png.h" #include "printf.h" #include "templates.h" +#include "glbackend/glbackend.h" #include "gl_load/gl_interface.h" #include "gl/system/gl_framebuffer.h" -/* #include "gl/renderer/gl_renderer.h" #include "gl/renderer/gl_renderbuffers.h" +/* #include "gl/textures/gl_samplers.h" #include "hwrenderer/utility/hw_clock.h" #include "hwrenderer/utility/hw_vrmodes.h" @@ -65,9 +66,7 @@ extern bool vid_hdr_active; namespace OpenGLRenderer { -#ifdef IMPLEMENT_IT FGLRenderer *GLRenderer; -#endif //========================================================================== // @@ -86,28 +85,28 @@ OpenGLFrameBuffer::OpenGLFrameBuffer(void *hMonitor, bool fullscreen) : // Make sure all global variables tracking OpenGL context state are reset.. FHardwareTexture::InitGlobalState(); gl_RenderState.Reset(); +#endif GLRenderer = nullptr; -#endif } OpenGLFrameBuffer::~OpenGLFrameBuffer() { -#ifdef IMPLEMENT_IT PPResource::ResetAll(); +#ifdef IMPLEMENT_IT if (mVertexData != nullptr) delete mVertexData; if (mSkyData != nullptr) delete mSkyData; if (mViewpoints != nullptr) delete mViewpoints; if (mLights != nullptr) delete mLights; mShadowMap.Reset(); +#endif if (GLRenderer) { delete GLRenderer; GLRenderer = nullptr; } -#endif } //========================================================================== @@ -166,10 +165,10 @@ void OpenGLFrameBuffer::InitializeState() mSkyData = new FSkyVertexBuffer; mViewpoints = new HWViewpointBuffer; mLights = new FLightBuffer(); - +#endif GLRenderer = new FGLRenderer(this); GLRenderer->Initialize(GetWidth(), GetHeight()); - +#ifdef IMPLEMENT_IT static_cast(mLights->GetBuffer())->BindBase(); #endif @@ -185,14 +184,14 @@ void OpenGLFrameBuffer::InitializeState() void OpenGLFrameBuffer::Update() { -#ifdef IMPLEMENT_IT +#if 0 twoD.Reset(); Flush3D.Reset(); Flush3D.Clock(); - GLRenderer->Flush(); - Flush3D.Unclock(); #endif + GLRenderer->Flush(); +// Flush3D.Unclock(); Swap(); Super::Update(); @@ -305,35 +304,33 @@ IIndexBuffer *OpenGLFrameBuffer::CreateIndexBuffer() { return new GLIndexBuffer; } +#endif IDataBuffer *OpenGLFrameBuffer::CreateDataBuffer(int bindingpoint, bool ssbo, bool needsresize) { return new GLDataBuffer(bindingpoint, ssbo); } +#ifdef IMPLEMENT_IT void OpenGLFrameBuffer::TextureFilterChanged() { if (GLRenderer != NULL && GLRenderer->mSamplerManager != NULL) GLRenderer->mSamplerManager->SetTextureFilterMode(); } +#endif void OpenGLFrameBuffer::BlurScene(float amount) { GLRenderer->BlurScene(amount); } -void OpenGLFrameBuffer::SetViewportRects(IntRect *bounds) +#if 0 +void OpenGLFrameBuffer::UpdatePalette() { - Super::SetViewportRects(bounds); - if (!bounds) - { - auto vrmode = VRMode::GetVRMode(true); - vrmode->AdjustViewport(this); - } + if (GLRenderer) + GLRenderer->ClearTonemapPalette(); } - #endif - //=========================================================================== // // @@ -343,6 +340,8 @@ void OpenGLFrameBuffer::SetViewportRects(IntRect *bounds) void OpenGLFrameBuffer::BeginFrame() { SetViewportRects(nullptr); + if (GLRenderer != nullptr) + GLRenderer->BeginFrame(); } //=========================================================================== @@ -401,9 +400,18 @@ TArray 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 &afterBloomDrawEndScene2D) { - //GLRenderer->PostProcessScene(fixedcm, afterBloomDrawEndScene2D); + GLRenderer->PostProcessScene(fixedcm, afterBloomDrawEndScene2D); } diff --git a/source/common/rendering/gl/system/gl_framebuffer.h b/source/common/rendering/gl/system/gl_framebuffer.h index 52d887a0f..c87b553da 100644 --- a/source/common/rendering/gl/system/gl_framebuffer.h +++ b/source/common/rendering/gl/system/gl_framebuffer.h @@ -23,6 +23,7 @@ public: void InitializeState() override; void Update() override; + void Draw2D() override; void CleanForRestart() override; const char* DeviceName() const override; @@ -34,13 +35,13 @@ public: void TextureFilterChanged() override; #endif void BeginFrame() override; -#ifdef IMPLEMENT_IT - void SetViewportRects(IntRect *bounds) override; + //void SetViewportRects(IntRect *bounds) override; void BlurScene(float amount) override; +#ifdef IMPLEMENT_IT IVertexBuffer *CreateVertexBuffer() override; IIndexBuffer *CreateIndexBuffer() override; - IDataBuffer *CreateDataBuffer(int bindingpoint, bool ssbo, bool needsresize) override; #endif + IDataBuffer *CreateDataBuffer(int bindingpoint, bool ssbo, bool needsresize) override; // Retrieves a buffer containing image data for a screenshot. // Hint: Pitch can be negative for upside-down images, in which case buffer diff --git a/source/common/rendering/hwrenderer/postprocessing/hw_postprocess.cpp b/source/common/rendering/hwrenderer/postprocessing/hw_postprocess.cpp index 2497eb968..fd07e69cf 100644 --- a/source/common/rendering/hwrenderer/postprocessing/hw_postprocess.cpp +++ b/source/common/rendering/hwrenderer/postprocessing/hw_postprocess.cpp @@ -372,8 +372,8 @@ void PPFXAA::CreateShaders() if (LastQuality == gl_fxaa) return; - FXAALuma = { "shaders/glsl/fxaa.fp", "#define FXAA_LUMA_PASS\n", {} }; - FXAA = { "shaders/glsl/fxaa.fp", GetDefines(), FXAAUniforms::Desc(), GetMaxVersion() }; + FXAALuma = { "engine/shaders/pp/fxaa.fp", "#define FXAA_LUMA_PASS\n", {} }; + FXAA = { "engine/shaders/pp/fxaa.fp", GetDefines(), FXAAUniforms::Desc(), GetMaxVersion() }; LastQuality = gl_fxaa; } @@ -627,14 +627,14 @@ void PPAmbientOcclusion::CreateShaders() #define NUM_STEPS %d.0 )", numDirections, numSteps); - LinearDepth = { "shaders/glsl/lineardepth.fp", "", LinearDepthUniforms::Desc() }; - LinearDepthMS = { "shaders/glsl/lineardepth.fp", "#define MULTISAMPLE\n", LinearDepthUniforms::Desc() }; - AmbientOcclude = { "shaders/glsl/ssao.fp", defines, SSAOUniforms::Desc() }; - AmbientOccludeMS = { "shaders/glsl/ssao.fp", defines + "\n#define MULTISAMPLE\n", SSAOUniforms::Desc() }; - BlurVertical = { "shaders/glsl/depthblur.fp", "#define BLUR_VERTICAL\n", DepthBlurUniforms::Desc() }; - BlurHorizontal = { "shaders/glsl/depthblur.fp", "#define BLUR_HORIZONTAL\n", DepthBlurUniforms::Desc() }; - Combine = { "shaders/glsl/ssaocombine.fp", "", AmbientCombineUniforms::Desc() }; - CombineMS = { "shaders/glsl/ssaocombine.fp", "#define MULTISAMPLE\n", AmbientCombineUniforms::Desc() }; + LinearDepth = { "engine/shaders/pp/lineardepth.fp", "", LinearDepthUniforms::Desc() }; + LinearDepthMS = { "engine/shaders/pp/lineardepth.fp", "#define MULTISAMPLE\n", LinearDepthUniforms::Desc() }; + AmbientOcclude = { "engine/shaders/pp/ssao.fp", defines, SSAOUniforms::Desc() }; + AmbientOccludeMS = { "engine/shaders/pp/ssao.fp", defines + "\n#define MULTISAMPLE\n", SSAOUniforms::Desc() }; + BlurVertical = { "engine/shaders/pp/depthblur.fp", "#define BLUR_VERTICAL\n", DepthBlurUniforms::Desc() }; + BlurHorizontal = { "engine/shaders/pp/depthblur.fp", "#define BLUR_HORIZONTAL\n", DepthBlurUniforms::Desc() }; + Combine = { "engine/shaders/pp/ssaocombine.fp", "", AmbientCombineUniforms::Desc() }; + CombineMS = { "engine/shaders/pp/ssaocombine.fp", "#define MULTISAMPLE\n", AmbientCombineUniforms::Desc() }; LastQuality = gl_ssao; } diff --git a/source/common/rendering/hwrenderer/postprocessing/hw_postprocess.h b/source/common/rendering/hwrenderer/postprocessing/hw_postprocess.h index 9b8033c9a..ea89175db 100644 --- a/source/common/rendering/hwrenderer/postprocessing/hw_postprocess.h +++ b/source/common/rendering/hwrenderer/postprocessing/hw_postprocess.h @@ -303,7 +303,7 @@ public: void ResetBackend() override { Backend.reset(); } - FString VertexShader = "shaders/glsl/screenquad.vp"; + FString VertexShader = "engine/shaders/pp/screenquad.vp"; FString FragmentShader; FString Defines; std::vector Uniforms; @@ -376,10 +376,10 @@ private: int lastWidth = 0; int lastHeight = 0; - PPShader BloomCombine = { "shaders/glsl/bloomcombine.fp", "", {} }; - PPShader BloomExtract = { "shaders/glsl/bloomextract.fp", "", ExtractUniforms::Desc() }; - PPShader BlurVertical = { "shaders/glsl/blur.fp", "#define BLUR_VERTICAL\n", BlurUniforms::Desc() }; - PPShader BlurHorizontal = { "shaders/glsl/blur.fp", "#define BLUR_HORIZONTAL\n", BlurUniforms::Desc() }; + PPShader BloomCombine = { "engine/shaders/pp/bloomcombine.fp", "", {} }; + PPShader BloomExtract = { "engine/shaders/pp/bloomextract.fp", "", ExtractUniforms::Desc() }; + PPShader BlurVertical = { "engine/shaders/pp/blur.fp", "#define BLUR_VERTICAL\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); 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 ExposureLevels; bool FirstExposureFrame = true; - PPShader ExposureExtract = { "shaders/glsl/exposureextract.fp", "", ExposureExtractUniforms::Desc() }; - PPShader ExposureAverage = { "shaders/glsl/exposureaverage.fp", "", {}, 400 }; - PPShader ExposureCombine = { "shaders/glsl/exposurecombine.fp", "", ExposureCombineUniforms::Desc() }; + PPShader ExposureExtract = { "engine/shaders/pp/exposureextract.fp", "", ExposureExtractUniforms::Desc() }; + PPShader ExposureAverage = { "engine/shaders/pp/exposureaverage.fp", "", {}, 400 }; + PPShader ExposureCombine = { "engine/shaders/pp/exposurecombine.fp", "", ExposureCombineUniforms::Desc() }; }; ///////////////////////////////////////////////////////////////////////////// @@ -539,11 +539,11 @@ private: PPTexture PaletteTexture; - PPShader LinearShader = { "shaders/glsl/tonemap.fp", "#define LINEAR\n", {} }; - PPShader ReinhardShader = { "shaders/glsl/tonemap.fp", "#define REINHARD\n", {} }; - PPShader HejlDawsonShader = { "shaders/glsl/tonemap.fp", "#define HEJLDAWSON\n", {} }; - PPShader Uncharted2Shader = { "shaders/glsl/tonemap.fp", "#define UNCHARTED2\n", {} }; - PPShader PaletteShader = { "shaders/glsl/tonemap.fp", "#define PALETTE\n", {} }; + PPShader LinearShader = { "engine/shaders/pp/tonemap.fp", "#define LINEAR\n", {} }; + PPShader ReinhardShader = { "engine/shaders/pp/tonemap.fp", "#define REINHARD\n", {} }; + PPShader HejlDawsonShader = { "engine/shaders/pp/tonemap.fp", "#define HEJLDAWSON\n", {} }; + PPShader Uncharted2Shader = { "engine/shaders/pp/tonemap.fp", "#define UNCHARTED2\n", {} }; + PPShader PaletteShader = { "engine/shaders/pp/tonemap.fp", "#define PALETTE\n", {} }; enum TonemapMode { @@ -744,10 +744,10 @@ public: PPTexture Dither; - PPShader Present = { "shaders/glsl/present.fp", "", PresentUniforms::Desc() }; - PPShader Checker3D = { "shaders/glsl/present_checker3d.fp", "", PresentUniforms::Desc() }; - PPShader Column3D = { "shaders/glsl/present_column3d.fp", "", PresentUniforms::Desc() }; - PPShader Row3D = { "shaders/glsl/present_row3d.fp", "", PresentUniforms::Desc() }; + PPShader Present = { "engine/shaders/pp/present.fp", "", PresentUniforms::Desc() }; + PPShader Checker3D = { "engine/shaders/pp/present_checker3d.fp", "", PresentUniforms::Desc() }; + PPShader Column3D = { "engine/shaders/pp/present_column3d.fp", "", PresentUniforms::Desc() }; + PPShader Row3D = { "engine/shaders/pp/present_row3d.fp", "", PresentUniforms::Desc() }; }; ///////////////////////////////////////////////////////////////////////////// diff --git a/source/common/rendering/hwrenderer/utility/hw_shaderpatcher.cpp b/source/common/rendering/hwrenderer/utility/hw_shaderpatcher.cpp index bdbaa50b4..ba77d9bc5 100644 --- a/source/common/rendering/hwrenderer/utility/hw_shaderpatcher.cpp +++ b/source/common/rendering/hwrenderer/utility/hw_shaderpatcher.cpp @@ -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. const FDefaultShader defaultshaders[] = { - {"Default", "shaders/glsl/func_normal.fp", "shaders/glsl/material_normal.fp", ""}, - {"Warp 1", "shaders/glsl/func_warp1.fp", "shaders/glsl/material_normal.fp", ""}, - {"Warp 2", "shaders/glsl/func_warp2.fp", "shaders/glsl/material_normal.fp", ""}, - {"Brightmap","shaders/glsl/func_brightmap.fp", "shaders/glsl/material_normal.fp", "#define BRIGHTMAP\n"}, - {"Specular", "shaders/glsl/func_spec.fp", "shaders/glsl/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"}, - {"PBR","shaders/glsl/func_pbr.fp", "shaders/glsl/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"}, - {"Paletted", "shaders/glsl/func_paletted.fp", "shaders/glsl/material_nolight.fp", ""}, - {"No Texture", "shaders/glsl/func_notexture.fp", "shaders/glsl/material_normal.fp", ""}, - {"Basic Fuzz", "shaders/glsl/fuzz_standard.fp", "shaders/glsl/material_normal.fp", ""}, - {"Smooth Fuzz", "shaders/glsl/fuzz_smooth.fp", "shaders/glsl/material_normal.fp", ""}, - {"Swirly Fuzz", "shaders/glsl/fuzz_swirly.fp", "shaders/glsl/material_normal.fp", ""}, - {"Translucent Fuzz", "shaders/glsl/fuzz_smoothtranslucent.fp", "shaders/glsl/material_normal.fp", ""}, - {"Jagged Fuzz", "shaders/glsl/fuzz_jagged.fp", "shaders/glsl/material_normal.fp", ""}, - {"Noise Fuzz", "shaders/glsl/fuzz_noise.fp", "shaders/glsl/material_normal.fp", ""}, - {"Smooth Noise Fuzz", "shaders/glsl/fuzz_smoothnoise.fp", "shaders/glsl/material_normal.fp", ""}, - {"Software Fuzz", "shaders/glsl/fuzz_software.fp", "shaders/glsl/material_normal.fp", ""}, + {"Default", "engine/shaders/pp/func_normal.fp", "engine/shaders/pp/material_normal.fp", ""}, + {"Warp 1", "engine/shaders/pp/func_warp1.fp", "engine/shaders/pp/material_normal.fp", ""}, + {"Warp 2", "engine/shaders/pp/func_warp2.fp", "engine/shaders/pp/material_normal.fp", ""}, + {"Brightmap","engine/shaders/pp/func_brightmap.fp", "engine/shaders/pp/material_normal.fp", "#define BRIGHTMAP\n"}, + {"Specular", "engine/shaders/pp/func_spec.fp", "engine/shaders/pp/material_specular.fp", "#define SPECULAR\n#define NORMALMAP\n"}, + {"SpecularBrightmap", "engine/shaders/pp/func_spec.fp", "engine/shaders/pp/material_specular.fp", "#define SPECULAR\n#define NORMALMAP\n#define BRIGHTMAP\n"}, + {"PBR","engine/shaders/pp/func_pbr.fp", "engine/shaders/pp/material_pbr.fp", "#define PBR\n#define NORMALMAP\n"}, + {"PBRBrightmap","engine/shaders/pp/func_pbr.fp", "engine/shaders/pp/material_pbr.fp", "#define PBR\n#define NORMALMAP\n#define BRIGHTMAP\n"}, + {"Paletted", "engine/shaders/pp/func_paletted.fp", "engine/shaders/pp/material_nolight.fp", ""}, + {"No Texture", "engine/shaders/pp/func_notexture.fp", "engine/shaders/pp/material_normal.fp", ""}, + {"Basic Fuzz", "engine/shaders/pp/fuzz_standard.fp", "engine/shaders/pp/material_normal.fp", ""}, + {"Smooth Fuzz", "engine/shaders/pp/fuzz_smooth.fp", "engine/shaders/pp/material_normal.fp", ""}, + {"Swirly Fuzz", "engine/shaders/pp/fuzz_swirly.fp", "engine/shaders/pp/material_normal.fp", ""}, + {"Translucent Fuzz", "engine/shaders/pp/fuzz_smoothtranslucent.fp", "engine/shaders/pp/material_normal.fp", ""}, + {"Jagged Fuzz", "engine/shaders/pp/fuzz_jagged.fp", "engine/shaders/pp/material_normal.fp", ""}, + {"Noise Fuzz", "engine/shaders/pp/fuzz_noise.fp", "engine/shaders/pp/material_normal.fp", ""}, + {"Smooth Noise Fuzz", "engine/shaders/pp/fuzz_smoothnoise.fp", "engine/shaders/pp/material_normal.fp", ""}, + {"Software Fuzz", "engine/shaders/pp/fuzz_software.fp", "engine/shaders/pp/material_normal.fp", ""}, {nullptr,nullptr,nullptr,nullptr} }; const FEffectShader effectshaders[] = { - { "fogboundary", "shaders/glsl/main.vp", "shaders/glsl/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" }, - { "burn", "shaders/glsl/main.vp", "shaders/glsl/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" }, + { "fogboundary", "engine/shaders/pp/main.vp", "engine/shaders/pp/fogboundary.fp", nullptr, nullptr, "#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", "engine/shaders/pp/main.vp", "engine/shaders/pp/burn.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" }, }; diff --git a/source/common/rendering/v_video.h b/source/common/rendering/v_video.h index f4d676091..64788b4b8 100644 --- a/source/common/rendering/v_video.h +++ b/source/common/rendering/v_video.h @@ -331,6 +331,7 @@ public: // Report a game restart virtual int Backend() { return 0; } virtual const char* DeviceName() const { return "Unknown"; } + virtual void Draw2D() {} // Screen wiping virtual FTexture *WipeStartScreen(); diff --git a/source/glbackend/glbackend.cpp b/source/glbackend/glbackend.cpp index aec7b1ad3..b2971d865 100644 --- a/source/glbackend/glbackend.cpp +++ b/source/glbackend/glbackend.cpp @@ -45,8 +45,11 @@ #include "imgui_impl_opengl3.h" #include "baselayer.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) { @@ -149,25 +152,36 @@ void GLInstance::LoadSurfaceShader() void GLInstance::InitGLState(int fogmode, int multisample) { glShadeModel(GL_SMOOTH); // GL_FLAT - glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); - glDisable(GL_DITHER); 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_UNPACK_ALIGNMENT, 1); - glEnable(GL_DEPTH_CLAMP); - if (multisample > 0 ) { //glHint(GL_MULTISAMPLE_FILTER_HINT_NV, GL_NICEST); glEnable(GL_MULTISAMPLE); } 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() { #if 0 @@ -502,6 +516,22 @@ void GLInstance::DrawImGui(ImDrawData* data) #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) diff --git a/source/glbackend/glbackend.h b/source/glbackend/glbackend.h index 0598a2254..697cf6e51 100644 --- a/source/glbackend/glbackend.h +++ b/source/glbackend/glbackend.h @@ -300,6 +300,7 @@ public: void SetPalette(int palette); bool ApplyTextureProps(FTexture *tex, int pal); void RestoreTextureProps(); + void ClearScreen(PalEntry color); void ReadPixels(int w, int h, uint8_t* buffer); diff --git a/source/platform/win32/gl_sysfb.cpp b/source/platform/win32/gl_sysfb.cpp index fa7b412f6..f3269f572 100644 --- a/source/platform/win32/gl_sysfb.cpp +++ b/source/platform/win32/gl_sysfb.cpp @@ -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) { - if (!static_cast(Video)->InitHardware(Window, MS)) + if (!static_cast(Video)->InitHardware(Window, 0)) { I_FatalError("Unable to initialize OpenGL"); return; diff --git a/wadsrc/static/engine/shaders/pp/bloomcombine.fp b/wadsrc/static/engine/shaders/pp/bloomcombine.fp new file mode 100644 index 000000000..5b04e2a09 --- /dev/null +++ b/wadsrc/static/engine/shaders/pp/bloomcombine.fp @@ -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); +} diff --git a/wadsrc/static/engine/shaders/pp/bloomextract.fp b/wadsrc/static/engine/shaders/pp/bloomextract.fp new file mode 100644 index 000000000..98b627060 --- /dev/null +++ b/wadsrc/static/engine/shaders/pp/bloomextract.fp @@ -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)); +} diff --git a/wadsrc/static/engine/shaders/pp/blur.fp b/wadsrc/static/engine/shaders/pp/blur.fp new file mode 100644 index 000000000..e4a4a3b18 --- /dev/null +++ b/wadsrc/static/engine/shaders/pp/blur.fp @@ -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 +} diff --git a/wadsrc/static/engine/shaders/pp/colormap.fp b/wadsrc/static/engine/shaders/pp/colormap.fp new file mode 100644 index 000000000..43cc28b25 --- /dev/null +++ b/wadsrc/static/engine/shaders/pp/colormap.fp @@ -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); +} + diff --git a/wadsrc/static/engine/shaders/pp/depthblur.fp b/wadsrc/static/engine/shaders/pp/depthblur.fp new file mode 100644 index 000000000..b337025bc --- /dev/null +++ b/wadsrc/static/engine/shaders/pp/depthblur.fp @@ -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 +} diff --git a/wadsrc/static/engine/shaders/pp/exposureaverage.fp b/wadsrc/static/engine/shaders/pp/exposureaverage.fp new file mode 100644 index 000000000..57b0ad017 --- /dev/null +++ b/wadsrc/static/engine/shaders/pp/exposureaverage.fp @@ -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); +} diff --git a/wadsrc/static/engine/shaders/pp/exposurecombine.fp b/wadsrc/static/engine/shaders/pp/exposurecombine.fp new file mode 100644 index 000000000..01ab78b11 --- /dev/null +++ b/wadsrc/static/engine/shaders/pp/exposurecombine.fp @@ -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); +} diff --git a/wadsrc/static/engine/shaders/pp/exposureextract.fp b/wadsrc/static/engine/shaders/pp/exposureextract.fp new file mode 100644 index 000000000..d134e8651 --- /dev/null +++ b/wadsrc/static/engine/shaders/pp/exposureextract.fp @@ -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); +} diff --git a/wadsrc/static/engine/shaders/pp/fxaa.fp b/wadsrc/static/engine/shaders/pp/fxaa.fp new file mode 100644 index 000000000..0cb919069 --- /dev/null +++ b/wadsrc/static/engine/shaders/pp/fxaa.fp @@ -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 diff --git a/wadsrc/static/engine/shaders/pp/lensdistortion.fp b/wadsrc/static/engine/shaders/pp/lensdistortion.fp new file mode 100644 index 000000000..1b0d47b4f --- /dev/null +++ b/wadsrc/static/engine/shaders/pp/lensdistortion.fp @@ -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); +} diff --git a/wadsrc/static/engine/shaders/pp/lineardepth.fp b/wadsrc/static/engine/shaders/pp/lineardepth.fp new file mode 100644 index 000000000..7966e310a --- /dev/null +++ b/wadsrc/static/engine/shaders/pp/lineardepth.fp @@ -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); +} diff --git a/wadsrc/static/engine/shaders/pp/present.fp b/wadsrc/static/engine/shaders/pp/present.fp new file mode 100644 index 000000000..7069d0fae --- /dev/null +++ b/wadsrc/static/engine/shaders/pp/present.fp @@ -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)))); +} diff --git a/wadsrc/static/engine/shaders/pp/present_checker3d.fp b/wadsrc/static/engine/shaders/pp/present_checker3d.fp new file mode 100644 index 000000000..36d77e250 --- /dev/null +++ b/wadsrc/static/engine/shaders/pp/present_checker3d.fp @@ -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); +} diff --git a/wadsrc/static/engine/shaders/pp/present_column3d.fp b/wadsrc/static/engine/shaders/pp/present_column3d.fp new file mode 100644 index 000000000..cf8758e3a --- /dev/null +++ b/wadsrc/static/engine/shaders/pp/present_column3d.fp @@ -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); +} diff --git a/wadsrc/static/engine/shaders/pp/present_row3d.fp b/wadsrc/static/engine/shaders/pp/present_row3d.fp new file mode 100644 index 000000000..a88be0ed0 --- /dev/null +++ b/wadsrc/static/engine/shaders/pp/present_row3d.fp @@ -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); +} diff --git a/wadsrc/static/engine/shaders/pp/screenquad.vp b/wadsrc/static/engine/shaders/pp/screenquad.vp new file mode 100644 index 000000000..e5e10660f --- /dev/null +++ b/wadsrc/static/engine/shaders/pp/screenquad.vp @@ -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; +} diff --git a/wadsrc/static/engine/shaders/pp/tonemap.fp b/wadsrc/static/engine/shaders/pp/tonemap.fp new file mode 100644 index 000000000..e36c4a95e --- /dev/null +++ b/wadsrc/static/engine/shaders/pp/tonemap.fp @@ -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); +}