Skip to content

Commit

Permalink
Hack in some sexxxy FXAA (ST)
Browse files Browse the repository at this point in the history
  • Loading branch information
grapereader committed Apr 4, 2021
1 parent 8878367 commit 7ba37fe
Show file tree
Hide file tree
Showing 4 changed files with 218 additions and 1 deletion.
119 changes: 119 additions & 0 deletions client/shaders/fxaa/opengl_fragment.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
uniform sampler2D baseTexture;

uniform vec2 resolution;

// The MIT License (MIT) Copyright (c) 2014 Matt DesLauriers

// 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.


#define rendered baseTexture

#ifndef FXAA_REDUCE_MIN
#define FXAA_REDUCE_MIN (1.0/ 128.0)
#endif
#ifndef FXAA_REDUCE_MUL
#define FXAA_REDUCE_MUL (1.0 / 8.0)
#endif
#ifndef FXAA_SPAN_MAX
#define FXAA_SPAN_MAX 8.0
#endif

void texcoords(vec2 fragCoord, vec2 resl,
out vec2 v_rgbNW, out vec2 v_rgbNE,
out vec2 v_rgbSW, out vec2 v_rgbSE,
out vec2 v_rgbM) {
vec2 inverseVP = 1.0 / resl.xy;
v_rgbNW = (fragCoord + vec2(-1.0, -1.0)) * inverseVP;
v_rgbNE = (fragCoord + vec2(1.0, -1.0)) * inverseVP;
v_rgbSW = (fragCoord + vec2(-1.0, 1.0)) * inverseVP;
v_rgbSE = (fragCoord + vec2(1.0, 1.0)) * inverseVP;
v_rgbM = vec2(fragCoord * inverseVP);
}

//optimized version for mobile, where dependent
//texture reads can be a bottleneck
vec4 fxaa(sampler2D tex, vec2 fragCoord, vec2 resl,
vec2 v_rgbNW, vec2 v_rgbNE,
vec2 v_rgbSW, vec2 v_rgbSE,
vec2 v_rgbM) {
vec4 color;
mediump vec2 inverseVP = vec2(1.0 / resl.x, 1.0 / resl.y);
vec3 rgbNW = texture2D(tex, v_rgbNW).xyz;
vec3 rgbNE = texture2D(tex, v_rgbNE).xyz;
vec3 rgbSW = texture2D(tex, v_rgbSW).xyz;
vec3 rgbSE = texture2D(tex, v_rgbSE).xyz;
vec4 texColor = texture2D(tex, v_rgbM);
vec3 rgbM = texColor.xyz;
vec3 luma = vec3(0.299, 0.587, 0.114);
float lumaNW = dot(rgbNW, luma);
float lumaNE = dot(rgbNE, luma);
float lumaSW = dot(rgbSW, luma);
float lumaSE = dot(rgbSE, luma);
float lumaM = dot(rgbM, luma);
float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE)));
float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE)));

mediump vec2 dir;
dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE));
dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE));

float dirReduce = max((lumaNW + lumaNE + lumaSW + lumaSE) *
(0.25 * FXAA_REDUCE_MUL), FXAA_REDUCE_MIN);

float rcpDirMin = 1.0 / (min(abs(dir.x), abs(dir.y)) + dirReduce);
dir = min(vec2(FXAA_SPAN_MAX, FXAA_SPAN_MAX),
max(vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX),
dir * rcpDirMin)) * inverseVP;

vec3 rgbA = 0.5 * (
texture2D(tex, fragCoord * inverseVP + dir * (1.0 / 3.0 - 0.5)).xyz +
texture2D(tex, fragCoord * inverseVP + dir * (2.0 / 3.0 - 0.5)).xyz);
vec3 rgbB = rgbA * 0.5 + 0.25 * (
texture2D(tex, fragCoord * inverseVP + dir * -0.5).xyz +
texture2D(tex, fragCoord * inverseVP + dir * 0.5).xyz);

float lumaB = dot(rgbB, luma);
if ((lumaB < lumaMin) || (lumaB > lumaMax))
color = vec4(rgbA, texColor.a);
else
color = vec4(rgbB, texColor.a);
return color;
}

vec4 apply(sampler2D tex, vec2 fragCoord, vec2 resl) {
mediump vec2 v_rgbNW;
mediump vec2 v_rgbNE;
mediump vec2 v_rgbSW;
mediump vec2 v_rgbSE;
mediump vec2 v_rgbM;

//compute the texture coords
texcoords(fragCoord, resl, v_rgbNW, v_rgbNE, v_rgbSW, v_rgbSE, v_rgbM);

//compute FXAA
return fxaa(tex, fragCoord, resl, v_rgbNW, v_rgbNE, v_rgbSW, v_rgbSE, v_rgbM);
}

void main(void)
{
gl_FragColor = apply(rendered, gl_TexCoord[0].st * resolution, resolution);
//gl_FragColor = texture2D(rendered, gl_TexCoord[0].st).rgba;
}
6 changes: 6 additions & 0 deletions client/shaders/fxaa/opengl_vertex.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
void main(void)
{
gl_TexCoord[0] = gl_MultiTexCoord0;
gl_Position = gl_Vertex;
gl_FrontColor = gl_BackColor = gl_Color;
}
89 changes: 88 additions & 1 deletion src/client/render/plain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,57 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "plain.h"
#include "settings.h"

#include "client/client.h"
#include "client/shader.h"
#include "client/tile.h"

// With the IShaderConstantSetter, uniforms of the shader can be set (probably)
class OversampleShaderConstantSetter : public IShaderConstantSetter
{
public:
OversampleShaderConstantSetter(RenderingCorePlain *core) :
m_core(core), m_resolution("resolution")
{
}

~OversampleShaderConstantSetter() override = default;

void onSetConstants(video::IMaterialRendererServices *services) override
{
// TODO: Why is the resolution uniform never set?

v2u32 render_size = m_core->getScreensize();
float as_array[2] = {
(float)render_size.X,
(float)render_size.Y,
};
m_resolution.set(as_array, services);
}

//~ void onSetMaterial(const video::SMaterial& material) override
//~ {
//~ m_render_size = render_size;
//~ }

private:
RenderingCorePlain *m_core;
CachedPixelShaderSetting<float, 2> m_resolution;
};

// Each shader requires a constant setter and a factory for it
class OversampleShaderConstantSetterFactory : public IShaderConstantSetterFactory
{
RenderingCorePlain *m_core;

public:
OversampleShaderConstantSetterFactory(RenderingCorePlain *core) : m_core(core) {}

virtual IShaderConstantSetter *create()
{
return new OversampleShaderConstantSetter(m_core);
}
};

inline u32 scaledown(u32 coef, u32 size)
{
return (size + coef - 1) / coef;
Expand All @@ -31,10 +82,28 @@ RenderingCorePlain::RenderingCorePlain(
: RenderingCore(_device, _client, _hud)
{
scale = g_settings->getU16("undersampling");

IWritableShaderSource *s = client->getShaderSource();
s->addShaderConstantSetterFactory(
new OversampleShaderConstantSetterFactory(this));
u32 shader = s->getShader("fxaa", TILE_MATERIAL_BASIC, NDT_NORMAL);
renderMaterial.UseMipMaps = false;
renderMaterial.MaterialType = s->getShaderInfo(shader).material;
renderMaterial.TextureLayer[0].AnisotropicFilter = false;
renderMaterial.TextureLayer[0].BilinearFilter = false;
renderMaterial.TextureLayer[0].TrilinearFilter = false;
renderMaterial.TextureLayer[0].TextureWrapU = video::ETC_CLAMP_TO_EDGE;
renderMaterial.TextureLayer[0].TextureWrapV = video::ETC_CLAMP_TO_EDGE;

}

void RenderingCorePlain::initTextures()
{
rendered = driver->addRenderTargetTexture(screensize, "3d_render",
//~ video::ECF_A8R8G8B8);
video::ECF_A16B16G16R16F);
renderMaterial.TextureLayer[0].Texture = rendered;

if (scale <= 1)
return;
v2u32 size{scaledown(scale, screensize.X), scaledown(scale, screensize.Y)};
Expand All @@ -44,6 +113,8 @@ void RenderingCorePlain::initTextures()

void RenderingCorePlain::clearTextures()
{
driver->removeTexture(rendered);

if (scale <= 1)
return;
driver->removeTexture(lowres);
Expand All @@ -69,8 +140,24 @@ void RenderingCorePlain::upscale()

void RenderingCorePlain::drawAll()
{
driver->setRenderTarget(rendered, true, true, skycolor);
draw3D();
driver->setRenderTarget(nullptr, false, false, skycolor);
static const video::S3DVertex vertices[4] = {
video::S3DVertex(1.0, -1.0, 0.0, 0.0, 0.0, -1.0,
video::SColor(255, 0, 255, 255), 1.0, 0.0),
video::S3DVertex(-1.0, -1.0, 0.0, 0.0, 0.0, -1.0,
video::SColor(255, 255, 0, 255), 0.0, 0.0),
video::S3DVertex(-1.0, 1.0, 0.0, 0.0, 0.0, -1.0,
video::SColor(255, 255, 255, 0), 0.0, 1.0),
video::S3DVertex(1.0, 1.0, 0.0, 0.0, 0.0, -1.0,
video::SColor(255, 255, 255, 255), 1.0, 1.0),
};
static const u16 indices[6] = {0, 1, 2, 2, 3, 0};
driver->setMaterial(renderMaterial);
driver->drawVertexPrimitiveList(&vertices, 4, &indices, 2);

drawPostFx();
upscale();
// upscale();
drawHUD();
}
5 changes: 5 additions & 0 deletions src/client/render/plain.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,12 @@ class RenderingCorePlain : public RenderingCore
void beforeDraw() override;
void upscale();

video::ITexture *rendered = nullptr;
video::SMaterial renderMaterial;


public:
RenderingCorePlain(IrrlichtDevice *_device, Client *_client, Hud *_hud);
void drawAll() override;
v2u32 getScreensize() const { return screensize; }
};

0 comments on commit 7ba37fe

Please sign in to comment.