diff --git a/src/common/rendering/gl/gl_framebuffer.cpp b/src/common/rendering/gl/gl_framebuffer.cpp index a089699492..b116e95774 100644 --- a/src/common/rendering/gl/gl_framebuffer.cpp +++ b/src/common/rendering/gl/gl_framebuffer.cpp @@ -515,10 +515,10 @@ void OpenGLFrameBuffer::Draw2D() } } -void OpenGLFrameBuffer::PostProcessScene(bool swscene, int fixedcm, const std::function &afterBloomDrawEndScene2D) +void OpenGLFrameBuffer::PostProcessScene(bool swscene, int fixedcm, float flash, const std::function &afterBloomDrawEndScene2D) { if (!swscene) GLRenderer->mBuffers->BlitSceneToTexture(); // Copy the resulting scene to the current post process texture - GLRenderer->PostProcessScene(fixedcm, afterBloomDrawEndScene2D); + GLRenderer->PostProcessScene(fixedcm, flash, afterBloomDrawEndScene2D); } //========================================================================== diff --git a/src/common/rendering/gl/gl_framebuffer.h b/src/common/rendering/gl/gl_framebuffer.h index aaebbfeb3f..de10ac0524 100644 --- a/src/common/rendering/gl/gl_framebuffer.h +++ b/src/common/rendering/gl/gl_framebuffer.h @@ -61,7 +61,7 @@ public: void SetVSync(bool vsync); void Draw2D() override; - void PostProcessScene(bool swscene, int fixedcm, const std::function &afterBloomDrawEndScene2D) override; + void PostProcessScene(bool swscene, int fixedcm, float flash, const std::function &afterBloomDrawEndScene2D) override; bool HWGammaActive = false; // Are we using hardware or software gamma? std::shared_ptr mDebug; // Debug API diff --git a/src/common/rendering/gl/gl_postprocess.cpp b/src/common/rendering/gl/gl_postprocess.cpp index 2ac2db3136..4beed0577d 100644 --- a/src/common/rendering/gl/gl_postprocess.cpp +++ b/src/common/rendering/gl/gl_postprocess.cpp @@ -52,7 +52,7 @@ void FGLRenderer::RenderScreenQuad() glDrawArrays(GL_TRIANGLE_STRIP, FFlatVertexBuffer::PRESENT_INDEX, 4); } -void FGLRenderer::PostProcessScene(int fixedcm, const std::function &afterBloomDrawEndScene2D) +void FGLRenderer::PostProcessScene(int fixedcm, float flash, const std::function &afterBloomDrawEndScene2D) { int sceneWidth = mBuffers->GetSceneWidth(); int sceneHeight = mBuffers->GetSceneHeight(); @@ -62,7 +62,7 @@ void FGLRenderer::PostProcessScene(int fixedcm, const std::function &aft hw_postprocess.Pass1(&renderstate, fixedcm, sceneWidth, sceneHeight); mBuffers->BindCurrentFB(); if (afterBloomDrawEndScene2D) afterBloomDrawEndScene2D(); - hw_postprocess.Pass2(&renderstate, fixedcm, sceneWidth, sceneHeight); + hw_postprocess.Pass2(&renderstate, fixedcm, flash, sceneWidth, sceneHeight); } //----------------------------------------------------------------------------- diff --git a/src/common/rendering/gl/gl_renderer.h b/src/common/rendering/gl/gl_renderer.h index 8b5fe7e038..c75927c0f5 100644 --- a/src/common/rendering/gl/gl_renderer.h +++ b/src/common/rendering/gl/gl_renderer.h @@ -72,7 +72,7 @@ public: void PresentStereo(); void RenderScreenQuad(); - void PostProcessScene(int fixedcm, const std::function &afterBloomDrawEndScene2D); + void PostProcessScene(int fixedcm, float flash, const std::function &afterBloomDrawEndScene2D); void AmbientOccludeScene(float m5); void ClearTonemapPalette(); void BlurScene(float gameinfobluramount); diff --git a/src/common/rendering/hwrenderer/postprocessing/hw_postprocess.cpp b/src/common/rendering/hwrenderer/postprocessing/hw_postprocess.cpp index 1dc670de0b..658a431dd2 100644 --- a/src/common/rendering/hwrenderer/postprocessing/hw_postprocess.cpp +++ b/src/common/rendering/hwrenderer/postprocessing/hw_postprocess.cpp @@ -532,20 +532,26 @@ void PPCameraExposure::UpdateTextures(int width, int height) ///////////////////////////////////////////////////////////////////////////// -void PPColormap::Render(PPRenderState *renderstate, int fixedcm) +void PPColormap::Render(PPRenderState *renderstate, int fixedcm, float flash) { + ColormapUniforms uniforms; + if (fixedcm < CM_FIRSTSPECIALCOLORMAP || fixedcm >= CM_MAXCOLORMAP) { - return; + if (flash == 1.f) + return; + + uniforms.MapStart = { 0,0,0, flash }; + uniforms.MapRange = { 0,0,0, 1.f }; } + else + { + FSpecialColormap* scm = &SpecialColormaps[fixedcm - CM_FIRSTSPECIALCOLORMAP]; - FSpecialColormap *scm = &SpecialColormaps[fixedcm - CM_FIRSTSPECIALCOLORMAP]; - float m[] = { scm->ColorizeEnd[0] - scm->ColorizeStart[0], - scm->ColorizeEnd[1] - scm->ColorizeStart[1], scm->ColorizeEnd[2] - scm->ColorizeStart[2], 0.f }; - - ColormapUniforms uniforms; - uniforms.MapStart = { scm->ColorizeStart[0], scm->ColorizeStart[1], scm->ColorizeStart[2], 0.f }; - uniforms.MapRange = m; + uniforms.MapStart = { scm->ColorizeStart[0], scm->ColorizeStart[1], scm->ColorizeStart[2], flash }; + uniforms.MapRange = { scm->ColorizeEnd[0] - scm->ColorizeStart[0], + scm->ColorizeEnd[1] - scm->ColorizeStart[1], scm->ColorizeEnd[2] - scm->ColorizeStart[2], 0.f }; + } renderstate->PushGroup("colormap"); @@ -1117,10 +1123,10 @@ void Postprocess::Pass1(PPRenderState* state, int fixedcm, int sceneWidth, int s bloom.RenderBloom(state, sceneWidth, sceneHeight, fixedcm); } -void Postprocess::Pass2(PPRenderState* state, int fixedcm, int sceneWidth, int sceneHeight) +void Postprocess::Pass2(PPRenderState* state, int fixedcm, float flash, int sceneWidth, int sceneHeight) { tonemap.Render(state); - colormap.Render(state, fixedcm); + colormap.Render(state, fixedcm, flash); lens.Render(state); fxaa.Render(state); customShaders.Run(state, "scene"); diff --git a/src/common/rendering/hwrenderer/postprocessing/hw_postprocess.h b/src/common/rendering/hwrenderer/postprocessing/hw_postprocess.h index 09c0d25534..71defdcae4 100644 --- a/src/common/rendering/hwrenderer/postprocessing/hw_postprocess.h +++ b/src/common/rendering/hwrenderer/postprocessing/hw_postprocess.h @@ -530,7 +530,7 @@ struct ColormapUniforms class PPColormap { public: - void Render(PPRenderState *renderstate, int fixedcm); + void Render(PPRenderState *renderstate, int fixedcm, float flash); private: PPShader Colormap = { "shaders/pp/colormap.fp", "", ColormapUniforms::Desc() }; @@ -841,7 +841,7 @@ public: void Pass1(PPRenderState *state, int fixedcm, int sceneWidth, int sceneHeight); - void Pass2(PPRenderState* state, int fixedcm, int sceneWidth, int sceneHeight); + void Pass2(PPRenderState* state, int fixedcm, float flash, int sceneWidth, int sceneHeight); }; extern Postprocess hw_postprocess; diff --git a/src/common/rendering/polyrenderer/backend/poly_framebuffer.cpp b/src/common/rendering/polyrenderer/backend/poly_framebuffer.cpp index d1dbd63db0..9bbdd70723 100644 --- a/src/common/rendering/polyrenderer/backend/poly_framebuffer.cpp +++ b/src/common/rendering/polyrenderer/backend/poly_framebuffer.cpp @@ -232,7 +232,7 @@ static uint8_t ToIntColorComponent(float v) return clamp((int)(v * 255.0f + 0.5f), 0, 255); } -void PolyFrameBuffer::PostProcessScene(bool swscene, int fixedcm, const std::function &afterBloomDrawEndScene2D) +void PolyFrameBuffer::PostProcessScene(bool swscene, int fixedcm, float flash, const std::function &afterBloomDrawEndScene2D) { afterBloomDrawEndScene2D(); diff --git a/src/common/rendering/polyrenderer/backend/poly_framebuffer.h b/src/common/rendering/polyrenderer/backend/poly_framebuffer.h index 84982d9d5f..a3c4eee292 100644 --- a/src/common/rendering/polyrenderer/backend/poly_framebuffer.h +++ b/src/common/rendering/polyrenderer/backend/poly_framebuffer.h @@ -39,7 +39,7 @@ public: void SetTextureFilterMode() override; void BeginFrame() override; void BlurScene(float amount) override; - void PostProcessScene(bool swscene, int fixedcm, const std::function &afterBloomDrawEndScene2D) override; + void PostProcessScene(bool swscene, int fixedcm, float flash, const std::function &afterBloomDrawEndScene2D) override; void AmbientOccludeScene(float m5) override; //void SetSceneRenderTarget(bool useSSAO) override; diff --git a/src/common/rendering/v_video.h b/src/common/rendering/v_video.h index ac61291dd3..ae4b318d0f 100644 --- a/src/common/rendering/v_video.h +++ b/src/common/rendering/v_video.h @@ -242,7 +242,7 @@ public: virtual FTexture *WipeStartScreen(); virtual FTexture *WipeEndScreen(); - virtual void PostProcessScene(bool swscene, int fixedcm, const std::function &afterBloomDrawEndScene2D) { if (afterBloomDrawEndScene2D) afterBloomDrawEndScene2D(); } + virtual void PostProcessScene(bool swscene, int fixedcm, float flash, const std::function &afterBloomDrawEndScene2D) { if (afterBloomDrawEndScene2D) afterBloomDrawEndScene2D(); } void ScaleCoordsFromWindow(int16_t &x, int16_t &y); diff --git a/src/common/rendering/vulkan/renderer/vk_postprocess.cpp b/src/common/rendering/vulkan/renderer/vk_postprocess.cpp index 6d3656fd92..ff2df75720 100644 --- a/src/common/rendering/vulkan/renderer/vk_postprocess.cpp +++ b/src/common/rendering/vulkan/renderer/vk_postprocess.cpp @@ -60,7 +60,7 @@ void VkPostprocess::SetActiveRenderTarget() fb->GetRenderState()->SetRenderTarget(&buffers->PipelineImage[mCurrentPipelineImage], nullptr, buffers->GetWidth(), buffers->GetHeight(), VK_FORMAT_R16G16B16A16_SFLOAT, VK_SAMPLE_COUNT_1_BIT); } -void VkPostprocess::PostProcessScene(int fixedcm, const std::function &afterBloomDrawEndScene2D) +void VkPostprocess::PostProcessScene(int fixedcm, float flash, const std::function &afterBloomDrawEndScene2D) { auto fb = GetVulkanFrameBuffer(); int sceneWidth = fb->GetBuffers()->GetSceneWidth(); @@ -71,7 +71,7 @@ void VkPostprocess::PostProcessScene(int fixedcm, const std::function &a hw_postprocess.Pass1(&renderstate, fixedcm, sceneWidth, sceneHeight); SetActiveRenderTarget(); afterBloomDrawEndScene2D(); - hw_postprocess.Pass2(&renderstate, fixedcm, sceneWidth, sceneHeight); + hw_postprocess.Pass2(&renderstate, fixedcm, flash, sceneWidth, sceneHeight); } void VkPostprocess::BlitSceneToPostprocess() diff --git a/src/common/rendering/vulkan/renderer/vk_postprocess.h b/src/common/rendering/vulkan/renderer/vk_postprocess.h index 53390e00e6..67660fe514 100644 --- a/src/common/rendering/vulkan/renderer/vk_postprocess.h +++ b/src/common/rendering/vulkan/renderer/vk_postprocess.h @@ -44,7 +44,7 @@ public: void RenderBuffersReset(); void SetActiveRenderTarget(); - void PostProcessScene(int fixedcm, const std::function &afterBloomDrawEndScene2D); + void PostProcessScene(int fixedcm, float flash, const std::function &afterBloomDrawEndScene2D); void AmbientOccludeScene(float m5); void BlurScene(float gameinfobluramount); diff --git a/src/common/rendering/vulkan/system/vk_framebuffer.cpp b/src/common/rendering/vulkan/system/vk_framebuffer.cpp index 602d628b10..dd8ff2341b 100644 --- a/src/common/rendering/vulkan/system/vk_framebuffer.cpp +++ b/src/common/rendering/vulkan/system/vk_framebuffer.cpp @@ -343,10 +343,10 @@ void VulkanFrameBuffer::RenderTextureView(FCanvasTexture* tex, std::functionSetUpdated(true); } -void VulkanFrameBuffer::PostProcessScene(bool swscene, int fixedcm, const std::function &afterBloomDrawEndScene2D) +void VulkanFrameBuffer::PostProcessScene(bool swscene, int fixedcm, float flash, const std::function &afterBloomDrawEndScene2D) { if (!swscene) mPostprocess->BlitSceneToPostprocess(); // Copy the resulting scene to the current post process texture - mPostprocess->PostProcessScene(fixedcm, afterBloomDrawEndScene2D); + mPostprocess->PostProcessScene(fixedcm, flash, afterBloomDrawEndScene2D); } const char* VulkanFrameBuffer::DeviceName() const diff --git a/src/common/rendering/vulkan/system/vk_framebuffer.h b/src/common/rendering/vulkan/system/vk_framebuffer.h index b1a7764525..9c5e5bf2d3 100644 --- a/src/common/rendering/vulkan/system/vk_framebuffer.h +++ b/src/common/rendering/vulkan/system/vk_framebuffer.h @@ -80,7 +80,7 @@ public: void StartPrecaching() override; void BeginFrame() override; void BlurScene(float amount) override; - void PostProcessScene(bool swscene, int fixedcm, const std::function &afterBloomDrawEndScene2D) override; + void PostProcessScene(bool swscene, int fixedcm, float flash, const std::function &afterBloomDrawEndScene2D) override; void AmbientOccludeScene(float m5) override; void SetSceneRenderTarget(bool useSSAO) override; void UpdateShadowMap() override; diff --git a/src/r_data/colormaps.h b/src/r_data/colormaps.h index 5077f7a7b7..58381f15d4 100644 --- a/src/r_data/colormaps.h +++ b/src/r_data/colormaps.h @@ -45,15 +45,11 @@ inline uint32_t MakeSpecialColormap(int index) enum EColorManipulation { - CM_PLAIN2D = -2, // regular 2D drawing. - CM_INVALID = -1, CM_DEFAULT = 0, // untranslated CM_FIRSTSPECIALCOLORMAP, // first special fixed colormap - CM_FIRSTSPECIALCOLORMAPFORCED = 0x08000000, // first special fixed colormap, application forced (for 2D overlays) }; #define CM_MAXCOLORMAP int(CM_FIRSTSPECIALCOLORMAP + SpecialColormaps.Size()) -#define CM_MAXCOLORMAPFORCED int(CM_FIRSTSPECIALCOLORMAPFORCED + SpecialColormaps.Size()) #endif diff --git a/src/rendering/hwrenderer/hw_entrypoint.cpp b/src/rendering/hwrenderer/hw_entrypoint.cpp index c11e3d7d5c..83093ff828 100644 --- a/src/rendering/hwrenderer/hw_entrypoint.cpp +++ b/src/rendering/hwrenderer/hw_entrypoint.cpp @@ -144,6 +144,7 @@ sector_t* RenderViewpoint(FRenderViewpoint& mainvp, AActor* camera, IntRect* bou di->Set3DViewport(RenderState); di->SetViewArea(); auto cm = di->SetFullbrightFlags(mainview ? vp.camera->player : nullptr); + float flash = 1.f; di->Viewpoint.FieldOfView = fov; // Set the real FOV for the current scene (it's not necessarily the same as the global setting in r_viewpoint) // Stereo mode specific perspective projection @@ -165,7 +166,7 @@ sector_t* RenderViewpoint(FRenderViewpoint& mainvp, AActor* camera, IntRect* bou RenderState.EnableDrawBuffers(1); } - screen->PostProcessScene(false, cm, [&]() { di->DrawEndScene2D(mainvp.sector, RenderState); }); + screen->PostProcessScene(false, cm, flash, [&]() { di->DrawEndScene2D(mainvp.sector, RenderState); }); PostProcess.Unclock(); } di->EndDrawInfo(); diff --git a/src/rendering/swrenderer/r_swscene.cpp b/src/rendering/swrenderer/r_swscene.cpp index d163df8f20..f6c58a8071 100644 --- a/src/rendering/swrenderer/r_swscene.cpp +++ b/src/rendering/swrenderer/r_swscene.cpp @@ -124,7 +124,7 @@ sector_t *SWSceneDrawer::RenderView(player_t *player) DrawTexture(twod, fbtex.get(), 0, 0, DTA_SpecialColormap, map, TAG_DONE); screen->Draw2D(); twod->Clear(); - screen->PostProcessScene(true, CM_DEFAULT, [&]() { + screen->PostProcessScene(true, CM_DEFAULT, 1.f, [&]() { SWRenderer->DrawRemainingPlayerSprites(); screen->Draw2D(); twod->Clear(); @@ -140,7 +140,7 @@ sector_t *SWSceneDrawer::RenderView(player_t *player) int cm = CM_DEFAULT; auto map = swrenderer::CameraLight::Instance()->ShaderColormap(); if (map) cm = (int)(ptrdiff_t)(map - SpecialColormaps.Data()) + CM_FIRSTSPECIALCOLORMAP; - screen->PostProcessScene(true, cm, [&]() { }); + screen->PostProcessScene(true, cm, 1.f, [&]() { }); SWRenderer->DrawRemainingPlayerSprites(); screen->Draw2D(); diff --git a/wadsrc/static/shaders/pp/colormap.fp b/wadsrc/static/shaders/pp/colormap.fp index 43cc28b25c..a60f4cfab0 100644 --- a/wadsrc/static/shaders/pp/colormap.fp +++ b/wadsrc/static/shaders/pp/colormap.fp @@ -6,8 +6,13 @@ 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); + frag.rgb = clamp(pow(frag.rgb, vec3(uFixedColormapStart.a)), 0.0, 1.0); + if (uFixedColormapRange.a == 0) + { + float gray = (frag.r * 0.3 + frag.g * 0.56 + frag.b * 0.14); + vec4 cm = uFixedColormapStart + gray * uFixedColormapRange; + frag.rgb = clamp(cm.rgb, 0.0, 1.0); + } + FragColor = frag; }