mirror of
https://github.com/hyprwm/Hyprland
synced 2025-04-07 02:31:52 +02:00
renderer/opengl: Extract shaders from source (#9600)
--------- Co-authored-by: Mihai Fufezan <mihai@fufexan.net>
This commit is contained in:
parent
a46576afc3
commit
7374a023ef
35 changed files with 1533 additions and 1059 deletions
.gitignoreCMakeLists.txtmeson.build
scripts
src
debug
render
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -28,6 +28,8 @@ protocols/*.c*
|
|||
protocols/*.h*
|
||||
.ccls-cache
|
||||
*.so
|
||||
src/render/shaders/*.inc
|
||||
src/render/shaders/Shaders.hpp
|
||||
|
||||
hyprctl/hyprctl
|
||||
|
||||
|
|
|
@ -25,6 +25,9 @@ message(STATUS "Gathering git info")
|
|||
# Get git info hash and branch
|
||||
execute_process(COMMAND ./scripts/generateVersion.sh
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
|
||||
# Make shader files includable
|
||||
execute_process(COMMAND ./scripts/generateShaderIncludes.sh
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
|
||||
|
||||
find_package(PkgConfig REQUIRED)
|
||||
|
||||
|
@ -445,4 +448,5 @@ install(
|
|||
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/hyprland
|
||||
FILES_MATCHING
|
||||
PATTERN "*.h*"
|
||||
PATTERN "*.frag")
|
||||
PATTERN "*.inc"
|
||||
)
|
||||
|
|
|
@ -87,9 +87,11 @@ endif
|
|||
|
||||
# Generate hyprland version and populate version.h
|
||||
run_command('sh', '-c', 'scripts/generateVersion.sh', check: true)
|
||||
# Make shader files includable
|
||||
run_command('sh', '-c', 'scripts/generateShaderIncludes.sh', check: true)
|
||||
|
||||
# Install headers
|
||||
globber = run_command('find', 'src', '-name', '*.h*', '-o', '-name', '*.frag', check: true)
|
||||
globber = run_command('find', 'src', '-name', '*.h*', '-o', '-name', '*.inc', check: true)
|
||||
headers = globber.stdout().strip().split('\n')
|
||||
foreach file : headers
|
||||
install_headers(file, subdir: 'hyprland', preserve_path: true)
|
||||
|
|
24
scripts/generateShaderIncludes.sh
Executable file
24
scripts/generateShaderIncludes.sh
Executable file
|
@ -0,0 +1,24 @@
|
|||
#!/bin/sh
|
||||
|
||||
SHADERS_SRC="./src/render/shaders/glsl"
|
||||
|
||||
echo "-- Generating shader includes"
|
||||
|
||||
if [ ! -d ./src/render/shaders ]; then
|
||||
mkdir ./src/render/shaders
|
||||
fi
|
||||
|
||||
echo '#pragma once' > ./src/render/shaders/Shaders.hpp
|
||||
echo '#include <map>' >> ./src/render/shaders/Shaders.hpp
|
||||
echo 'static const std::map<std::string, std::string> SHADERS = {' >> ./src/render/shaders/Shaders.hpp
|
||||
|
||||
for filename in `ls ${SHADERS_SRC}`; do
|
||||
echo "-- ${filename}"
|
||||
|
||||
{ echo 'R"#('; cat ${SHADERS_SRC}/${filename}; echo ')#"'; } > ./src/render/shaders/${filename}.inc
|
||||
echo "{\"${filename}\"," >> ./src/render/shaders/Shaders.hpp
|
||||
echo "#include \"./${filename}.inc\"" >> ./src/render/shaders/Shaders.hpp
|
||||
echo "}," >> ./src/render/shaders/Shaders.hpp
|
||||
done
|
||||
|
||||
echo '};' >> ./src/render/shaders/Shaders.hpp
|
|
@ -51,6 +51,7 @@ using namespace Hyprutils::OS;
|
|||
#include "../managers/AnimationManager.hpp"
|
||||
#include "../debug/HyprNotificationOverlay.hpp"
|
||||
#include "../render/Renderer.hpp"
|
||||
#include "../render/OpenGL.hpp"
|
||||
|
||||
static void trimTrailingComma(std::string& str) {
|
||||
if (!str.empty() && str.back() == ',')
|
||||
|
@ -1643,6 +1644,13 @@ static std::string submapRequest(eHyprCtlOutputFormat format, std::string reques
|
|||
return format == FORMAT_JSON ? std::format("{{\"{}\"}}\n", escapeJSONStrings(submap)) : (submap + "\n");
|
||||
}
|
||||
|
||||
static std::string reloadShaders(eHyprCtlOutputFormat format, std::string request) {
|
||||
if (g_pHyprOpenGL->initShaders())
|
||||
return format == FORMAT_JSON ? "{\"ok\": true}" : "ok";
|
||||
else
|
||||
return format == FORMAT_JSON ? "{\"ok\": false}" : "error";
|
||||
}
|
||||
|
||||
CHyprCtl::CHyprCtl() {
|
||||
registerCommand(SHyprCtlCommand{"workspaces", true, workspacesRequest});
|
||||
registerCommand(SHyprCtlCommand{"workspacerules", true, workspaceRulesRequest});
|
||||
|
@ -1665,6 +1673,7 @@ CHyprCtl::CHyprCtl() {
|
|||
registerCommand(SHyprCtlCommand{"locked", true, getIsLocked});
|
||||
registerCommand(SHyprCtlCommand{"descriptions", true, getDescriptions});
|
||||
registerCommand(SHyprCtlCommand{"submap", true, submapRequest});
|
||||
registerCommand(SHyprCtlCommand{.name = "reloadshaders", .exact = true, .fn = reloadShaders});
|
||||
|
||||
registerCommand(SHyprCtlCommand{"monitors", false, monitorsRequest});
|
||||
registerCommand(SHyprCtlCommand{"reload", false, reloadRequest});
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -9,6 +9,7 @@
|
|||
#include "../helpers/sync/SyncTimeline.hpp"
|
||||
#include <cstdint>
|
||||
#include <list>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <map>
|
||||
|
||||
|
@ -78,6 +79,26 @@ enum eMonitorExtraRenderFBs : uint8_t {
|
|||
FB_MONITOR_RENDER_EXTRA_BLUR,
|
||||
};
|
||||
|
||||
struct SPreparedShaders {
|
||||
std::string TEXVERTSRC;
|
||||
std::string TEXVERTSRC300;
|
||||
std::string TEXVERTSRC320;
|
||||
CShader m_shQUAD;
|
||||
CShader m_shRGBA;
|
||||
CShader m_shPASSTHRURGBA;
|
||||
CShader m_shMATTE;
|
||||
CShader m_shRGBX;
|
||||
CShader m_shEXT;
|
||||
CShader m_shBLUR1;
|
||||
CShader m_shBLUR2;
|
||||
CShader m_shBLURPREPARE;
|
||||
CShader m_shBLURFINISH;
|
||||
CShader m_shSHADOW;
|
||||
CShader m_shBORDER1;
|
||||
CShader m_shGLITCH;
|
||||
CShader m_shCM;
|
||||
};
|
||||
|
||||
struct SMonitorRenderData {
|
||||
CFramebuffer offloadFB;
|
||||
CFramebuffer mirrorFB; // these are used for some effects,
|
||||
|
@ -90,23 +111,6 @@ struct SMonitorRenderData {
|
|||
|
||||
bool blurFBDirty = true;
|
||||
bool blurFBShouldRender = false;
|
||||
|
||||
// Shaders
|
||||
bool m_bShadersInitialized = false;
|
||||
CShader m_shQUAD;
|
||||
CShader m_shRGBA;
|
||||
CShader m_shPASSTHRURGBA;
|
||||
CShader m_shMATTE;
|
||||
CShader m_shRGBX;
|
||||
CShader m_shEXT;
|
||||
CShader m_shBLUR1;
|
||||
CShader m_shBLUR2;
|
||||
CShader m_shBLURPREPARE;
|
||||
CShader m_shBLURFINISH;
|
||||
CShader m_shSHADOW;
|
||||
CShader m_shBORDER1;
|
||||
CShader m_shGLITCH;
|
||||
CShader m_shCM;
|
||||
};
|
||||
|
||||
struct SCurrentRenderData {
|
||||
|
@ -232,6 +236,10 @@ class CHyprOpenGLImpl {
|
|||
EGLImageKHR createEGLImage(const Aquamarine::SDMABUFAttrs& attrs);
|
||||
SP<CEGLSync> createEGLSync(int fence = -1);
|
||||
|
||||
bool initShaders();
|
||||
bool m_bShadersInitialized = false;
|
||||
SP<SPreparedShaders> m_shaders;
|
||||
|
||||
SCurrentRenderData m_RenderData;
|
||||
|
||||
Hyprutils::OS::CFileDescriptor m_iGBMFD;
|
||||
|
@ -309,7 +317,6 @@ class CHyprOpenGLImpl {
|
|||
GLuint createProgram(const std::string&, const std::string&, bool dynamic = false, bool silent = false);
|
||||
GLuint compileShader(const GLuint&, std::string, bool dynamic = false, bool silent = false);
|
||||
void createBGTextureForMonitor(PHLMONITOR);
|
||||
void initShaders();
|
||||
void initDRMFormats();
|
||||
void initEGL(bool gbm);
|
||||
EGLDeviceEXT eglDeviceFromDRMFD(int drmFD);
|
||||
|
@ -322,6 +329,9 @@ class CHyprOpenGLImpl {
|
|||
// returns the out FB, can be either Mirror or MirrorSwap
|
||||
CFramebuffer* blurMainFramebufferWithDamage(float a, CRegion* damage);
|
||||
|
||||
void passCMUniforms(const CShader&, const NColorManagement::SImageDescription& imageDescription, const NColorManagement::SImageDescription& targetImageDescription,
|
||||
bool modifySDR = false);
|
||||
void passCMUniforms(const CShader&, const NColorManagement::SImageDescription& imageDescription);
|
||||
void renderTextureInternalWithDamage(SP<CTexture>, const CBox& box, float a, const CRegion& damage, int round = 0, float roundingPower = 2.0f, bool discardOpaque = false,
|
||||
bool noAA = false, bool allowCustomUV = false, bool allowDim = false);
|
||||
void renderTexturePrimitive(SP<CTexture> tex, const CBox& box);
|
||||
|
|
|
@ -1,17 +1,5 @@
|
|||
#include "Shader.hpp"
|
||||
|
||||
GLint CShader::getUniformLocation(const std::string& unif) {
|
||||
const auto itpos = m_muUniforms.find(unif);
|
||||
|
||||
if (itpos == m_muUniforms.end()) {
|
||||
const auto unifLoc = glGetUniformLocation(program, unif.c_str());
|
||||
m_muUniforms[unif] = unifLoc;
|
||||
return unifLoc;
|
||||
}
|
||||
|
||||
return itpos->second;
|
||||
}
|
||||
|
||||
CShader::~CShader() {
|
||||
destroy();
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ class CShader {
|
|||
GLint color = -1;
|
||||
GLint alphaMatte = -1;
|
||||
GLint texType = -1;
|
||||
GLint skipCM = -1;
|
||||
GLint sourceTF = -1;
|
||||
GLint targetTF = -1;
|
||||
GLint sourcePrimaries = -1;
|
||||
|
@ -74,8 +75,6 @@ class CShader {
|
|||
GLint brightness = -1;
|
||||
GLint noise = -1;
|
||||
|
||||
GLint getUniformLocation(const std::string&);
|
||||
|
||||
void destroy();
|
||||
|
||||
private:
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include "shaders/Textures.hpp"
|
||||
#include "shaders/Shadow.hpp"
|
||||
#include "shaders/Border.hpp"
|
|
@ -1,3 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
constexpr float SHADER_ROUNDED_SMOOTHING_FACTOR = M_PI / 5.34665792551;
|
|
@ -1,541 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <format>
|
||||
#include "SharedValues.hpp"
|
||||
|
||||
inline static constexpr auto ROUNDED_SHADER_FUNC = [](const std::string colorVarName) -> std::string {
|
||||
return R"#(
|
||||
|
||||
// shoutout me: I fixed this shader being a bit pixelated while watching hentai
|
||||
|
||||
highp vec2 pixCoord = vec2(gl_FragCoord);
|
||||
pixCoord -= topLeft + fullSize * 0.5;
|
||||
pixCoord *= vec2(lessThan(pixCoord, vec2(0.0))) * -2.0 + 1.0;
|
||||
pixCoord -= fullSize * 0.5 - radius;
|
||||
pixCoord += vec2(1.0, 1.0) / fullSize; // center the pix dont make it top-left
|
||||
|
||||
// smoothing constant for the edge: more = blurrier, but smoother
|
||||
const float SMOOTHING_CONSTANT = )#" +
|
||||
std::format("{:.7f}", SHADER_ROUNDED_SMOOTHING_FACTOR) + R"#(;
|
||||
|
||||
if (pixCoord.x + pixCoord.y > radius) {
|
||||
|
||||
float dist = pow(pow(pixCoord.x, roundingPower) + pow(pixCoord.y, roundingPower), 1.0/roundingPower);
|
||||
|
||||
if (dist > radius + SMOOTHING_CONSTANT)
|
||||
discard;
|
||||
|
||||
float normalized = 1.0 - smoothstep(0.0, 1.0, (dist - radius + SMOOTHING_CONSTANT) / (SMOOTHING_CONSTANT * 2.0));
|
||||
|
||||
)#" +
|
||||
colorVarName + R"#( = )#" + colorVarName + R"#( * normalized;
|
||||
}
|
||||
)#";
|
||||
};
|
||||
|
||||
inline const std::string QUADVERTSRC = R"#(
|
||||
uniform mat3 proj;
|
||||
uniform vec4 color;
|
||||
attribute vec2 pos;
|
||||
attribute vec2 texcoord;
|
||||
attribute vec2 texcoordMatte;
|
||||
varying vec4 v_color;
|
||||
varying vec2 v_texcoord;
|
||||
varying vec2 v_texcoordMatte;
|
||||
|
||||
void main() {
|
||||
gl_Position = vec4(proj * vec3(pos, 1.0), 1.0);
|
||||
v_color = color;
|
||||
v_texcoord = texcoord;
|
||||
v_texcoordMatte = texcoordMatte;
|
||||
})#";
|
||||
|
||||
inline const std::string QUADFRAGSRC = R"#(
|
||||
precision highp float;
|
||||
varying vec4 v_color;
|
||||
|
||||
uniform vec2 topLeft;
|
||||
uniform vec2 fullSize;
|
||||
uniform float radius;
|
||||
uniform float roundingPower;
|
||||
|
||||
void main() {
|
||||
|
||||
vec4 pixColor = v_color;
|
||||
|
||||
if (radius > 0.0) {
|
||||
)#" +
|
||||
ROUNDED_SHADER_FUNC("pixColor") + R"#(
|
||||
}
|
||||
|
||||
gl_FragColor = pixColor;
|
||||
})#";
|
||||
|
||||
inline const std::string TEXVERTSRC = R"#(
|
||||
uniform mat3 proj;
|
||||
attribute vec2 pos;
|
||||
attribute vec2 texcoord;
|
||||
varying vec2 v_texcoord;
|
||||
|
||||
void main() {
|
||||
gl_Position = vec4(proj * vec3(pos, 1.0), 1.0);
|
||||
v_texcoord = texcoord;
|
||||
})#";
|
||||
|
||||
inline const std::string TEXVERTSRC320 = R"#(#version 320 es
|
||||
uniform mat3 proj;
|
||||
in vec2 pos;
|
||||
in vec2 texcoord;
|
||||
out vec2 v_texcoord;
|
||||
|
||||
void main() {
|
||||
gl_Position = vec4(proj * vec3(pos, 1.0), 1.0);
|
||||
v_texcoord = texcoord;
|
||||
})#";
|
||||
|
||||
inline const std::string TEXFRAGSRCCM =
|
||||
#include "CM.frag"
|
||||
;
|
||||
|
||||
inline const std::string TEXFRAGSRCRGBA = R"#(
|
||||
precision highp float;
|
||||
varying vec2 v_texcoord; // is in 0-1
|
||||
uniform sampler2D tex;
|
||||
uniform float alpha;
|
||||
|
||||
uniform vec2 topLeft;
|
||||
uniform vec2 fullSize;
|
||||
uniform float radius;
|
||||
uniform float roundingPower;
|
||||
|
||||
uniform int discardOpaque;
|
||||
uniform int discardAlpha;
|
||||
uniform float discardAlphaValue;
|
||||
|
||||
uniform int applyTint;
|
||||
uniform vec3 tint;
|
||||
|
||||
void main() {
|
||||
|
||||
vec4 pixColor = texture2D(tex, v_texcoord);
|
||||
|
||||
if (discardOpaque == 1 && pixColor[3] * alpha == 1.0)
|
||||
discard;
|
||||
|
||||
if (discardAlpha == 1 && pixColor[3] <= discardAlphaValue)
|
||||
discard;
|
||||
|
||||
if (applyTint == 1) {
|
||||
pixColor[0] = pixColor[0] * tint[0];
|
||||
pixColor[1] = pixColor[1] * tint[1];
|
||||
pixColor[2] = pixColor[2] * tint[2];
|
||||
}
|
||||
|
||||
if (radius > 0.0) {
|
||||
)#" +
|
||||
ROUNDED_SHADER_FUNC("pixColor") + R"#(
|
||||
}
|
||||
|
||||
gl_FragColor = pixColor * alpha;
|
||||
})#";
|
||||
|
||||
inline const std::string TEXFRAGSRCRGBAPASSTHRU = R"#(
|
||||
precision highp float;
|
||||
varying vec2 v_texcoord; // is in 0-1
|
||||
uniform sampler2D tex;
|
||||
|
||||
void main() {
|
||||
gl_FragColor = texture2D(tex, v_texcoord);
|
||||
})#";
|
||||
|
||||
inline const std::string TEXFRAGSRCRGBAMATTE = R"#(
|
||||
precision highp float;
|
||||
varying vec2 v_texcoord; // is in 0-1
|
||||
uniform sampler2D tex;
|
||||
uniform sampler2D texMatte;
|
||||
|
||||
void main() {
|
||||
gl_FragColor = texture2D(tex, v_texcoord) * texture2D(texMatte, v_texcoord)[0]; // I know it only uses R, but matte should be black/white anyways.
|
||||
})#";
|
||||
|
||||
inline const std::string TEXFRAGSRCRGBX = R"#(
|
||||
precision highp float;
|
||||
varying vec2 v_texcoord;
|
||||
uniform sampler2D tex;
|
||||
uniform float alpha;
|
||||
|
||||
uniform vec2 topLeft;
|
||||
uniform vec2 fullSize;
|
||||
uniform float radius;
|
||||
uniform float roundingPower;
|
||||
|
||||
uniform int discardOpaque;
|
||||
uniform int discardAlpha;
|
||||
uniform int discardAlphaValue;
|
||||
|
||||
uniform int applyTint;
|
||||
uniform vec3 tint;
|
||||
|
||||
void main() {
|
||||
|
||||
if (discardOpaque == 1 && alpha == 1.0)
|
||||
discard;
|
||||
|
||||
vec4 pixColor = vec4(texture2D(tex, v_texcoord).rgb, 1.0);
|
||||
|
||||
if (applyTint == 1) {
|
||||
pixColor[0] = pixColor[0] * tint[0];
|
||||
pixColor[1] = pixColor[1] * tint[1];
|
||||
pixColor[2] = pixColor[2] * tint[2];
|
||||
}
|
||||
|
||||
if (radius > 0.0) {
|
||||
)#" +
|
||||
ROUNDED_SHADER_FUNC("pixColor") + R"#(
|
||||
}
|
||||
|
||||
gl_FragColor = pixColor * alpha;
|
||||
})#";
|
||||
|
||||
inline const std::string FRAGBLUR1 = R"#(
|
||||
#version 100
|
||||
precision highp float;
|
||||
varying highp vec2 v_texcoord; // is in 0-1
|
||||
uniform sampler2D tex;
|
||||
|
||||
uniform float radius;
|
||||
uniform vec2 halfpixel;
|
||||
uniform int passes;
|
||||
uniform float vibrancy;
|
||||
uniform float vibrancy_darkness;
|
||||
|
||||
// see http://alienryderflex.com/hsp.html
|
||||
const float Pr = 0.299;
|
||||
const float Pg = 0.587;
|
||||
const float Pb = 0.114;
|
||||
|
||||
// Y is "v" ( brightness ). X is "s" ( saturation )
|
||||
// see https://www.desmos.com/3d/a88652b9a4
|
||||
// Determines if high brightness or high saturation is more important
|
||||
const float a = 0.93;
|
||||
const float b = 0.11;
|
||||
const float c = 0.66; // Determines the smoothness of the transition of unboosted to boosted colors
|
||||
//
|
||||
|
||||
// http://www.flong.com/archive/texts/code/shapers_circ/
|
||||
float doubleCircleSigmoid(float x, float a) {
|
||||
a = clamp(a, 0.0, 1.0);
|
||||
|
||||
float y = .0;
|
||||
if (x <= a) {
|
||||
y = a - sqrt(a * a - x * x);
|
||||
} else {
|
||||
y = a + sqrt(pow(1. - a, 2.) - pow(x - 1., 2.));
|
||||
}
|
||||
return y;
|
||||
}
|
||||
|
||||
vec3 rgb2hsl(vec3 col) {
|
||||
float red = col.r;
|
||||
float green = col.g;
|
||||
float blue = col.b;
|
||||
|
||||
float minc = min(col.r, min(col.g, col.b));
|
||||
float maxc = max(col.r, max(col.g, col.b));
|
||||
float delta = maxc - minc;
|
||||
|
||||
float lum = (minc + maxc) * 0.5;
|
||||
float sat = 0.0;
|
||||
float hue = 0.0;
|
||||
|
||||
if (lum > 0.0 && lum < 1.0) {
|
||||
float mul = (lum < 0.5) ? (lum) : (1.0 - lum);
|
||||
sat = delta / (mul * 2.0);
|
||||
}
|
||||
|
||||
if (delta > 0.0) {
|
||||
vec3 maxcVec = vec3(maxc);
|
||||
vec3 masks = vec3(equal(maxcVec, col)) * vec3(notEqual(maxcVec, vec3(green, blue, red)));
|
||||
vec3 adds = vec3(0.0, 2.0, 4.0) + vec3(green - blue, blue - red, red - green) / delta;
|
||||
|
||||
hue += dot(adds, masks);
|
||||
hue /= 6.0;
|
||||
|
||||
if (hue < 0.0)
|
||||
hue += 1.0;
|
||||
}
|
||||
|
||||
return vec3(hue, sat, lum);
|
||||
}
|
||||
|
||||
vec3 hsl2rgb(vec3 col) {
|
||||
const float onethird = 1.0 / 3.0;
|
||||
const float twothird = 2.0 / 3.0;
|
||||
const float rcpsixth = 6.0;
|
||||
|
||||
float hue = col.x;
|
||||
float sat = col.y;
|
||||
float lum = col.z;
|
||||
|
||||
vec3 xt = vec3(0.0);
|
||||
|
||||
if (hue < onethird) {
|
||||
xt.r = rcpsixth * (onethird - hue);
|
||||
xt.g = rcpsixth * hue;
|
||||
xt.b = 0.0;
|
||||
} else if (hue < twothird) {
|
||||
xt.r = 0.0;
|
||||
xt.g = rcpsixth * (twothird - hue);
|
||||
xt.b = rcpsixth * (hue - onethird);
|
||||
} else
|
||||
xt = vec3(rcpsixth * (hue - twothird), 0.0, rcpsixth * (1.0 - hue));
|
||||
|
||||
xt = min(xt, 1.0);
|
||||
|
||||
float sat2 = 2.0 * sat;
|
||||
float satinv = 1.0 - sat;
|
||||
float luminv = 1.0 - lum;
|
||||
float lum2m1 = (2.0 * lum) - 1.0;
|
||||
vec3 ct = (sat2 * xt) + satinv;
|
||||
|
||||
vec3 rgb;
|
||||
if (lum >= 0.5)
|
||||
rgb = (luminv * ct) + lum2m1;
|
||||
else
|
||||
rgb = lum * ct;
|
||||
|
||||
return rgb;
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec2 uv = v_texcoord * 2.0;
|
||||
|
||||
vec4 sum = texture2D(tex, uv) * 4.0;
|
||||
sum += texture2D(tex, uv - halfpixel.xy * radius);
|
||||
sum += texture2D(tex, uv + halfpixel.xy * radius);
|
||||
sum += texture2D(tex, uv + vec2(halfpixel.x, -halfpixel.y) * radius);
|
||||
sum += texture2D(tex, uv - vec2(halfpixel.x, -halfpixel.y) * radius);
|
||||
|
||||
vec4 color = sum / 8.0;
|
||||
|
||||
if (vibrancy == 0.0) {
|
||||
gl_FragColor = color;
|
||||
} else {
|
||||
// Invert it so that it correctly maps to the config setting
|
||||
float vibrancy_darkness1 = 1.0 - vibrancy_darkness;
|
||||
|
||||
// Decrease the RGB components based on their perceived brightness, to prevent visually dark colors from overblowing the rest.
|
||||
vec3 hsl = rgb2hsl(color.rgb);
|
||||
// Calculate perceived brightness, as not boost visually dark colors like deep blue as much as equally saturated yellow
|
||||
float perceivedBrightness = doubleCircleSigmoid(sqrt(color.r * color.r * Pr + color.g * color.g * Pg + color.b * color.b * Pb), 0.8 * vibrancy_darkness1);
|
||||
|
||||
float b1 = b * vibrancy_darkness1;
|
||||
float boostBase = hsl[1] > 0.0 ? smoothstep(b1 - c * 0.5, b1 + c * 0.5, 1.0 - (pow(1.0 - hsl[1] * cos(a), 2.0) + pow(1.0 - perceivedBrightness * sin(a), 2.0))) : 0.0;
|
||||
|
||||
float saturation = clamp(hsl[1] + (boostBase * vibrancy) / float(passes), 0.0, 1.0);
|
||||
|
||||
vec3 newColor = hsl2rgb(vec3(hsl[0], saturation, hsl[2]));
|
||||
|
||||
gl_FragColor = vec4(newColor, color[3]);
|
||||
}
|
||||
}
|
||||
)#";
|
||||
|
||||
inline const std::string FRAGBLUR2 = R"#(
|
||||
#version 100
|
||||
precision highp float;
|
||||
varying highp vec2 v_texcoord; // is in 0-1
|
||||
uniform sampler2D tex;
|
||||
|
||||
uniform float radius;
|
||||
uniform vec2 halfpixel;
|
||||
|
||||
void main() {
|
||||
vec2 uv = v_texcoord / 2.0;
|
||||
|
||||
vec4 sum = texture2D(tex, uv + vec2(-halfpixel.x * 2.0, 0.0) * radius);
|
||||
|
||||
sum += texture2D(tex, uv + vec2(-halfpixel.x, halfpixel.y) * radius) * 2.0;
|
||||
sum += texture2D(tex, uv + vec2(0.0, halfpixel.y * 2.0) * radius);
|
||||
sum += texture2D(tex, uv + vec2(halfpixel.x, halfpixel.y) * radius) * 2.0;
|
||||
sum += texture2D(tex, uv + vec2(halfpixel.x * 2.0, 0.0) * radius);
|
||||
sum += texture2D(tex, uv + vec2(halfpixel.x, -halfpixel.y) * radius) * 2.0;
|
||||
sum += texture2D(tex, uv + vec2(0.0, -halfpixel.y * 2.0) * radius);
|
||||
sum += texture2D(tex, uv + vec2(-halfpixel.x, -halfpixel.y) * radius) * 2.0;
|
||||
|
||||
gl_FragColor = sum / 12.0;
|
||||
}
|
||||
)#";
|
||||
|
||||
inline const std::string FRAGBLURPREPARE = R"#(
|
||||
precision highp float;
|
||||
varying vec2 v_texcoord; // is in 0-1
|
||||
uniform sampler2D tex;
|
||||
|
||||
uniform float contrast;
|
||||
uniform float brightness;
|
||||
|
||||
float gain(float x, float k) {
|
||||
float a = 0.5 * pow(2.0 * ((x < 0.5) ? x : 1.0 - x), k);
|
||||
return (x < 0.5) ? a : 1.0 - a;
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec4 pixColor = texture2D(tex, v_texcoord);
|
||||
|
||||
// contrast
|
||||
if (contrast != 1.0) {
|
||||
pixColor.r = gain(pixColor.r, contrast);
|
||||
pixColor.g = gain(pixColor.g, contrast);
|
||||
pixColor.b = gain(pixColor.b, contrast);
|
||||
}
|
||||
|
||||
// brightness
|
||||
if (brightness > 1.0) {
|
||||
pixColor.rgb *= brightness;
|
||||
}
|
||||
|
||||
gl_FragColor = pixColor;
|
||||
}
|
||||
)#";
|
||||
|
||||
inline const std::string FRAGBLURFINISH = R"#(
|
||||
precision highp float;
|
||||
varying vec2 v_texcoord; // is in 0-1
|
||||
uniform sampler2D tex;
|
||||
|
||||
uniform float noise;
|
||||
uniform float brightness;
|
||||
|
||||
float hash(vec2 p) {
|
||||
vec3 p3 = fract(vec3(p.xyx) * 1689.1984);
|
||||
p3 += dot(p3, p3.yzx + 33.33);
|
||||
return fract((p3.x + p3.y) * p3.z);
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec4 pixColor = texture2D(tex, v_texcoord);
|
||||
|
||||
// noise
|
||||
float noiseHash = hash(v_texcoord);
|
||||
float noiseAmount = (mod(noiseHash, 1.0) - 0.5);
|
||||
pixColor.rgb += noiseAmount * noise;
|
||||
|
||||
// brightness
|
||||
if (brightness < 1.0) {
|
||||
pixColor.rgb *= brightness;
|
||||
}
|
||||
|
||||
gl_FragColor = pixColor;
|
||||
}
|
||||
)#";
|
||||
|
||||
inline const std::string TEXFRAGSRCEXT = R"#(
|
||||
#extension GL_OES_EGL_image_external : require
|
||||
|
||||
precision highp float;
|
||||
varying vec2 v_texcoord;
|
||||
uniform samplerExternalOES texture0;
|
||||
uniform float alpha;
|
||||
|
||||
uniform vec2 topLeft;
|
||||
uniform vec2 fullSize;
|
||||
uniform float radius;
|
||||
uniform float roundingPower;
|
||||
|
||||
uniform int discardOpaque;
|
||||
uniform int discardAlpha;
|
||||
uniform int discardAlphaValue;
|
||||
|
||||
uniform int applyTint;
|
||||
uniform vec3 tint;
|
||||
|
||||
void main() {
|
||||
|
||||
vec4 pixColor = texture2D(texture0, v_texcoord);
|
||||
|
||||
if (discardOpaque == 1 && pixColor[3] * alpha == 1.0)
|
||||
discard;
|
||||
|
||||
if (applyTint == 1) {
|
||||
pixColor[0] = pixColor[0] * tint[0];
|
||||
pixColor[1] = pixColor[1] * tint[1];
|
||||
pixColor[2] = pixColor[2] * tint[2];
|
||||
}
|
||||
|
||||
if (radius > 0.0) {
|
||||
)#" +
|
||||
ROUNDED_SHADER_FUNC("pixColor") + R"#(
|
||||
}
|
||||
|
||||
gl_FragColor = pixColor * alpha;
|
||||
}
|
||||
)#";
|
||||
|
||||
static const std::string FRAGGLITCH = R"#(
|
||||
precision highp float;
|
||||
varying vec2 v_texcoord;
|
||||
uniform sampler2D tex;
|
||||
uniform float time; // quirk: time is set to 0 at the beginning, should be around 10 when crash.
|
||||
uniform float distort;
|
||||
uniform vec2 screenSize;
|
||||
|
||||
float rand(float co) {
|
||||
return fract(sin(dot(vec2(co, co), vec2(12.9898, 78.233))) * 43758.5453);
|
||||
}
|
||||
|
||||
float rand(vec2 co) {
|
||||
return fract(sin(dot(co, vec2(12.9898, 78.233))) * 43758.5453);
|
||||
}
|
||||
|
||||
float noise(vec2 point) {
|
||||
vec2 floored = floor(point);
|
||||
vec2 fractal = fract(point);
|
||||
fractal = fractal * fractal * (3.0 - 2.0 * fractal);
|
||||
|
||||
float mixed = mix(
|
||||
mix(rand(floored), rand(floored + vec2(1.0, 0.0)), fractal.x),
|
||||
mix(rand(floored + vec2(0.0,1.0)), rand(floored + vec2(1.0,1.0)), fractal.x), fractal.y);
|
||||
return mixed * mixed;
|
||||
}
|
||||
|
||||
void main() {
|
||||
float ABERR_OFFSET = 4.0 * (distort / 5.5) * time;
|
||||
float TEAR_AMOUNT = 9000.0 * (1.0 - (distort / 5.5));
|
||||
float TEAR_BANDS = 108.0 / 2.0 * (distort / 5.5) * 2.0;
|
||||
float MELT_AMOUNT = (distort * 8.0) / screenSize.y;
|
||||
|
||||
float NOISE = abs(mod(noise(v_texcoord) * distort * time * 2.771, 1.0)) * time / 10.0;
|
||||
if (time < 2.0)
|
||||
NOISE = 0.0;
|
||||
|
||||
float offset = (mod(rand(floor(v_texcoord.y * TEAR_BANDS)) * 318.772 * time, 20.0) - 10.0) / TEAR_AMOUNT;
|
||||
|
||||
vec2 blockOffset = vec2(((abs(mod(rand(floor(v_texcoord.x * 37.162)) * 721.43, 100.0))) - 50.0) / 200000.0 * pow(time, 3.0),
|
||||
((abs(mod(rand(floor(v_texcoord.y * 45.882)) * 733.923, 100.0))) - 50.0) / 200000.0 * pow(time, 3.0));
|
||||
if (time < 3.0)
|
||||
blockOffset = vec2(0,0);
|
||||
|
||||
float meltSeed = abs(mod(rand(floor(v_texcoord.x * screenSize.x * 17.719)) * 281.882, 1.0));
|
||||
if (meltSeed < 0.8) {
|
||||
meltSeed = 0.0;
|
||||
} else {
|
||||
meltSeed *= 25.0 * NOISE;
|
||||
}
|
||||
float meltAmount = MELT_AMOUNT * meltSeed;
|
||||
|
||||
vec2 pixCoord = vec2(v_texcoord.x + offset + NOISE * 3.0 / screenSize.x + blockOffset.x, v_texcoord.y - meltAmount + 0.02 * NOISE / screenSize.x + NOISE * 3.0 / screenSize.y + blockOffset.y);
|
||||
|
||||
vec4 pixColor = texture2D(tex, pixCoord);
|
||||
vec4 pixColorLeft = texture2D(tex, pixCoord + vec2(ABERR_OFFSET / screenSize.x, 0));
|
||||
vec4 pixColorRight = texture2D(tex, pixCoord + vec2(-ABERR_OFFSET / screenSize.x, 0));
|
||||
|
||||
pixColor[0] = pixColorLeft[0];
|
||||
pixColor[2] = pixColorRight[2];
|
||||
|
||||
pixColor[0] += distort / 90.0;
|
||||
|
||||
gl_FragColor = pixColor;
|
||||
}
|
||||
)#";
|
55
src/render/shaders/glsl/CM.frag
Normal file
55
src/render/shaders/glsl/CM.frag
Normal file
|
@ -0,0 +1,55 @@
|
|||
#version 300 es
|
||||
//#extension GL_OES_EGL_image_external : require
|
||||
#extension GL_ARB_shading_language_include : enable
|
||||
|
||||
precision highp float;
|
||||
in vec2 v_texcoord;
|
||||
uniform sampler2D tex;
|
||||
//uniform samplerExternalOES texture0;
|
||||
|
||||
uniform int texType; // eTextureType: 0 - rgba, 1 - rgbx, 2 - ext
|
||||
// uniform int skipCM;
|
||||
uniform int sourceTF; // eTransferFunction
|
||||
uniform int targetTF; // eTransferFunction
|
||||
uniform mat4x2 sourcePrimaries;
|
||||
uniform mat4x2 targetPrimaries;
|
||||
|
||||
uniform float alpha;
|
||||
|
||||
uniform int discardOpaque;
|
||||
uniform int discardAlpha;
|
||||
uniform float discardAlphaValue;
|
||||
|
||||
uniform int applyTint;
|
||||
uniform vec3 tint;
|
||||
|
||||
#include "rounding.glsl"
|
||||
#include "CM.glsl"
|
||||
|
||||
layout(location = 0) out vec4 fragColor;
|
||||
void main() {
|
||||
vec4 pixColor;
|
||||
if (texType == 1)
|
||||
pixColor = vec4(texture(tex, v_texcoord).rgb, 1.0);
|
||||
// else if (texType == 2)
|
||||
// pixColor = texture(texture0, v_texcoord);
|
||||
else // assume rgba
|
||||
pixColor = texture(tex, v_texcoord);
|
||||
|
||||
if (discardOpaque == 1 && pixColor[3] * alpha == 1.0)
|
||||
discard;
|
||||
|
||||
if (discardAlpha == 1 && pixColor[3] <= discardAlphaValue)
|
||||
discard;
|
||||
|
||||
// this shader shouldn't be used when skipCM == 1
|
||||
pixColor = doColorManagement(pixColor, sourceTF, sourcePrimaries, targetTF, targetPrimaries);
|
||||
|
||||
if (applyTint == 1)
|
||||
pixColor = vec4(pixColor.rgb * tint.rgb, pixColor[3]);
|
||||
|
||||
if (radius > 0.0)
|
||||
pixColor = rounding(pixColor);
|
||||
|
||||
fragColor = pixColor * alpha;
|
||||
}
|
|
@ -1,37 +1,9 @@
|
|||
R"#(
|
||||
#version 320 es
|
||||
//#extension GL_OES_EGL_image_external : require
|
||||
|
||||
precision highp float;
|
||||
in vec2 v_texcoord;
|
||||
uniform sampler2D tex;
|
||||
//uniform samplerExternalOES texture0;
|
||||
|
||||
uniform int texType; // eTextureType: 0 - rgba, 1 - rgbx, 2 - ext
|
||||
uniform int sourceTF; // eTransferFunction
|
||||
uniform int targetTF; // eTransferFunction
|
||||
uniform mat4x2 sourcePrimaries;
|
||||
uniform mat4x2 targetPrimaries;
|
||||
uniform float maxLuminance;
|
||||
uniform float dstMaxLuminance;
|
||||
uniform float dstRefLuminance;
|
||||
uniform float sdrSaturation;
|
||||
uniform float sdrBrightnessMultiplier;
|
||||
|
||||
uniform float alpha;
|
||||
|
||||
uniform vec2 topLeft;
|
||||
uniform vec2 fullSize;
|
||||
uniform float radius;
|
||||
uniform float roundingPower;
|
||||
|
||||
uniform int discardOpaque;
|
||||
uniform int discardAlpha;
|
||||
uniform float discardAlphaValue;
|
||||
|
||||
uniform int applyTint;
|
||||
uniform vec3 tint;
|
||||
|
||||
//enum eTransferFunction
|
||||
#define CM_TRANSFER_FUNCTION_BT1886 1
|
||||
#define CM_TRANSFER_FUNCTION_GAMMA22 2
|
||||
|
@ -78,31 +50,7 @@ uniform vec3 tint;
|
|||
#define HDR_MAX_LUMINANCE 10000.0
|
||||
#define HLG_MAX_LUMINANCE 1000.0
|
||||
|
||||
// smoothing constant for the edge: more = blurrier, but smoother
|
||||
#define M_PI 3.1415926535897932384626433832795
|
||||
#define M_E 2.718281828459045
|
||||
#define SMOOTHING_CONSTANT (M_PI / 5.34665792551)
|
||||
|
||||
vec4 rounding(vec4 color) {
|
||||
highp vec2 pixCoord = vec2(gl_FragCoord);
|
||||
pixCoord -= topLeft + fullSize * 0.5;
|
||||
pixCoord *= vec2(lessThan(pixCoord, vec2(0.0))) * -2.0 + 1.0;
|
||||
pixCoord -= fullSize * 0.5 - radius;
|
||||
pixCoord += vec2(1.0, 1.0) / fullSize; // center the pix dont make it top-left
|
||||
|
||||
if (pixCoord.x + pixCoord.y > radius) {
|
||||
float dist = pow(pow(pixCoord.x, roundingPower) + pow(pixCoord.y, roundingPower), 1.0/roundingPower);
|
||||
|
||||
if (dist > radius + SMOOTHING_CONSTANT)
|
||||
discard;
|
||||
|
||||
float normalized = 1.0 - smoothstep(0.0, 1.0, (dist - radius + SMOOTHING_CONSTANT) / (SMOOTHING_CONSTANT * 2.0));
|
||||
|
||||
color *= normalized;
|
||||
}
|
||||
|
||||
return color;
|
||||
}
|
||||
|
||||
vec3 xy2xyz(vec2 xy) {
|
||||
if (xy.y == 0.0)
|
||||
|
@ -391,50 +339,26 @@ vec4 tonemap(vec4 color, mat3 dstXYZ) {
|
|||
return vec4(fromLMS * toLinear(vec4(ICtCpPQInv * ICtCp, 1.0), CM_TRANSFER_FUNCTION_ST2084_PQ).rgb * HDR_MAX_LUMINANCE, color[3]);
|
||||
}
|
||||
|
||||
layout(location = 0) out vec4 fragColor;
|
||||
void main() {
|
||||
vec4 pixColor;
|
||||
if (texType == 1)
|
||||
pixColor = vec4(texture(tex, v_texcoord).rgb, 1.0);
|
||||
// else if (texType == 2)
|
||||
// pixColor = texture(texture0, v_texcoord);
|
||||
else // assume rgba
|
||||
pixColor = texture(tex, v_texcoord);
|
||||
|
||||
if (discardOpaque == 1 && pixColor[3] * alpha == 1.0)
|
||||
discard;
|
||||
|
||||
if (discardAlpha == 1 && pixColor[3] <= discardAlphaValue)
|
||||
discard;
|
||||
|
||||
pixColor.rgb /= max(pixColor.a, 0.001);
|
||||
pixColor.rgb = toLinearRGB(pixColor.rgb, sourceTF);
|
||||
mat3 srcxyz = primaries2xyz(sourcePrimaries);
|
||||
mat3 dstxyz;
|
||||
|
||||
if (sourcePrimaries == targetPrimaries)
|
||||
dstxyz = srcxyz;
|
||||
else {
|
||||
dstxyz = primaries2xyz(targetPrimaries);
|
||||
pixColor = convertPrimaries(pixColor, srcxyz, sourcePrimaries[3], dstxyz, targetPrimaries[3]);
|
||||
}
|
||||
|
||||
pixColor = toNit(pixColor, sourceTF);
|
||||
pixColor.rgb *= pixColor.a;
|
||||
pixColor = tonemap(pixColor, dstxyz);
|
||||
|
||||
if (sourceTF == CM_TRANSFER_FUNCTION_SRGB && targetTF == CM_TRANSFER_FUNCTION_ST2084_PQ)
|
||||
pixColor = saturate(pixColor, srcxyz, sdrSaturation);
|
||||
|
||||
pixColor *= sdrBrightnessMultiplier;
|
||||
pixColor = fromLinearNit(pixColor, targetTF);
|
||||
|
||||
if (applyTint == 1)
|
||||
pixColor = vec4(pixColor.rgb * tint.rgb, pixColor[3]);
|
||||
|
||||
if (radius > 0.0)
|
||||
pixColor = rounding(pixColor);
|
||||
|
||||
fragColor = pixColor * alpha;
|
||||
vec4 doColorManagement(vec4 pixColor, int srcTF, mat4x2 srcPrimaries, int dstTF, mat4x2 dstPrimaries) {
|
||||
pixColor.rgb /= max(pixColor.a, 0.001);
|
||||
pixColor.rgb = toLinearRGB(pixColor.rgb, srcTF);
|
||||
mat3 srcxyz = primaries2xyz(srcPrimaries);
|
||||
mat3 dstxyz;
|
||||
if (srcPrimaries == dstPrimaries)
|
||||
dstxyz = srcxyz;
|
||||
else {
|
||||
dstxyz = primaries2xyz(dstPrimaries);
|
||||
pixColor = convertPrimaries(pixColor, srcxyz, srcPrimaries[3], dstxyz, dstPrimaries[3]);
|
||||
}
|
||||
pixColor = toNit(pixColor, srcTF);
|
||||
pixColor.rgb *= pixColor.a;
|
||||
pixColor = tonemap(pixColor, dstxyz);
|
||||
pixColor = fromLinearNit(pixColor, dstTF);
|
||||
if (srcTF == CM_TRANSFER_FUNCTION_SRGB && dstTF == CM_TRANSFER_FUNCTION_ST2084_PQ) {
|
||||
pixColor = saturate(pixColor, srcxyz, sdrSaturation);
|
||||
pixColor.rgb /= pixColor.a;
|
||||
pixColor.rgb *= sdrBrightnessMultiplier;
|
||||
pixColor.rgb *= pixColor.a;
|
||||
}
|
||||
return pixColor;
|
||||
}
|
||||
)#"
|
141
src/render/shaders/glsl/blur1.frag
Normal file
141
src/render/shaders/glsl/blur1.frag
Normal file
|
@ -0,0 +1,141 @@
|
|||
#version 100
|
||||
precision highp float;
|
||||
varying highp vec2 v_texcoord; // is in 0-1
|
||||
uniform sampler2D tex;
|
||||
|
||||
uniform float radius;
|
||||
uniform vec2 halfpixel;
|
||||
uniform int passes;
|
||||
uniform float vibrancy;
|
||||
uniform float vibrancy_darkness;
|
||||
|
||||
// see http://alienryderflex.com/hsp.html
|
||||
const float Pr = 0.299;
|
||||
const float Pg = 0.587;
|
||||
const float Pb = 0.114;
|
||||
|
||||
// Y is "v" ( brightness ). X is "s" ( saturation )
|
||||
// see https://www.desmos.com/3d/a88652b9a4
|
||||
// Determines if high brightness or high saturation is more important
|
||||
const float a = 0.93;
|
||||
const float b = 0.11;
|
||||
const float c = 0.66; // Determines the smoothness of the transition of unboosted to boosted colors
|
||||
//
|
||||
|
||||
// http://www.flong.com/archive/texts/code/shapers_circ/
|
||||
float doubleCircleSigmoid(float x, float a) {
|
||||
a = clamp(a, 0.0, 1.0);
|
||||
|
||||
float y = .0;
|
||||
if (x <= a) {
|
||||
y = a - sqrt(a * a - x * x);
|
||||
} else {
|
||||
y = a + sqrt(pow(1. - a, 2.) - pow(x - 1., 2.));
|
||||
}
|
||||
return y;
|
||||
}
|
||||
|
||||
vec3 rgb2hsl(vec3 col) {
|
||||
float red = col.r;
|
||||
float green = col.g;
|
||||
float blue = col.b;
|
||||
|
||||
float minc = min(col.r, min(col.g, col.b));
|
||||
float maxc = max(col.r, max(col.g, col.b));
|
||||
float delta = maxc - minc;
|
||||
|
||||
float lum = (minc + maxc) * 0.5;
|
||||
float sat = 0.0;
|
||||
float hue = 0.0;
|
||||
|
||||
if (lum > 0.0 && lum < 1.0) {
|
||||
float mul = (lum < 0.5) ? (lum) : (1.0 - lum);
|
||||
sat = delta / (mul * 2.0);
|
||||
}
|
||||
|
||||
if (delta > 0.0) {
|
||||
vec3 maxcVec = vec3(maxc);
|
||||
vec3 masks = vec3(equal(maxcVec, col)) * vec3(notEqual(maxcVec, vec3(green, blue, red)));
|
||||
vec3 adds = vec3(0.0, 2.0, 4.0) + vec3(green - blue, blue - red, red - green) / delta;
|
||||
|
||||
hue += dot(adds, masks);
|
||||
hue /= 6.0;
|
||||
|
||||
if (hue < 0.0)
|
||||
hue += 1.0;
|
||||
}
|
||||
|
||||
return vec3(hue, sat, lum);
|
||||
}
|
||||
|
||||
vec3 hsl2rgb(vec3 col) {
|
||||
const float onethird = 1.0 / 3.0;
|
||||
const float twothird = 2.0 / 3.0;
|
||||
const float rcpsixth = 6.0;
|
||||
|
||||
float hue = col.x;
|
||||
float sat = col.y;
|
||||
float lum = col.z;
|
||||
|
||||
vec3 xt = vec3(0.0);
|
||||
|
||||
if (hue < onethird) {
|
||||
xt.r = rcpsixth * (onethird - hue);
|
||||
xt.g = rcpsixth * hue;
|
||||
xt.b = 0.0;
|
||||
} else if (hue < twothird) {
|
||||
xt.r = 0.0;
|
||||
xt.g = rcpsixth * (twothird - hue);
|
||||
xt.b = rcpsixth * (hue - onethird);
|
||||
} else
|
||||
xt = vec3(rcpsixth * (hue - twothird), 0.0, rcpsixth * (1.0 - hue));
|
||||
|
||||
xt = min(xt, 1.0);
|
||||
|
||||
float sat2 = 2.0 * sat;
|
||||
float satinv = 1.0 - sat;
|
||||
float luminv = 1.0 - lum;
|
||||
float lum2m1 = (2.0 * lum) - 1.0;
|
||||
vec3 ct = (sat2 * xt) + satinv;
|
||||
|
||||
vec3 rgb;
|
||||
if (lum >= 0.5)
|
||||
rgb = (luminv * ct) + lum2m1;
|
||||
else
|
||||
rgb = lum * ct;
|
||||
|
||||
return rgb;
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec2 uv = v_texcoord * 2.0;
|
||||
|
||||
vec4 sum = texture2D(tex, uv) * 4.0;
|
||||
sum += texture2D(tex, uv - halfpixel.xy * radius);
|
||||
sum += texture2D(tex, uv + halfpixel.xy * radius);
|
||||
sum += texture2D(tex, uv + vec2(halfpixel.x, -halfpixel.y) * radius);
|
||||
sum += texture2D(tex, uv - vec2(halfpixel.x, -halfpixel.y) * radius);
|
||||
|
||||
vec4 color = sum / 8.0;
|
||||
|
||||
if (vibrancy == 0.0) {
|
||||
gl_FragColor = color;
|
||||
} else {
|
||||
// Invert it so that it correctly maps to the config setting
|
||||
float vibrancy_darkness1 = 1.0 - vibrancy_darkness;
|
||||
|
||||
// Decrease the RGB components based on their perceived brightness, to prevent visually dark colors from overblowing the rest.
|
||||
vec3 hsl = rgb2hsl(color.rgb);
|
||||
// Calculate perceived brightness, as not boost visually dark colors like deep blue as much as equally saturated yellow
|
||||
float perceivedBrightness = doubleCircleSigmoid(sqrt(color.r * color.r * Pr + color.g * color.g * Pg + color.b * color.b * Pb), 0.8 * vibrancy_darkness1);
|
||||
|
||||
float b1 = b * vibrancy_darkness1;
|
||||
float boostBase = hsl[1] > 0.0 ? smoothstep(b1 - c * 0.5, b1 + c * 0.5, 1.0 - (pow(1.0 - hsl[1] * cos(a), 2.0) + pow(1.0 - perceivedBrightness * sin(a), 2.0))) : 0.0;
|
||||
|
||||
float saturation = clamp(hsl[1] + (boostBase * vibrancy) / float(passes), 0.0, 1.0);
|
||||
|
||||
vec3 newColor = hsl2rgb(vec3(hsl[0], saturation, hsl[2]));
|
||||
|
||||
gl_FragColor = vec4(newColor, color[3]);
|
||||
}
|
||||
}
|
23
src/render/shaders/glsl/blur2.frag
Normal file
23
src/render/shaders/glsl/blur2.frag
Normal file
|
@ -0,0 +1,23 @@
|
|||
#version 100
|
||||
precision highp float;
|
||||
varying highp vec2 v_texcoord; // is in 0-1
|
||||
uniform sampler2D tex;
|
||||
|
||||
uniform float radius;
|
||||
uniform vec2 halfpixel;
|
||||
|
||||
void main() {
|
||||
vec2 uv = v_texcoord / 2.0;
|
||||
|
||||
vec4 sum = texture2D(tex, uv + vec2(-halfpixel.x * 2.0, 0.0) * radius);
|
||||
|
||||
sum += texture2D(tex, uv + vec2(-halfpixel.x, halfpixel.y) * radius) * 2.0;
|
||||
sum += texture2D(tex, uv + vec2(0.0, halfpixel.y * 2.0) * radius);
|
||||
sum += texture2D(tex, uv + vec2(halfpixel.x, halfpixel.y) * radius) * 2.0;
|
||||
sum += texture2D(tex, uv + vec2(halfpixel.x * 2.0, 0.0) * radius);
|
||||
sum += texture2D(tex, uv + vec2(halfpixel.x, -halfpixel.y) * radius) * 2.0;
|
||||
sum += texture2D(tex, uv + vec2(0.0, -halfpixel.y * 2.0) * radius);
|
||||
sum += texture2D(tex, uv + vec2(-halfpixel.x, -halfpixel.y) * radius) * 2.0;
|
||||
|
||||
gl_FragColor = sum / 12.0;
|
||||
}
|
32
src/render/shaders/glsl/blurfinish.frag
Normal file
32
src/render/shaders/glsl/blurfinish.frag
Normal file
|
@ -0,0 +1,32 @@
|
|||
#version 300 es
|
||||
#extension GL_ARB_shading_language_include : enable
|
||||
|
||||
precision highp float;
|
||||
in vec2 v_texcoord; // is in 0-1
|
||||
uniform sampler2D tex;
|
||||
|
||||
uniform float noise;
|
||||
uniform float brightness;
|
||||
|
||||
float hash(vec2 p) {
|
||||
vec3 p3 = fract(vec3(p.xyx) * 1689.1984);
|
||||
p3 += dot(p3, p3.yzx + 33.33);
|
||||
return fract((p3.x + p3.y) * p3.z);
|
||||
}
|
||||
|
||||
layout(location = 0) out vec4 fragColor;
|
||||
void main() {
|
||||
vec4 pixColor = texture(tex, v_texcoord);
|
||||
|
||||
// noise
|
||||
float noiseHash = hash(v_texcoord);
|
||||
float noiseAmount = (mod(noiseHash, 1.0) - 0.5);
|
||||
pixColor.rgb += noiseAmount * noise;
|
||||
|
||||
// brightness
|
||||
if (brightness < 1.0) {
|
||||
pixColor.rgb *= brightness;
|
||||
}
|
||||
|
||||
fragColor = pixColor;
|
||||
}
|
28
src/render/shaders/glsl/blurfinish_legacy.frag
Normal file
28
src/render/shaders/glsl/blurfinish_legacy.frag
Normal file
|
@ -0,0 +1,28 @@
|
|||
precision highp float;
|
||||
varying vec2 v_texcoord; // is in 0-1
|
||||
uniform sampler2D tex;
|
||||
|
||||
uniform float noise;
|
||||
uniform float brightness;
|
||||
|
||||
float hash(vec2 p) {
|
||||
vec3 p3 = fract(vec3(p.xyx) * 1689.1984);
|
||||
p3 += dot(p3, p3.yzx + 33.33);
|
||||
return fract((p3.x + p3.y) * p3.z);
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec4 pixColor = texture2D(tex, v_texcoord);
|
||||
|
||||
// noise
|
||||
float noiseHash = hash(v_texcoord);
|
||||
float noiseAmount = (mod(noiseHash, 1.0) - 0.5);
|
||||
pixColor.rgb += noiseAmount * noise;
|
||||
|
||||
// brightness
|
||||
if (brightness < 1.0) {
|
||||
pixColor.rgb *= brightness;
|
||||
}
|
||||
|
||||
gl_FragColor = pixColor;
|
||||
}
|
58
src/render/shaders/glsl/blurprepare.frag
Normal file
58
src/render/shaders/glsl/blurprepare.frag
Normal file
|
@ -0,0 +1,58 @@
|
|||
#version 300 es
|
||||
#extension GL_ARB_shading_language_include : enable
|
||||
|
||||
precision highp float;
|
||||
in vec2 v_texcoord; // is in 0-1
|
||||
uniform sampler2D tex;
|
||||
|
||||
uniform float contrast;
|
||||
uniform float brightness;
|
||||
|
||||
uniform int skipCM;
|
||||
uniform int sourceTF; // eTransferFunction
|
||||
uniform int targetTF; // eTransferFunction
|
||||
uniform mat4x2 sourcePrimaries;
|
||||
uniform mat4x2 targetPrimaries;
|
||||
|
||||
#include "CM.glsl"
|
||||
|
||||
float gain(float x, float k) {
|
||||
float a = 0.5 * pow(2.0 * ((x < 0.5) ? x : 1.0 - x), k);
|
||||
return (x < 0.5) ? a : 1.0 - a;
|
||||
}
|
||||
|
||||
layout(location = 0) out vec4 fragColor;
|
||||
void main() {
|
||||
vec4 pixColor = texture(tex, v_texcoord);
|
||||
|
||||
if (skipCM == 0) {
|
||||
if (sourceTF == CM_TRANSFER_FUNCTION_ST2084_PQ) {
|
||||
pixColor.rgb /= sdrBrightnessMultiplier;
|
||||
}
|
||||
pixColor.rgb = toLinearRGB(pixColor.rgb, sourceTF);
|
||||
mat3 srcxyz = primaries2xyz(sourcePrimaries);
|
||||
mat3 dstxyz;
|
||||
if (sourcePrimaries == targetPrimaries)
|
||||
dstxyz = srcxyz;
|
||||
else {
|
||||
dstxyz = primaries2xyz(targetPrimaries);
|
||||
pixColor = convertPrimaries(pixColor, srcxyz, sourcePrimaries[3], dstxyz, targetPrimaries[3]);
|
||||
}
|
||||
pixColor = toNit(pixColor, sourceTF);
|
||||
pixColor = fromLinearNit(pixColor, targetTF);
|
||||
}
|
||||
|
||||
// contrast
|
||||
if (contrast != 1.0) {
|
||||
pixColor.r = gain(pixColor.r, contrast);
|
||||
pixColor.g = gain(pixColor.g, contrast);
|
||||
pixColor.b = gain(pixColor.b, contrast);
|
||||
}
|
||||
|
||||
// brightness
|
||||
if (brightness > 1.0) {
|
||||
pixColor.rgb *= brightness;
|
||||
}
|
||||
|
||||
fragColor = pixColor;
|
||||
}
|
29
src/render/shaders/glsl/blurprepare_legacy.frag
Normal file
29
src/render/shaders/glsl/blurprepare_legacy.frag
Normal file
|
@ -0,0 +1,29 @@
|
|||
precision highp float;
|
||||
varying vec2 v_texcoord; // is in 0-1
|
||||
uniform sampler2D tex;
|
||||
|
||||
uniform float contrast;
|
||||
uniform float brightness;
|
||||
|
||||
float gain(float x, float k) {
|
||||
float a = 0.5 * pow(2.0 * ((x < 0.5) ? x : 1.0 - x), k);
|
||||
return (x < 0.5) ? a : 1.0 - a;
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec4 pixColor = texture2D(tex, v_texcoord);
|
||||
|
||||
// contrast
|
||||
if (contrast != 1.0) {
|
||||
pixColor.r = gain(pixColor.r, contrast);
|
||||
pixColor.g = gain(pixColor.g, contrast);
|
||||
pixColor.b = gain(pixColor.b, contrast);
|
||||
}
|
||||
|
||||
// brightness
|
||||
if (brightness > 1.0) {
|
||||
pixColor.rgb *= brightness;
|
||||
}
|
||||
|
||||
gl_FragColor = pixColor;
|
||||
}
|
183
src/render/shaders/glsl/border.frag
Normal file
183
src/render/shaders/glsl/border.frag
Normal file
|
@ -0,0 +1,183 @@
|
|||
#version 300 es
|
||||
#extension GL_ARB_shading_language_include : enable
|
||||
|
||||
precision highp float;
|
||||
in vec2 v_texcoord;
|
||||
|
||||
uniform int skipCM;
|
||||
uniform int sourceTF; // eTransferFunction
|
||||
uniform int targetTF; // eTransferFunction
|
||||
uniform mat4x2 sourcePrimaries;
|
||||
uniform mat4x2 targetPrimaries;
|
||||
|
||||
uniform vec2 fullSizeUntransformed;
|
||||
uniform float radiusOuter;
|
||||
uniform float thick;
|
||||
|
||||
// Gradients are in OkLabA!!!! {l, a, b, alpha}
|
||||
uniform vec4 gradient[10];
|
||||
uniform vec4 gradient2[10];
|
||||
uniform int gradientLength;
|
||||
uniform int gradient2Length;
|
||||
uniform float angle;
|
||||
uniform float angle2;
|
||||
uniform float gradientLerp;
|
||||
uniform float alpha;
|
||||
|
||||
#include "rounding.glsl"
|
||||
#include "CM.glsl"
|
||||
|
||||
vec4 okLabAToSrgb(vec4 lab) {
|
||||
float l = pow(lab[0] + lab[1] * 0.3963377774 + lab[2] * 0.2158037573, 3.0);
|
||||
float m = pow(lab[0] + lab[1] * (-0.1055613458) + lab[2] * (-0.0638541728), 3.0);
|
||||
float s = pow(lab[0] + lab[1] * (-0.0894841775) + lab[2] * (-1.2914855480), 3.0);
|
||||
|
||||
return vec4(fromLinearRGB(
|
||||
vec3(
|
||||
l * 4.0767416621 + m * -3.3077115913 + s * 0.2309699292,
|
||||
l * (-1.2684380046) + m * 2.6097574011 + s * (-0.3413193965),
|
||||
l * (-0.0041960863) + m * (-0.7034186147) + s * 1.7076147010
|
||||
), CM_TRANSFER_FUNCTION_SRGB
|
||||
), lab[3]);
|
||||
}
|
||||
|
||||
vec4 getOkColorForCoordArray1(vec2 normalizedCoord) {
|
||||
if (gradientLength < 2)
|
||||
return gradient[0];
|
||||
|
||||
float finalAng = 0.0;
|
||||
|
||||
if (angle > 4.71 /* 270 deg */) {
|
||||
normalizedCoord[1] = 1.0 - normalizedCoord[1];
|
||||
finalAng = 6.28 - angle;
|
||||
} else if (angle > 3.14 /* 180 deg */) {
|
||||
normalizedCoord[0] = 1.0 - normalizedCoord[0];
|
||||
normalizedCoord[1] = 1.0 - normalizedCoord[1];
|
||||
finalAng = angle - 3.14;
|
||||
} else if (angle > 1.57 /* 90 deg */) {
|
||||
normalizedCoord[0] = 1.0 - normalizedCoord[0];
|
||||
finalAng = 3.14 - angle;
|
||||
} else {
|
||||
finalAng = angle;
|
||||
}
|
||||
|
||||
float sine = sin(finalAng);
|
||||
|
||||
float progress = (normalizedCoord[1] * sine + normalizedCoord[0] * (1.0 - sine)) * float(gradientLength - 1);
|
||||
int bottom = int(floor(progress));
|
||||
int top = bottom + 1;
|
||||
|
||||
return gradient[top] * (progress - float(bottom)) + gradient[bottom] * (float(top) - progress);
|
||||
}
|
||||
|
||||
vec4 getOkColorForCoordArray2(vec2 normalizedCoord) {
|
||||
if (gradient2Length < 2)
|
||||
return gradient2[0];
|
||||
|
||||
float finalAng = 0.0;
|
||||
|
||||
if (angle2 > 4.71 /* 270 deg */) {
|
||||
normalizedCoord[1] = 1.0 - normalizedCoord[1];
|
||||
finalAng = 6.28 - angle;
|
||||
} else if (angle2 > 3.14 /* 180 deg */) {
|
||||
normalizedCoord[0] = 1.0 - normalizedCoord[0];
|
||||
normalizedCoord[1] = 1.0 - normalizedCoord[1];
|
||||
finalAng = angle - 3.14;
|
||||
} else if (angle2 > 1.57 /* 90 deg */) {
|
||||
normalizedCoord[0] = 1.0 - normalizedCoord[0];
|
||||
finalAng = 3.14 - angle2;
|
||||
} else {
|
||||
finalAng = angle2;
|
||||
}
|
||||
|
||||
float sine = sin(finalAng);
|
||||
|
||||
float progress = (normalizedCoord[1] * sine + normalizedCoord[0] * (1.0 - sine)) * float(gradient2Length - 1);
|
||||
int bottom = int(floor(progress));
|
||||
int top = bottom + 1;
|
||||
|
||||
return gradient2[top] * (progress - float(bottom)) + gradient2[bottom] * (float(top) - progress);
|
||||
}
|
||||
|
||||
vec4 getColorForCoord(vec2 normalizedCoord) {
|
||||
vec4 result1 = getOkColorForCoordArray1(normalizedCoord);
|
||||
|
||||
if (gradient2Length <= 0)
|
||||
return okLabAToSrgb(result1);
|
||||
|
||||
vec4 result2 = getOkColorForCoordArray2(normalizedCoord);
|
||||
|
||||
return okLabAToSrgb(mix(result1, result2, gradientLerp));
|
||||
}
|
||||
|
||||
layout(location = 0) out vec4 fragColor;
|
||||
void main() {
|
||||
highp vec2 pixCoord = vec2(gl_FragCoord);
|
||||
highp vec2 pixCoordOuter = pixCoord;
|
||||
highp vec2 originalPixCoord = v_texcoord;
|
||||
originalPixCoord *= fullSizeUntransformed;
|
||||
float additionalAlpha = 1.0;
|
||||
|
||||
vec4 pixColor = vec4(1.0, 1.0, 1.0, 1.0);
|
||||
|
||||
bool done = false;
|
||||
|
||||
pixCoord -= topLeft + fullSize * 0.5;
|
||||
pixCoord *= vec2(lessThan(pixCoord, vec2(0.0))) * -2.0 + 1.0;
|
||||
pixCoordOuter = pixCoord;
|
||||
pixCoord -= fullSize * 0.5 - radius;
|
||||
pixCoordOuter -= fullSize * 0.5 - radiusOuter;
|
||||
|
||||
// center the pixes dont make it top-left
|
||||
pixCoord += vec2(1.0, 1.0) / fullSize;
|
||||
pixCoordOuter += vec2(1.0, 1.0) / fullSize;
|
||||
|
||||
if (min(pixCoord.x, pixCoord.y) > 0.0 && radius > 0.0) {
|
||||
float dist = pow(pow(pixCoord.x,roundingPower)+pow(pixCoord.y,roundingPower),1.0/roundingPower);
|
||||
float distOuter = pow(pow(pixCoordOuter.x,roundingPower)+pow(pixCoordOuter.y,roundingPower),1.0/roundingPower);
|
||||
float h = (thick / 2.0);
|
||||
|
||||
if (dist < radius - h) {
|
||||
// lower
|
||||
float normalized = smoothstep(0.0, 1.0, (dist - radius + thick + SMOOTHING_CONSTANT) / (SMOOTHING_CONSTANT * 2.0));
|
||||
additionalAlpha *= normalized;
|
||||
done = true;
|
||||
} else if (min(pixCoordOuter.x, pixCoordOuter.y) > 0.0) {
|
||||
// higher
|
||||
float normalized = 1.0 - smoothstep(0.0, 1.0, (distOuter - radiusOuter + SMOOTHING_CONSTANT) / (SMOOTHING_CONSTANT * 2.0));
|
||||
additionalAlpha *= normalized;
|
||||
done = true;
|
||||
} else if (distOuter < radiusOuter - h) {
|
||||
additionalAlpha = 1.0;
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
|
||||
// now check for other shit
|
||||
if (!done) {
|
||||
// distance to all straight bb borders
|
||||
float distanceT = originalPixCoord[1];
|
||||
float distanceB = fullSizeUntransformed[1] - originalPixCoord[1];
|
||||
float distanceL = originalPixCoord[0];
|
||||
float distanceR = fullSizeUntransformed[0] - originalPixCoord[0];
|
||||
|
||||
// get the smallest
|
||||
float smallest = min(min(distanceT, distanceB), min(distanceL, distanceR));
|
||||
|
||||
if (smallest > thick)
|
||||
discard;
|
||||
}
|
||||
|
||||
if (additionalAlpha == 0.0)
|
||||
discard;
|
||||
|
||||
pixColor = getColorForCoord(v_texcoord);
|
||||
pixColor.rgb *= pixColor[3];
|
||||
|
||||
if (skipCM == 0)
|
||||
pixColor = doColorManagement(pixColor, sourceTF, sourcePrimaries, targetTF, targetPrimaries);
|
||||
|
||||
pixColor *= alpha * additionalAlpha;
|
||||
|
||||
fragColor = pixColor;
|
||||
}
|
|
@ -1,21 +1,11 @@
|
|||
#pragma once
|
||||
#extension GL_ARB_shading_language_include : enable
|
||||
|
||||
#include <string>
|
||||
#include <format>
|
||||
#include "SharedValues.hpp"
|
||||
|
||||
// makes a stencil without corners
|
||||
inline const std::string FRAGBORDER1 = R"#(
|
||||
precision highp float;
|
||||
varying vec4 v_color;
|
||||
varying vec2 v_texcoord;
|
||||
|
||||
uniform vec2 topLeft;
|
||||
uniform vec2 fullSize;
|
||||
uniform vec2 fullSizeUntransformed;
|
||||
uniform float radius;
|
||||
uniform float radiusOuter;
|
||||
uniform float roundingPower;
|
||||
uniform float thick;
|
||||
|
||||
// Gradients are in OkLabA!!!! {l, a, b, alpha}
|
||||
|
@ -28,6 +18,8 @@ uniform float angle2;
|
|||
uniform float gradientLerp;
|
||||
uniform float alpha;
|
||||
|
||||
#include "rounding.glsl"
|
||||
|
||||
float linearToGamma(float x) {
|
||||
return x >= 0.0031308 ? 1.055 * pow(x, 0.416666666) - 0.055 : 12.92 * x;
|
||||
}
|
||||
|
@ -135,13 +127,9 @@ void main() {
|
|||
pixCoordOuter += vec2(1.0, 1.0) / fullSize;
|
||||
|
||||
if (min(pixCoord.x, pixCoord.y) > 0.0 && radius > 0.0) {
|
||||
// smoothing constant for the edge: more = blurrier, but smoother
|
||||
const float SMOOTHING_CONSTANT = )#" +
|
||||
std::format("{:.7f}", SHADER_ROUNDED_SMOOTHING_FACTOR) + R"#(;
|
||||
|
||||
float dist = pow(pow(pixCoord.x,roundingPower)+pow(pixCoord.y,roundingPower),1.0/roundingPower);
|
||||
float distOuter = pow(pow(pixCoordOuter.x,roundingPower)+pow(pixCoordOuter.y,roundingPower),1.0/roundingPower);
|
||||
float h = (thick / 2.0);
|
||||
float h = (thick / 2.0);
|
||||
|
||||
if (dist < radius - h) {
|
||||
// lower
|
||||
|
@ -184,4 +172,3 @@ void main() {
|
|||
|
||||
gl_FragColor = pixColor;
|
||||
}
|
||||
)#";
|
35
src/render/shaders/glsl/ext.frag
Normal file
35
src/render/shaders/glsl/ext.frag
Normal file
|
@ -0,0 +1,35 @@
|
|||
#extension GL_ARB_shading_language_include : enable
|
||||
#extension GL_OES_EGL_image_external : require
|
||||
|
||||
precision highp float;
|
||||
varying vec2 v_texcoord;
|
||||
uniform samplerExternalOES texture0;
|
||||
uniform float alpha;
|
||||
|
||||
#include "rounding.glsl"
|
||||
|
||||
uniform int discardOpaque;
|
||||
uniform int discardAlpha;
|
||||
uniform int discardAlphaValue;
|
||||
|
||||
uniform int applyTint;
|
||||
uniform vec3 tint;
|
||||
|
||||
void main() {
|
||||
|
||||
vec4 pixColor = texture2D(texture0, v_texcoord);
|
||||
|
||||
if (discardOpaque == 1 && pixColor[3] * alpha == 1.0)
|
||||
discard;
|
||||
|
||||
if (applyTint == 1) {
|
||||
pixColor[0] = pixColor[0] * tint[0];
|
||||
pixColor[1] = pixColor[1] * tint[1];
|
||||
pixColor[2] = pixColor[2] * tint[2];
|
||||
}
|
||||
|
||||
if (radius > 0.0)
|
||||
pixColor = rounding(pixColor);
|
||||
|
||||
gl_FragColor = pixColor * alpha;
|
||||
}
|
64
src/render/shaders/glsl/glitch.frag
Normal file
64
src/render/shaders/glsl/glitch.frag
Normal file
|
@ -0,0 +1,64 @@
|
|||
precision highp float;
|
||||
varying vec2 v_texcoord;
|
||||
uniform sampler2D tex;
|
||||
uniform float time; // quirk: time is set to 0 at the beginning, should be around 10 when crash.
|
||||
uniform float distort;
|
||||
uniform vec2 screenSize;
|
||||
|
||||
float rand(float co) {
|
||||
return fract(sin(dot(vec2(co, co), vec2(12.9898, 78.233))) * 43758.5453);
|
||||
}
|
||||
|
||||
float rand(vec2 co) {
|
||||
return fract(sin(dot(co, vec2(12.9898, 78.233))) * 43758.5453);
|
||||
}
|
||||
|
||||
float noise(vec2 point) {
|
||||
vec2 floored = floor(point);
|
||||
vec2 fractal = fract(point);
|
||||
fractal = fractal * fractal * (3.0 - 2.0 * fractal);
|
||||
|
||||
float mixed = mix(
|
||||
mix(rand(floored), rand(floored + vec2(1.0, 0.0)), fractal.x),
|
||||
mix(rand(floored + vec2(0.0,1.0)), rand(floored + vec2(1.0,1.0)), fractal.x), fractal.y);
|
||||
return mixed * mixed;
|
||||
}
|
||||
|
||||
void main() {
|
||||
float ABERR_OFFSET = 4.0 * (distort / 5.5) * time;
|
||||
float TEAR_AMOUNT = 9000.0 * (1.0 - (distort / 5.5));
|
||||
float TEAR_BANDS = 108.0 / 2.0 * (distort / 5.5) * 2.0;
|
||||
float MELT_AMOUNT = (distort * 8.0) / screenSize.y;
|
||||
|
||||
float NOISE = abs(mod(noise(v_texcoord) * distort * time * 2.771, 1.0)) * time / 10.0;
|
||||
if (time < 2.0)
|
||||
NOISE = 0.0;
|
||||
|
||||
float offset = (mod(rand(floor(v_texcoord.y * TEAR_BANDS)) * 318.772 * time, 20.0) - 10.0) / TEAR_AMOUNT;
|
||||
|
||||
vec2 blockOffset = vec2(((abs(mod(rand(floor(v_texcoord.x * 37.162)) * 721.43, 100.0))) - 50.0) / 200000.0 * pow(time, 3.0),
|
||||
((abs(mod(rand(floor(v_texcoord.y * 45.882)) * 733.923, 100.0))) - 50.0) / 200000.0 * pow(time, 3.0));
|
||||
if (time < 3.0)
|
||||
blockOffset = vec2(0,0);
|
||||
|
||||
float meltSeed = abs(mod(rand(floor(v_texcoord.x * screenSize.x * 17.719)) * 281.882, 1.0));
|
||||
if (meltSeed < 0.8) {
|
||||
meltSeed = 0.0;
|
||||
} else {
|
||||
meltSeed *= 25.0 * NOISE;
|
||||
}
|
||||
float meltAmount = MELT_AMOUNT * meltSeed;
|
||||
|
||||
vec2 pixCoord = vec2(v_texcoord.x + offset + NOISE * 3.0 / screenSize.x + blockOffset.x, v_texcoord.y - meltAmount + 0.02 * NOISE / screenSize.x + NOISE * 3.0 / screenSize.y + blockOffset.y);
|
||||
|
||||
vec4 pixColor = texture2D(tex, pixCoord);
|
||||
vec4 pixColorLeft = texture2D(tex, pixCoord + vec2(ABERR_OFFSET / screenSize.x, 0));
|
||||
vec4 pixColorRight = texture2D(tex, pixCoord + vec2(-ABERR_OFFSET / screenSize.x, 0));
|
||||
|
||||
pixColor[0] = pixColorLeft[0];
|
||||
pixColor[2] = pixColorRight[2];
|
||||
|
||||
pixColor[0] += distort / 90.0;
|
||||
|
||||
gl_FragColor = pixColor;
|
||||
}
|
7
src/render/shaders/glsl/passthru.frag
Normal file
7
src/render/shaders/glsl/passthru.frag
Normal file
|
@ -0,0 +1,7 @@
|
|||
precision highp float;
|
||||
varying vec2 v_texcoord; // is in 0-1
|
||||
uniform sampler2D tex;
|
||||
|
||||
void main() {
|
||||
gl_FragColor = texture2D(tex, v_texcoord);
|
||||
}
|
14
src/render/shaders/glsl/quad.frag
Normal file
14
src/render/shaders/glsl/quad.frag
Normal file
|
@ -0,0 +1,14 @@
|
|||
#extension GL_ARB_shading_language_include : enable
|
||||
precision highp float;
|
||||
varying vec4 v_color;
|
||||
|
||||
#include "rounding.glsl"
|
||||
|
||||
void main() {
|
||||
vec4 pixColor = v_color;
|
||||
|
||||
if (radius > 0.0)
|
||||
pixColor = rounding(pixColor);
|
||||
|
||||
gl_FragColor = pixColor;
|
||||
}
|
36
src/render/shaders/glsl/rgba.frag
Normal file
36
src/render/shaders/glsl/rgba.frag
Normal file
|
@ -0,0 +1,36 @@
|
|||
#extension GL_ARB_shading_language_include : enable
|
||||
precision highp float;
|
||||
varying vec2 v_texcoord; // is in 0-1
|
||||
uniform sampler2D tex;
|
||||
uniform float alpha;
|
||||
|
||||
#include "rounding.glsl"
|
||||
|
||||
uniform int discardOpaque;
|
||||
uniform int discardAlpha;
|
||||
uniform float discardAlphaValue;
|
||||
|
||||
uniform int applyTint;
|
||||
uniform vec3 tint;
|
||||
|
||||
void main() {
|
||||
|
||||
vec4 pixColor = texture2D(tex, v_texcoord);
|
||||
|
||||
if (discardOpaque == 1 && pixColor[3] * alpha == 1.0)
|
||||
discard;
|
||||
|
||||
if (discardAlpha == 1 && pixColor[3] <= discardAlphaValue)
|
||||
discard;
|
||||
|
||||
if (applyTint == 1) {
|
||||
pixColor[0] = pixColor[0] * tint[0];
|
||||
pixColor[1] = pixColor[1] * tint[1];
|
||||
pixColor[2] = pixColor[2] * tint[2];
|
||||
}
|
||||
|
||||
if (radius > 0.0)
|
||||
pixColor = rounding(pixColor);
|
||||
|
||||
gl_FragColor = pixColor * alpha;
|
||||
}
|
8
src/render/shaders/glsl/rgbamatte.frag
Normal file
8
src/render/shaders/glsl/rgbamatte.frag
Normal file
|
@ -0,0 +1,8 @@
|
|||
precision highp float;
|
||||
varying vec2 v_texcoord; // is in 0-1
|
||||
uniform sampler2D tex;
|
||||
uniform sampler2D texMatte;
|
||||
|
||||
void main() {
|
||||
gl_FragColor = texture2D(tex, v_texcoord) * texture2D(texMatte, v_texcoord)[0]; // I know it only uses R, but matte should be black/white anyways.
|
||||
}
|
33
src/render/shaders/glsl/rgbx.frag
Normal file
33
src/render/shaders/glsl/rgbx.frag
Normal file
|
@ -0,0 +1,33 @@
|
|||
#extension GL_ARB_shading_language_include : enable
|
||||
precision highp float;
|
||||
varying vec2 v_texcoord;
|
||||
uniform sampler2D tex;
|
||||
uniform float alpha;
|
||||
|
||||
#include "rounding.glsl"
|
||||
|
||||
uniform int discardOpaque;
|
||||
uniform int discardAlpha;
|
||||
uniform int discardAlphaValue;
|
||||
|
||||
uniform int applyTint;
|
||||
uniform vec3 tint;
|
||||
|
||||
void main() {
|
||||
|
||||
if (discardOpaque == 1 && alpha == 1.0)
|
||||
discard;
|
||||
|
||||
vec4 pixColor = vec4(texture2D(tex, v_texcoord).rgb, 1.0);
|
||||
|
||||
if (applyTint == 1) {
|
||||
pixColor[0] = pixColor[0] * tint[0];
|
||||
pixColor[1] = pixColor[1] * tint[1];
|
||||
pixColor[2] = pixColor[2] * tint[2];
|
||||
}
|
||||
|
||||
if (radius > 0.0)
|
||||
pixColor = rounding(pixColor);
|
||||
|
||||
gl_FragColor = pixColor * alpha;
|
||||
}
|
29
src/render/shaders/glsl/rounding.glsl
Normal file
29
src/render/shaders/glsl/rounding.glsl
Normal file
|
@ -0,0 +1,29 @@
|
|||
// smoothing constant for the edge: more = blurrier, but smoother
|
||||
#define M_PI 3.1415926535897932384626433832795
|
||||
#define SMOOTHING_CONSTANT (M_PI / 5.34665792551)
|
||||
|
||||
uniform float radius;
|
||||
uniform float roundingPower;
|
||||
uniform vec2 topLeft;
|
||||
uniform vec2 fullSize;
|
||||
|
||||
vec4 rounding(vec4 color) {
|
||||
vec2 pixCoord = vec2(gl_FragCoord);
|
||||
pixCoord -= topLeft + fullSize * 0.5;
|
||||
pixCoord *= vec2(lessThan(pixCoord, vec2(0.0))) * -2.0 + 1.0;
|
||||
pixCoord -= fullSize * 0.5 - radius;
|
||||
pixCoord += vec2(1.0, 1.0) / fullSize; // center the pix dont make it top-left
|
||||
|
||||
if (pixCoord.x + pixCoord.y > radius) {
|
||||
float dist = pow(pow(pixCoord.x, roundingPower) + pow(pixCoord.y, roundingPower), 1.0/roundingPower);
|
||||
|
||||
if (dist > radius + SMOOTHING_CONSTANT)
|
||||
discard;
|
||||
|
||||
float normalized = 1.0 - smoothstep(0.0, 1.0, (dist - radius + SMOOTHING_CONSTANT) / (SMOOTHING_CONSTANT * 2.0));
|
||||
|
||||
color *= normalized;
|
||||
}
|
||||
|
||||
return color;
|
||||
}
|
100
src/render/shaders/glsl/shadow.frag
Normal file
100
src/render/shaders/glsl/shadow.frag
Normal file
|
@ -0,0 +1,100 @@
|
|||
#version 300 es
|
||||
#extension GL_ARB_shading_language_include : enable
|
||||
|
||||
precision highp float;
|
||||
in vec4 v_color;
|
||||
in vec2 v_texcoord;
|
||||
|
||||
uniform int skipCM;
|
||||
uniform int sourceTF; // eTransferFunction
|
||||
uniform int targetTF; // eTransferFunction
|
||||
uniform mat4x2 sourcePrimaries;
|
||||
uniform mat4x2 targetPrimaries;
|
||||
|
||||
uniform vec2 topLeft;
|
||||
uniform vec2 bottomRight;
|
||||
uniform vec2 fullSize;
|
||||
uniform float radius;
|
||||
uniform float roundingPower;
|
||||
uniform float range;
|
||||
uniform float shadowPower;
|
||||
|
||||
#include "CM.glsl"
|
||||
|
||||
float pixAlphaRoundedDistance(float distanceToCorner) {
|
||||
if (distanceToCorner > radius) {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
if (distanceToCorner > radius - range) {
|
||||
return pow((range - (distanceToCorner - radius + range)) / range, shadowPower); // i think?
|
||||
}
|
||||
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
float modifiedLength(vec2 a) {
|
||||
return pow(pow(abs(a.x),roundingPower)+pow(abs(a.y),roundingPower),1.0/roundingPower);
|
||||
}
|
||||
|
||||
layout(location = 0) out vec4 fragColor;
|
||||
void main() {
|
||||
|
||||
vec4 pixColor = v_color;
|
||||
float originalAlpha = pixColor[3];
|
||||
|
||||
bool done = false;
|
||||
|
||||
vec2 pixCoord = fullSize * v_texcoord;
|
||||
|
||||
// ok, now we check the distance to a border.
|
||||
|
||||
if (pixCoord[0] < topLeft[0]) {
|
||||
if (pixCoord[1] < topLeft[1]) {
|
||||
// top left
|
||||
pixColor[3] = pixColor[3] * pixAlphaRoundedDistance(modifiedLength(pixCoord - topLeft));
|
||||
done = true;
|
||||
} else if (pixCoord[1] > bottomRight[1]) {
|
||||
// bottom left
|
||||
pixColor[3] = pixColor[3] * pixAlphaRoundedDistance(modifiedLength(pixCoord - vec2(topLeft[0], bottomRight[1])));
|
||||
done = true;
|
||||
}
|
||||
} else if (pixCoord[0] > bottomRight[0]) {
|
||||
if (pixCoord[1] < topLeft[1]) {
|
||||
// top right
|
||||
pixColor[3] = pixColor[3] * pixAlphaRoundedDistance(modifiedLength(pixCoord - vec2(bottomRight[0], topLeft[1])));
|
||||
done = true;
|
||||
} else if (pixCoord[1] > bottomRight[1]) {
|
||||
// bottom right
|
||||
pixColor[3] = pixColor[3] * pixAlphaRoundedDistance(modifiedLength(pixCoord - bottomRight));
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!done) {
|
||||
// distance to all straight bb borders
|
||||
float distanceT = pixCoord[1];
|
||||
float distanceB = fullSize[1] - pixCoord[1];
|
||||
float distanceL = pixCoord[0];
|
||||
float distanceR = fullSize[0] - pixCoord[0];
|
||||
|
||||
// get the smallest
|
||||
float smallest = min(min(distanceT, distanceB), min(distanceL, distanceR));
|
||||
|
||||
if (smallest < range) {
|
||||
pixColor[3] = pixColor[3] * pow((smallest / range), shadowPower);
|
||||
}
|
||||
}
|
||||
|
||||
if (pixColor[3] == 0.0) {
|
||||
discard; return;
|
||||
}
|
||||
|
||||
// premultiply
|
||||
pixColor.rgb *= pixColor[3];
|
||||
|
||||
if (skipCM == 0)
|
||||
pixColor = doColorManagement(pixColor, sourceTF, sourcePrimaries, targetTF, targetPrimaries);
|
||||
|
||||
fragColor = pixColor;
|
||||
}
|
|
@ -1,8 +1,4 @@
|
|||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
inline const std::string FRAGSHADOW = R"#(
|
||||
#extension GL_ARB_shading_language_include : enable
|
||||
precision highp float;
|
||||
varying vec4 v_color;
|
||||
varying vec2 v_texcoord;
|
||||
|
@ -87,4 +83,4 @@ void main() {
|
|||
pixColor.rgb *= pixColor[3];
|
||||
|
||||
gl_FragColor = pixColor;
|
||||
})#";
|
||||
}
|
15
src/render/shaders/glsl/tex.vert
Normal file
15
src/render/shaders/glsl/tex.vert
Normal file
|
@ -0,0 +1,15 @@
|
|||
uniform mat3 proj;
|
||||
uniform vec4 color;
|
||||
attribute vec2 pos;
|
||||
attribute vec2 texcoord;
|
||||
attribute vec2 texcoordMatte;
|
||||
varying vec4 v_color;
|
||||
varying vec2 v_texcoord;
|
||||
varying vec2 v_texcoordMatte;
|
||||
|
||||
void main() {
|
||||
gl_Position = vec4(proj * vec3(pos, 1.0), 1.0);
|
||||
v_color = color;
|
||||
v_texcoord = texcoord;
|
||||
v_texcoordMatte = texcoordMatte;
|
||||
}
|
17
src/render/shaders/glsl/tex300.vert
Normal file
17
src/render/shaders/glsl/tex300.vert
Normal file
|
@ -0,0 +1,17 @@
|
|||
#version 300 es
|
||||
|
||||
uniform mat3 proj;
|
||||
uniform vec4 color;
|
||||
in vec2 pos;
|
||||
in vec2 texcoord;
|
||||
in vec2 texcoordMatte;
|
||||
out vec4 v_color;
|
||||
out vec2 v_texcoord;
|
||||
out vec2 v_texcoordMatte;
|
||||
|
||||
void main() {
|
||||
gl_Position = vec4(proj * vec3(pos, 1.0), 1.0);
|
||||
v_color = color;
|
||||
v_texcoord = texcoord;
|
||||
v_texcoordMatte = texcoordMatte;
|
||||
}
|
17
src/render/shaders/glsl/tex320.vert
Normal file
17
src/render/shaders/glsl/tex320.vert
Normal file
|
@ -0,0 +1,17 @@
|
|||
#version 320 es
|
||||
|
||||
uniform mat3 proj;
|
||||
uniform vec4 color;
|
||||
in vec2 pos;
|
||||
in vec2 texcoord;
|
||||
in vec2 texcoordMatte;
|
||||
out vec4 v_color;
|
||||
out vec2 v_texcoord;
|
||||
out vec2 v_texcoordMatte;
|
||||
|
||||
void main() {
|
||||
gl_Position = vec4(proj * vec3(pos, 1.0), 1.0);
|
||||
v_color = color;
|
||||
v_texcoord = texcoord;
|
||||
v_texcoordMatte = texcoordMatte;
|
||||
}
|
Loading…
Add table
Reference in a new issue