mirror of
https://github.com/hyprwm/Hyprland
synced 2025-04-13 07:18:08 +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*
|
protocols/*.h*
|
||||||
.ccls-cache
|
.ccls-cache
|
||||||
*.so
|
*.so
|
||||||
|
src/render/shaders/*.inc
|
||||||
|
src/render/shaders/Shaders.hpp
|
||||||
|
|
||||||
hyprctl/hyprctl
|
hyprctl/hyprctl
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,9 @@ message(STATUS "Gathering git info")
|
||||||
# Get git info hash and branch
|
# Get git info hash and branch
|
||||||
execute_process(COMMAND ./scripts/generateVersion.sh
|
execute_process(COMMAND ./scripts/generateVersion.sh
|
||||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
|
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
|
||||||
|
# Make shader files includable
|
||||||
|
execute_process(COMMAND ./scripts/generateShaderIncludes.sh
|
||||||
|
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
|
||||||
|
|
||||||
find_package(PkgConfig REQUIRED)
|
find_package(PkgConfig REQUIRED)
|
||||||
|
|
||||||
|
@ -445,4 +448,5 @@ install(
|
||||||
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/hyprland
|
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/hyprland
|
||||||
FILES_MATCHING
|
FILES_MATCHING
|
||||||
PATTERN "*.h*"
|
PATTERN "*.h*"
|
||||||
PATTERN "*.frag")
|
PATTERN "*.inc"
|
||||||
|
)
|
||||||
|
|
|
@ -87,9 +87,11 @@ endif
|
||||||
|
|
||||||
# Generate hyprland version and populate version.h
|
# Generate hyprland version and populate version.h
|
||||||
run_command('sh', '-c', 'scripts/generateVersion.sh', check: true)
|
run_command('sh', '-c', 'scripts/generateVersion.sh', check: true)
|
||||||
|
# Make shader files includable
|
||||||
|
run_command('sh', '-c', 'scripts/generateShaderIncludes.sh', check: true)
|
||||||
|
|
||||||
# Install headers
|
# 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')
|
headers = globber.stdout().strip().split('\n')
|
||||||
foreach file : headers
|
foreach file : headers
|
||||||
install_headers(file, subdir: 'hyprland', preserve_path: true)
|
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 "../managers/AnimationManager.hpp"
|
||||||
#include "../debug/HyprNotificationOverlay.hpp"
|
#include "../debug/HyprNotificationOverlay.hpp"
|
||||||
#include "../render/Renderer.hpp"
|
#include "../render/Renderer.hpp"
|
||||||
|
#include "../render/OpenGL.hpp"
|
||||||
|
|
||||||
static void trimTrailingComma(std::string& str) {
|
static void trimTrailingComma(std::string& str) {
|
||||||
if (!str.empty() && str.back() == ',')
|
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");
|
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() {
|
CHyprCtl::CHyprCtl() {
|
||||||
registerCommand(SHyprCtlCommand{"workspaces", true, workspacesRequest});
|
registerCommand(SHyprCtlCommand{"workspaces", true, workspacesRequest});
|
||||||
registerCommand(SHyprCtlCommand{"workspacerules", true, workspaceRulesRequest});
|
registerCommand(SHyprCtlCommand{"workspacerules", true, workspaceRulesRequest});
|
||||||
|
@ -1665,6 +1673,7 @@ CHyprCtl::CHyprCtl() {
|
||||||
registerCommand(SHyprCtlCommand{"locked", true, getIsLocked});
|
registerCommand(SHyprCtlCommand{"locked", true, getIsLocked});
|
||||||
registerCommand(SHyprCtlCommand{"descriptions", true, getDescriptions});
|
registerCommand(SHyprCtlCommand{"descriptions", true, getDescriptions});
|
||||||
registerCommand(SHyprCtlCommand{"submap", true, submapRequest});
|
registerCommand(SHyprCtlCommand{"submap", true, submapRequest});
|
||||||
|
registerCommand(SHyprCtlCommand{.name = "reloadshaders", .exact = true, .fn = reloadShaders});
|
||||||
|
|
||||||
registerCommand(SHyprCtlCommand{"monitors", false, monitorsRequest});
|
registerCommand(SHyprCtlCommand{"monitors", false, monitorsRequest});
|
||||||
registerCommand(SHyprCtlCommand{"reload", false, reloadRequest});
|
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 "../helpers/sync/SyncTimeline.hpp"
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <list>
|
#include <list>
|
||||||
|
#include <string>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
|
@ -78,6 +79,26 @@ enum eMonitorExtraRenderFBs : uint8_t {
|
||||||
FB_MONITOR_RENDER_EXTRA_BLUR,
|
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 {
|
struct SMonitorRenderData {
|
||||||
CFramebuffer offloadFB;
|
CFramebuffer offloadFB;
|
||||||
CFramebuffer mirrorFB; // these are used for some effects,
|
CFramebuffer mirrorFB; // these are used for some effects,
|
||||||
|
@ -90,23 +111,6 @@ struct SMonitorRenderData {
|
||||||
|
|
||||||
bool blurFBDirty = true;
|
bool blurFBDirty = true;
|
||||||
bool blurFBShouldRender = false;
|
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 {
|
struct SCurrentRenderData {
|
||||||
|
@ -232,6 +236,10 @@ class CHyprOpenGLImpl {
|
||||||
EGLImageKHR createEGLImage(const Aquamarine::SDMABUFAttrs& attrs);
|
EGLImageKHR createEGLImage(const Aquamarine::SDMABUFAttrs& attrs);
|
||||||
SP<CEGLSync> createEGLSync(int fence = -1);
|
SP<CEGLSync> createEGLSync(int fence = -1);
|
||||||
|
|
||||||
|
bool initShaders();
|
||||||
|
bool m_bShadersInitialized = false;
|
||||||
|
SP<SPreparedShaders> m_shaders;
|
||||||
|
|
||||||
SCurrentRenderData m_RenderData;
|
SCurrentRenderData m_RenderData;
|
||||||
|
|
||||||
Hyprutils::OS::CFileDescriptor m_iGBMFD;
|
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 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);
|
GLuint compileShader(const GLuint&, std::string, bool dynamic = false, bool silent = false);
|
||||||
void createBGTextureForMonitor(PHLMONITOR);
|
void createBGTextureForMonitor(PHLMONITOR);
|
||||||
void initShaders();
|
|
||||||
void initDRMFormats();
|
void initDRMFormats();
|
||||||
void initEGL(bool gbm);
|
void initEGL(bool gbm);
|
||||||
EGLDeviceEXT eglDeviceFromDRMFD(int drmFD);
|
EGLDeviceEXT eglDeviceFromDRMFD(int drmFD);
|
||||||
|
@ -322,6 +329,9 @@ class CHyprOpenGLImpl {
|
||||||
// returns the out FB, can be either Mirror or MirrorSwap
|
// returns the out FB, can be either Mirror or MirrorSwap
|
||||||
CFramebuffer* blurMainFramebufferWithDamage(float a, CRegion* damage);
|
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,
|
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);
|
bool noAA = false, bool allowCustomUV = false, bool allowDim = false);
|
||||||
void renderTexturePrimitive(SP<CTexture> tex, const CBox& box);
|
void renderTexturePrimitive(SP<CTexture> tex, const CBox& box);
|
||||||
|
|
|
@ -1,17 +1,5 @@
|
||||||
#include "Shader.hpp"
|
#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() {
|
CShader::~CShader() {
|
||||||
destroy();
|
destroy();
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@ class CShader {
|
||||||
GLint color = -1;
|
GLint color = -1;
|
||||||
GLint alphaMatte = -1;
|
GLint alphaMatte = -1;
|
||||||
GLint texType = -1;
|
GLint texType = -1;
|
||||||
|
GLint skipCM = -1;
|
||||||
GLint sourceTF = -1;
|
GLint sourceTF = -1;
|
||||||
GLint targetTF = -1;
|
GLint targetTF = -1;
|
||||||
GLint sourcePrimaries = -1;
|
GLint sourcePrimaries = -1;
|
||||||
|
@ -74,8 +75,6 @@ class CShader {
|
||||||
GLint brightness = -1;
|
GLint brightness = -1;
|
||||||
GLint noise = -1;
|
GLint noise = -1;
|
||||||
|
|
||||||
GLint getUniformLocation(const std::string&);
|
|
||||||
|
|
||||||
void destroy();
|
void destroy();
|
||||||
|
|
||||||
private:
|
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 maxLuminance;
|
||||||
uniform float dstMaxLuminance;
|
uniform float dstMaxLuminance;
|
||||||
uniform float dstRefLuminance;
|
uniform float dstRefLuminance;
|
||||||
uniform float sdrSaturation;
|
uniform float sdrSaturation;
|
||||||
uniform float sdrBrightnessMultiplier;
|
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
|
//enum eTransferFunction
|
||||||
#define CM_TRANSFER_FUNCTION_BT1886 1
|
#define CM_TRANSFER_FUNCTION_BT1886 1
|
||||||
#define CM_TRANSFER_FUNCTION_GAMMA22 2
|
#define CM_TRANSFER_FUNCTION_GAMMA22 2
|
||||||
|
@ -78,31 +50,7 @@ uniform vec3 tint;
|
||||||
#define HDR_MAX_LUMINANCE 10000.0
|
#define HDR_MAX_LUMINANCE 10000.0
|
||||||
#define HLG_MAX_LUMINANCE 1000.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 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) {
|
vec3 xy2xyz(vec2 xy) {
|
||||||
if (xy.y == 0.0)
|
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]);
|
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;
|
vec4 doColorManagement(vec4 pixColor, int srcTF, mat4x2 srcPrimaries, int dstTF, mat4x2 dstPrimaries) {
|
||||||
void main() {
|
pixColor.rgb /= max(pixColor.a, 0.001);
|
||||||
vec4 pixColor;
|
pixColor.rgb = toLinearRGB(pixColor.rgb, srcTF);
|
||||||
if (texType == 1)
|
mat3 srcxyz = primaries2xyz(srcPrimaries);
|
||||||
pixColor = vec4(texture(tex, v_texcoord).rgb, 1.0);
|
mat3 dstxyz;
|
||||||
// else if (texType == 2)
|
if (srcPrimaries == dstPrimaries)
|
||||||
// pixColor = texture(texture0, v_texcoord);
|
dstxyz = srcxyz;
|
||||||
else // assume rgba
|
else {
|
||||||
pixColor = texture(tex, v_texcoord);
|
dstxyz = primaries2xyz(dstPrimaries);
|
||||||
|
pixColor = convertPrimaries(pixColor, srcxyz, srcPrimaries[3], dstxyz, dstPrimaries[3]);
|
||||||
if (discardOpaque == 1 && pixColor[3] * alpha == 1.0)
|
}
|
||||||
discard;
|
pixColor = toNit(pixColor, srcTF);
|
||||||
|
pixColor.rgb *= pixColor.a;
|
||||||
if (discardAlpha == 1 && pixColor[3] <= discardAlphaValue)
|
pixColor = tonemap(pixColor, dstxyz);
|
||||||
discard;
|
pixColor = fromLinearNit(pixColor, dstTF);
|
||||||
|
if (srcTF == CM_TRANSFER_FUNCTION_SRGB && dstTF == CM_TRANSFER_FUNCTION_ST2084_PQ) {
|
||||||
pixColor.rgb /= max(pixColor.a, 0.001);
|
pixColor = saturate(pixColor, srcxyz, sdrSaturation);
|
||||||
pixColor.rgb = toLinearRGB(pixColor.rgb, sourceTF);
|
pixColor.rgb /= pixColor.a;
|
||||||
mat3 srcxyz = primaries2xyz(sourcePrimaries);
|
pixColor.rgb *= sdrBrightnessMultiplier;
|
||||||
mat3 dstxyz;
|
pixColor.rgb *= pixColor.a;
|
||||||
|
}
|
||||||
if (sourcePrimaries == targetPrimaries)
|
return pixColor;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
)#"
|
|
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;
|
precision highp float;
|
||||||
varying vec4 v_color;
|
varying vec4 v_color;
|
||||||
varying vec2 v_texcoord;
|
varying vec2 v_texcoord;
|
||||||
|
|
||||||
uniform vec2 topLeft;
|
|
||||||
uniform vec2 fullSize;
|
|
||||||
uniform vec2 fullSizeUntransformed;
|
uniform vec2 fullSizeUntransformed;
|
||||||
uniform float radius;
|
|
||||||
uniform float radiusOuter;
|
uniform float radiusOuter;
|
||||||
uniform float roundingPower;
|
|
||||||
uniform float thick;
|
uniform float thick;
|
||||||
|
|
||||||
// Gradients are in OkLabA!!!! {l, a, b, alpha}
|
// Gradients are in OkLabA!!!! {l, a, b, alpha}
|
||||||
|
@ -28,6 +18,8 @@ uniform float angle2;
|
||||||
uniform float gradientLerp;
|
uniform float gradientLerp;
|
||||||
uniform float alpha;
|
uniform float alpha;
|
||||||
|
|
||||||
|
#include "rounding.glsl"
|
||||||
|
|
||||||
float linearToGamma(float x) {
|
float linearToGamma(float x) {
|
||||||
return x >= 0.0031308 ? 1.055 * pow(x, 0.416666666) - 0.055 : 12.92 * 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;
|
pixCoordOuter += vec2(1.0, 1.0) / fullSize;
|
||||||
|
|
||||||
if (min(pixCoord.x, pixCoord.y) > 0.0 && radius > 0.0) {
|
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 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 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) {
|
if (dist < radius - h) {
|
||||||
// lower
|
// lower
|
||||||
|
@ -184,4 +172,3 @@ void main() {
|
||||||
|
|
||||||
gl_FragColor = pixColor;
|
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
|
#extension GL_ARB_shading_language_include : enable
|
||||||
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
inline const std::string FRAGSHADOW = R"#(
|
|
||||||
precision highp float;
|
precision highp float;
|
||||||
varying vec4 v_color;
|
varying vec4 v_color;
|
||||||
varying vec2 v_texcoord;
|
varying vec2 v_texcoord;
|
||||||
|
@ -87,4 +83,4 @@ void main() {
|
||||||
pixColor.rgb *= pixColor[3];
|
pixColor.rgb *= pixColor[3];
|
||||||
|
|
||||||
gl_FragColor = pixColor;
|
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