Adds contrast-adaptiv-sharpening filter, also helps to partly remove FXAA texture blurring.
Patch By: OptimusShepard Tested By: Stan Differential Revision: https://code.wildfiregames.com/D2642 This was SVN commit r23947.
This commit is contained in:
parent
8d90636306
commit
26ae55cad0
@ -29,6 +29,9 @@ in particular, let us know and we can try to clarify it.
|
||||
/binaries/data/mods/public/shaders/glsl/fxaa.fs
|
||||
BSD
|
||||
|
||||
/binaries/data/mods/public/shaders/glsl/cas.fs
|
||||
MIT
|
||||
|
||||
/binaries/system
|
||||
Various (unspecified)
|
||||
|
||||
|
@ -110,6 +110,10 @@ postproc = false
|
||||
; Use anti-aliasing techniques.
|
||||
antialiasing = "disabled"
|
||||
|
||||
; Use sharpening techniques.
|
||||
sharpening = "disabled"
|
||||
sharpness = 0.3
|
||||
|
||||
; Quality level of shader effects (set to 10 to display all effects)
|
||||
materialmgr.quality = 2.0
|
||||
|
||||
|
@ -129,6 +129,28 @@
|
||||
],
|
||||
"function": "Renderer_UpdateAntiAliasingTechnique"
|
||||
},
|
||||
{
|
||||
"type": "dropdown",
|
||||
"label": "Sharpening",
|
||||
"tooltip": "Reduce blurry effects.",
|
||||
"dependencies": ["postproc", "preferglsl"],
|
||||
"config": "sharpening",
|
||||
"list": [
|
||||
{ "value": "disabled", "label": "Disabled", "tooltip": "Do not use sharpening." },
|
||||
{ "value": "cas", "label": "FidelityFX CAS", "tooltip": "Contrast adaptive sharpening, a fast, contrast based sharpening pass." }
|
||||
],
|
||||
"function": "Renderer_UpdateSharpeningTechnique"
|
||||
},
|
||||
{
|
||||
"type": "slider",
|
||||
"label": "Sharpness factor",
|
||||
"tooltip": "The sharpness of the choosen pass.",
|
||||
"dependencies": ["postproc", "preferglsl"],
|
||||
"config": "sharpness",
|
||||
"min": 0,
|
||||
"max": 1,
|
||||
"function": "Renderer_UpdateSharpnessFactor"
|
||||
},
|
||||
{
|
||||
"type": "slider",
|
||||
"label": "Shader effects",
|
||||
|
@ -9,7 +9,7 @@
|
||||
<object type="image" sprite="ModernFade"/>
|
||||
|
||||
<!-- Settings Window -->
|
||||
<object name="options" type="image" style="ModernDialog" size="50%-350 50%-344 50%+350 50%+344">
|
||||
<object name="options" type="image" style="ModernDialog" size="50%-350 50%-374 50%+350 50%+374">
|
||||
|
||||
<object style="ModernLabelText" type="text" size="50%-128 -16 50%+128 16">
|
||||
<translatableAttribute id="caption">Game Options</translatableAttribute>
|
||||
|
7
binaries/data/mods/public/shaders/effects/cas.xml
Normal file
7
binaries/data/mods/public/shaders/effects/cas.xml
Normal file
@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<effect>
|
||||
<technique>
|
||||
<require shaders="glsl"/>
|
||||
<pass shader="glsl/cas"/>
|
||||
</technique>
|
||||
</effect>
|
91
binaries/data/mods/public/shaders/glsl/cas.fs
Normal file
91
binaries/data/mods/public/shaders/glsl/cas.fs
Normal file
@ -0,0 +1,91 @@
|
||||
#version 110
|
||||
|
||||
// LICENSE
|
||||
// =======
|
||||
// Copyright (c) 2020 Advanced Micro Devices, Inc. All rights reserved.
|
||||
// -------
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
|
||||
// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy,
|
||||
// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
// -------
|
||||
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
|
||||
// Software.
|
||||
// -------
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||||
// WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE
|
||||
|
||||
// GLSL port of the CasFilter() (no scaling). https://github.com/GPUOpen-Effects/FidelityFX-CAS/blob/master/ffx-cas/ffx_cas.h
|
||||
|
||||
uniform sampler2D renderedTex;
|
||||
uniform float width;
|
||||
uniform float height;
|
||||
uniform float sharpness;
|
||||
|
||||
varying vec2 v_tex;
|
||||
|
||||
float saturate(float inputFloat){
|
||||
return clamp(inputFloat, 0.0, 1.0);
|
||||
}
|
||||
|
||||
vec3 saturate(vec3 inputFloat){
|
||||
return vec3(saturate(inputFloat.x), saturate(inputFloat.y), saturate(inputFloat.z));
|
||||
}
|
||||
|
||||
vec3 sharpen()
|
||||
{
|
||||
vec2 invSSize = vec2(1.0 / width, 1.0 / height);
|
||||
|
||||
// No scaling algorithm uses a minimal 3x3 neighborhood around the pixel 'e',
|
||||
// a b c
|
||||
// d(e)f
|
||||
// g h i
|
||||
vec3 a = texture2D(renderedTex, v_tex + vec2(-1.0, -1.0) * invSSize).rgb;
|
||||
vec3 b = texture2D(renderedTex, v_tex + vec2(0.0, -1.0) * invSSize).rgb;
|
||||
vec3 c = texture2D(renderedTex, v_tex + vec2(1.0, -1.0) * invSSize).rgb;
|
||||
vec3 d = texture2D(renderedTex, v_tex + vec2(-1.0, 0.0) * invSSize).rgb;
|
||||
vec3 e = texture2D(renderedTex, v_tex + vec2(0.0, 0.0) * invSSize).rgb;
|
||||
vec3 f = texture2D(renderedTex, v_tex + vec2(1.0, 0.0) * invSSize).rgb;
|
||||
vec3 g = texture2D(renderedTex, v_tex + vec2(-1.0, 1.0) * invSSize).rgb;
|
||||
vec3 h = texture2D(renderedTex, v_tex + vec2(0.0, 1.0) * invSSize).rgb;
|
||||
vec3 i = texture2D(renderedTex, v_tex + vec2(1.0, 1.0) * invSSize).rgb;
|
||||
|
||||
// Soft min and max.
|
||||
// a b c b
|
||||
// d e f * 0.5 + d e f * 0.5
|
||||
// g h i h
|
||||
// These are 2.0x bigger (factored out the extra multiply).
|
||||
vec3 mnRGB = min(min(min(d, e), min(f, b)), h);
|
||||
vec3 mnRGB2 = min(mnRGB, min(min(a, c), min(g, i)));
|
||||
mnRGB += mnRGB2;
|
||||
|
||||
vec3 mxRGB = max(max(max(d, e), max(f, b)), h);
|
||||
vec3 mxRGB2 = max(mxRGB, max(max(a, c), max(g, i)));
|
||||
mxRGB += mxRGB2;
|
||||
|
||||
// Smooth minimum distance to signal limit divided by smooth max.
|
||||
vec3 rcpMRGB = 1.0 / (mxRGB);
|
||||
vec3 ampRGB = saturate(min(mnRGB, 2.0 - mxRGB) * rcpMRGB);
|
||||
|
||||
// Shaping amount of sharpening.
|
||||
ampRGB = sqrt(ampRGB);
|
||||
|
||||
float peak = -1.0 / (8.0 - 3.0 * sharpness);
|
||||
vec3 wRGB = ampRGB * peak;
|
||||
|
||||
vec3 rcpWeightRGB = 1.0 / (1.0 + 4.0 * wRGB);
|
||||
|
||||
// 0 w 0
|
||||
// Filter shape: w 1 w
|
||||
// 0 w 0
|
||||
vec3 outColor = saturate(((b + d + f + h) * wRGB + e) * rcpWeightRGB);
|
||||
|
||||
return outColor;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_FragColor.rgb = sharpen();
|
||||
}
|
13
binaries/data/mods/public/shaders/glsl/cas.xml
Normal file
13
binaries/data/mods/public/shaders/glsl/cas.xml
Normal file
@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<program type="glsl">
|
||||
|
||||
<vertex file="glsl/simple.vs">
|
||||
<stream name="pos"/>
|
||||
<stream name="uv0"/>
|
||||
<attrib name="a_vertex" semantics="gl_Vertex"/>
|
||||
<attrib name="a_uv0" semantics="gl_MultiTexCoord0"/>
|
||||
</vertex>
|
||||
|
||||
<fragment file="glsl/cas.fs"/>
|
||||
|
||||
</program>
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2014 Wildfire Games.
|
||||
/* Copyright (C) 2020 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
@ -135,6 +135,7 @@ X(shadingColor)
|
||||
X(shadowScale)
|
||||
X(shadowTex)
|
||||
X(shadowTransform)
|
||||
X(sharpness)
|
||||
X(skinBlendMatrices)
|
||||
X2(skinBlendMatrices_0, "skinBlendMatrices[0]")
|
||||
X(skyBoxRot)
|
||||
|
@ -38,7 +38,7 @@
|
||||
CPostprocManager::CPostprocManager()
|
||||
: m_IsInitialized(false), m_PingFbo(0), m_PongFbo(0), m_PostProcEffect(L"default"), m_ColorTex1(0), m_ColorTex2(0),
|
||||
m_DepthTex(0), m_BloomFbo(0), m_BlurTex2a(0), m_BlurTex2b(0), m_BlurTex4a(0), m_BlurTex4b(0),
|
||||
m_BlurTex8a(0), m_BlurTex8b(0), m_WhichBuffer(true)
|
||||
m_BlurTex8a(0), m_BlurTex8b(0), m_WhichBuffer(true), m_Sharpness(0.3f)
|
||||
{
|
||||
}
|
||||
|
||||
@ -81,6 +81,8 @@ void CPostprocManager::Initialize()
|
||||
m_Height = g_Renderer.GetHeight();
|
||||
|
||||
UpdateAntiAliasingTechnique();
|
||||
UpdateSharpeningTechnique();
|
||||
UpdateSharpnessFactor();
|
||||
RecreateBuffers();
|
||||
m_IsInitialized = true;
|
||||
|
||||
@ -428,6 +430,8 @@ void CPostprocManager::ApplyEffect(CShaderTechniquePtr &shaderTech1, int pass)
|
||||
shader->Uniform(str_zNear, m_NearPlane);
|
||||
shader->Uniform(str_zFar, m_FarPlane);
|
||||
|
||||
shader->Uniform(str_sharpness, m_Sharpness);
|
||||
|
||||
shader->Uniform(str_brightness, g_LightEnv.m_Brightness);
|
||||
shader->Uniform(str_hdr, g_LightEnv.m_Contrast);
|
||||
shader->Uniform(str_saturation, g_LightEnv.m_Saturation);
|
||||
@ -473,7 +477,8 @@ void CPostprocManager::ApplyPostproc()
|
||||
// Don't do anything if we are using the default effect and no AA.
|
||||
const bool hasEffects = m_PostProcEffect != L"default";
|
||||
const bool hasAA = m_AATech && g_RenderingOptions.GetPreferGLSL();
|
||||
if (!hasEffects && !hasAA)
|
||||
const bool hasSharp = m_SharpTech && g_RenderingOptions.GetPreferGLSL();
|
||||
if (!hasEffects && !hasAA && !hasSharp)
|
||||
return;
|
||||
|
||||
pglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_PongFbo);
|
||||
@ -508,6 +513,12 @@ void CPostprocManager::ApplyPostproc()
|
||||
ApplyEffect(m_AATech, pass);
|
||||
}
|
||||
|
||||
if (hasSharp)
|
||||
{
|
||||
for (int pass = 0; pass < m_SharpTech->GetNumPasses(); ++pass)
|
||||
ApplyEffect(m_SharpTech, pass);
|
||||
}
|
||||
|
||||
pglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_PongFbo);
|
||||
pglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, m_DepthTex, 0);
|
||||
|
||||
@ -574,6 +585,29 @@ void CPostprocManager::UpdateAntiAliasingTechnique()
|
||||
}
|
||||
}
|
||||
|
||||
void CPostprocManager::UpdateSharpeningTechnique()
|
||||
{
|
||||
if (!g_RenderingOptions.GetPreferGLSL())
|
||||
return;
|
||||
|
||||
CStr newSharpName;
|
||||
CFG_GET_VAL("sharpening", newSharpName);
|
||||
if (m_SharpName == newSharpName)
|
||||
return;
|
||||
m_SharpName = newSharpName;
|
||||
m_SharpTech.reset();
|
||||
|
||||
if (m_SharpName == "cas")
|
||||
{
|
||||
m_SharpTech = g_Renderer.GetShaderManager().LoadEffect(CStrIntern(m_SharpName));
|
||||
}
|
||||
}
|
||||
|
||||
void CPostprocManager::UpdateSharpnessFactor()
|
||||
{
|
||||
CFG_GET_VAL("sharpness", m_Sharpness);
|
||||
}
|
||||
|
||||
void CPostprocManager::SetDepthBufferClipPlanes(float nearPlane, float farPlane)
|
||||
{
|
||||
m_NearPlane = nearPlane;
|
||||
@ -637,6 +671,14 @@ void CPostprocManager::UpdateAntiAliasingTechnique()
|
||||
{
|
||||
}
|
||||
|
||||
void CPostprocManager::UpdateSharpeningTechnique()
|
||||
{
|
||||
}
|
||||
|
||||
void CPostprocManager::UpdateSharpnessFactor()
|
||||
{
|
||||
}
|
||||
|
||||
void CPostprocManager::CaptureRenderOutput()
|
||||
{
|
||||
}
|
||||
|
@ -50,6 +50,8 @@ public:
|
||||
|
||||
// Triggers update of shaders and FBO if needed.
|
||||
void UpdateAntiAliasingTechnique();
|
||||
void UpdateSharpeningTechnique();
|
||||
void UpdateSharpnessFactor();
|
||||
|
||||
void SetDepthBufferClipPlanes(float nearPlane, float farPlane);
|
||||
|
||||
@ -91,6 +93,10 @@ private:
|
||||
CStrW m_PostProcEffect;
|
||||
CShaderTechniquePtr m_PostProcTech;
|
||||
|
||||
CStr m_SharpName;
|
||||
CShaderTechniquePtr m_SharpTech;
|
||||
float m_Sharpness;
|
||||
|
||||
CStr m_AAName;
|
||||
CShaderTechniquePtr m_AATech;
|
||||
|
||||
|
@ -72,6 +72,16 @@ void JSI_Renderer::UpdateAntiAliasingTechnique(ScriptInterface::CxPrivate* UNUSE
|
||||
g_Renderer.GetPostprocManager().UpdateAntiAliasingTechnique();
|
||||
}
|
||||
|
||||
void JSI_Renderer::UpdateSharpeningTechnique(ScriptInterface::CxPrivate* UNUSED(pCxPrivate))
|
||||
{
|
||||
g_Renderer.GetPostprocManager().UpdateSharpeningTechnique();
|
||||
}
|
||||
|
||||
void JSI_Renderer::UpdateSharpnessFactor(ScriptInterface::CxPrivate* UNUSED(pCxPrivate))
|
||||
{
|
||||
g_Renderer.GetPostprocManager().UpdateSharpnessFactor();
|
||||
}
|
||||
|
||||
void JSI_Renderer::RecreateShadowMap(ScriptInterface::CxPrivate* UNUSED(pCxPrivate))
|
||||
{
|
||||
g_Renderer.GetShadowMap().RecreateTexture();
|
||||
@ -92,6 +102,8 @@ void JSI_Renderer::RegisterScriptFunctions(const ScriptInterface& scriptInterfac
|
||||
scriptInterface.RegisterFunction<void, std::string, &JSI_Renderer::SetRenderPath>("Renderer_SetRenderPath");
|
||||
scriptInterface.RegisterFunction<void, &JSI_Renderer::RecreateShadowMap>("Renderer_RecreateShadowMap");
|
||||
scriptInterface.RegisterFunction<void, &JSI_Renderer::UpdateAntiAliasingTechnique>("Renderer_UpdateAntiAliasingTechnique");
|
||||
scriptInterface.RegisterFunction<void, &JSI_Renderer::UpdateSharpeningTechnique>("Renderer_UpdateSharpeningTechnique");
|
||||
scriptInterface.RegisterFunction<void, &JSI_Renderer::UpdateSharpnessFactor>("Renderer_UpdateSharpnessFactor");
|
||||
scriptInterface.RegisterFunction<bool, std::wstring, &JSI_Renderer::TextureExists>("TextureExists");
|
||||
REGISTER_BOOLEAN_SCRIPT_SETTING(Shadows);
|
||||
REGISTER_BOOLEAN_SCRIPT_SETTING(ShadowPCF);
|
||||
|
@ -29,6 +29,8 @@ namespace JSI_Renderer
|
||||
std::string GetRenderPath(ScriptInterface::CxPrivate* pCxPrivate);
|
||||
void SetRenderPath(ScriptInterface::CxPrivate* pCxPrivate, const std::string& name);
|
||||
void UpdateAntiAliasingTechnique(ScriptInterface::CxPrivate* pCxPrivate);
|
||||
void UpdateSharpeningTechnique(ScriptInterface::CxPrivate* pCxPrivate);
|
||||
void UpdateSharpnessFactor(ScriptInterface::CxPrivate* pCxPrivate);
|
||||
void RecreateShadowMap(ScriptInterface::CxPrivate* pCxPrivate);
|
||||
bool TextureExists(ScriptInterface::CxPrivate* pCxPrivate, const std::wstring& filename);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user