diff --git a/app/qml/ApplicationSettings.qml b/app/qml/ApplicationSettings.qml index a6d6643..c73aa37 100644 --- a/app/qml/ApplicationSettings.qml +++ b/app/qml/ApplicationSettings.qml @@ -73,16 +73,11 @@ QtObject { property string _backgroundColor: "#000000" property string _fontColor: "#ff8100" - property string saturatedColor: Utils.mix(Utils.strToColor("#FFFFFF"), - Utils.strToColor(_fontColor), - saturationColor * 0.5) - property color fontColor: Utils.mix(Utils.strToColor(saturatedColor), - Utils.strToColor(_backgroundColor), - 0.7 + (contrast * 0.3)) - property color backgroundColor: Utils.mix(Utils.strToColor( - _backgroundColor), - Utils.strToColor(saturatedColor), - 0.7 + (contrast * 0.3)) + property string _frameColor: "#ffffff" + property string saturatedColor: Utils.mix(Utils.strToColor(_fontColor), Utils.strToColor("#FFFFFF"), (saturationColor * 0.5)) + property color fontColor: Utils.mix(Utils.strToColor(_backgroundColor), Utils.strToColor(saturatedColor), (0.7 + (contrast * 0.3))) + property color backgroundColor: Utils.mix(Utils.strToColor(saturatedColor), Utils.strToColor(_backgroundColor), (0.7 + (contrast * 0.3))) + property color frameColor: Utils.strToColor(_frameColor) property real staticNoise: 0.12 property real screenCurvature: 0.3 @@ -100,13 +95,14 @@ QtObject { property real rbgShift: 0.0 + property real _frameShininess: 0.2 + property real frameShininess: _frameShininess * 0.5 + property real _margin: 0.5 - property real _frameMargin: 0.5 - property real margin: Utils.lint(1.0, 20.0, _margin) - property real frameMargin: Utils.lint(1.0, 50.0, _frameMargin) - property real totalMargin: frameMargin + margin + property real _frameSize: 0.2 + property real frameSize: _frameSize * 0.1 readonly property int no_rasterization: 0 readonly property int scanline_rasterization: 1 @@ -304,7 +300,9 @@ QtObject { "fontWidth": fontWidth, "margin": _margin, "blinkingCursor": blinkingCursor, - "frameMargin": _frameMargin, + "frameSize": _frameSize, + "frameColor": _frameColor, + "frameShininess": _frameShininess } return settings } @@ -413,7 +411,9 @@ QtObject { lineSpacing = settings.lineSpacing !== undefined ? settings.lineSpacing : lineSpacing _margin = settings.margin !== undefined ? settings.margin : _margin - _frameMargin = settings.frameMargin !== undefined ? settings.frameMargin : _frameMargin + _frameSize = settings.frameSize !== undefined ? settings.frameSize : _frameSize + _frameColor = settings.frameColor !== undefined ? settings.frameColor : _frameColor + _frameShininess = settings.frameShininess !== undefined ? settings.frameShininess : _frameShininess blinkingCursor = settings.blinkingCursor !== undefined ? settings.blinkingCursor : blinkingCursor } @@ -498,7 +498,9 @@ QtObject { "windowOpacity": 1, "margin": 0.5, "blinkingCursor": false, - "frameMargin": 0.1 + "frameSize": 0.1, + "frameColor": "#ffffff", + "frameShininess": 0.2 }' builtin: true } @@ -528,7 +530,9 @@ QtObject { "windowOpacity": 1, "margin": 0.5, "blinkingCursor": false, - "frameMargin": 0.1 + "frameSize": 0.1, + "frameColor": "#ffffff", + "frameShininess": 0.2 }' builtin: true } @@ -559,7 +563,9 @@ QtObject { "windowOpacity": 1, "margin": 0.5, "blinkingCursor": false, - "frameMargin": 0.1 + "frameSize": 0.1, + "frameColor": "#ffffff", + "frameShininess": 0.2 }' builtin: true } @@ -590,7 +596,9 @@ QtObject { "windowOpacity": 1, "margin": 0.5, "blinkingCursor": false, - "frameMargin": 0.1 + "frameSize": 0.1, + "frameColor": "#ffffff", + "frameShininess": 0.2 }' builtin: true } @@ -621,7 +629,9 @@ QtObject { "windowOpacity": 1, "margin": 0.5, "blinkingCursor": false, - "frameMargin": 0.2 + "frameSize": 0.2, + "frameColor": "#ffffff", + "frameShininess": 0.2 }' builtin: true } @@ -652,7 +662,9 @@ QtObject { "windowOpacity": 1, "margin": 0.5, "blinkingCursor": false, - "frameMargin": 0.5 + "frameSize": 0.5, + "frameColor": "#ffffff", + "frameShininess": 0.2 }' builtin: true } @@ -683,7 +695,9 @@ QtObject { "windowOpacity": 1, "margin": 0.5, "blinkingCursor": false, - "frameMargin": 0.2 + "frameSize": 0.2, + "frameColor": "#ffffff", + "frameShininess": 0.2 }' builtin: true } @@ -714,7 +728,9 @@ QtObject { "windowOpacity": 1, "margin": 0.5, "blinkingCursor": false, - "frameMargin": 0.1 + "frameSize": 0.1, + "frameColor": "#ffffff", + "frameShininess": 0.2 }' builtin: true } @@ -745,7 +761,9 @@ QtObject { "windowOpacity": 0.7, "margin": 0.1, "blinkingCursor": false, - "frameMargin": 0 + "frameSize": 0, + "frameColor": "#ffffff", + "frameShininess": 0.2 }' builtin: true } diff --git a/app/qml/BurnInEffect.qml b/app/qml/BurnInEffect.qml index 464ca21..4f5fd53 100644 --- a/app/qml/BurnInEffect.qml +++ b/app/qml/BurnInEffect.qml @@ -139,11 +139,10 @@ Loader { property real screen_brightness: 1.0 property real bloom: 0 property real rbgShift: 0 - property real screenShadowCoeff: 0 property real frameShadowCoeff: 0 + property real frameShininess: 0 property color frameColor: backgroundColor - property size margin: Qt.size(0, 0) - + property real frameSize: 0 fragmentShader: "qrc:/shaders/burn_in.frag.qsb" vertexShader: "qrc:/shaders/passthrough.vert.qsb" diff --git a/app/qml/PreprocessedTerminal.qml b/app/qml/PreprocessedTerminal.qml index db1c9a1..a44669f 100644 --- a/app/qml/PreprocessedTerminal.qml +++ b/app/qml/PreprocessedTerminal.qml @@ -98,7 +98,7 @@ Item{ id: kterminal property int textureResolutionScale: appSettings.lowResolutionFont ? devicePixelRatio : 1 - property int margin: appSettings.totalMargin / screenScaling + property int margin: appSettings.margin / screenScaling property int totalWidth: Math.floor(parent.width / (screenScaling * fontWidth)) property int totalHeight: Math.floor(parent.height / screenScaling) @@ -213,7 +213,8 @@ Item{ property alias contextmenu: menuLoader.item MouseArea { - property real margin: appSettings.totalMargin + property real margin: appSettings.margin + property real frameSize: appSettings.frameSize acceptedButtons: Qt.LeftButton | Qt.MiddleButton | Qt.RightButton anchors.fill: parent @@ -247,10 +248,13 @@ Item{ kterminal.simulateMouseMove(coord.x, coord.y, mouse.button, mouse.buttons, mouse.modifiers); } - function correctDistortion(x, y){ + function correctDistortion(x, y) { x = (x - margin) / width; y = (y - margin) / height; + x = x * (1 + frameSize * 2) - frameSize; + y = y * (1 + frameSize * 2) - frameSize; + var cc = Qt.size(0.5 - x, 0.5 - y); var distortion = (cc.height * cc.height + cc.width * cc.width) * appSettings.screenCurvature * appSettings.screenCurvatureSize; diff --git a/app/qml/SettingsEffectsTab.qml b/app/qml/SettingsEffectsTab.qml index b6281f2..133eaec 100644 --- a/app/qml/SettingsEffectsTab.qml +++ b/app/qml/SettingsEffectsTab.qml @@ -86,6 +86,11 @@ ColumnLayout { onNewValue: function(newValue) { appSettings.rbgShift = newValue } value: appSettings.rbgShift } + CheckableSlider { + name: qsTr("Frame Shininess") + onNewValue: function(newValue) { appSettings._frameShininess = newValue } + value: appSettings._frameShininess + } } } } diff --git a/app/qml/SettingsGeneralTab.qml b/app/qml/SettingsGeneralTab.qml index ea936d2..0a70685 100644 --- a/app/qml/SettingsGeneralTab.qml +++ b/app/qml/SettingsGeneralTab.qml @@ -215,8 +215,8 @@ ColumnLayout { text: qsTr("Frame size") } SimpleSlider { - onValueChanged: appSettings._frameMargin = value - value: appSettings._frameMargin + onValueChanged: appSettings._frameSize = value + value: appSettings._frameSize } Label { text: qsTr("Opacity") diff --git a/app/qml/SettingsTerminalTab.qml b/app/qml/SettingsTerminalTab.qml index 11b2067..ddfcd16 100644 --- a/app/qml/SettingsTerminalTab.qml +++ b/app/qml/SettingsTerminalTab.qml @@ -209,6 +209,13 @@ ColumnLayout { onColorSelected: appSettings._backgroundColor = color color: appSettings._backgroundColor } + ColorButton { + name: qsTr("Frame") + height: 50 + Layout.fillWidth: true + onColorSelected: appSettings._frameColor = color + color: appSettings._frameColor + } } } } diff --git a/app/qml/ShaderTerminal.qml b/app/qml/ShaderTerminal.qml index 73fb4dc..50ba426 100644 --- a/app/qml/ShaderTerminal.qml +++ b/app/qml/ShaderTerminal.qml @@ -81,20 +81,20 @@ Item { property real rasterizationIntensity: Utils.smoothstep(2.0, 4.0, _screenDensity) property int rasterizationMode: appSettings.rasterization - property real displayTerminalFrame: appSettings._frameMargin > 0 || appSettings.screenCurvature > 0 + property real displayTerminalFrame: appSettings._frameSize > 0 || appSettings.screenCurvature > 0 property real time: timeManager.time property ShaderEffectSource noiseSource: noiseShaderSource // Extra uniforms expected by the shared uniform block - property real screenShadowCoeff: 0 property real frameShadowCoeff: 0 property color frameColor: backgroundColor - property size margin: Qt.size(0, 0) + property real frameSize: appSettings.frameSize property real prevLastUpdate: burnInEffect.prevLastUpdate property real screen_brightness: Utils.lint(0.5, 1.5, appSettings.brightness) property real bloom: appSettings.bloom property real rbgShift: (appSettings.rbgShift / Math.max(width, 1)) * appSettings.totalFontScaling + property real frameShininess: appSettings.frameShininess anchors.fill: parent blending: false @@ -174,6 +174,7 @@ Item { property real ambientLight: parent.ambientLight property size virtualResolution: parent.virtualResolution + property real frameShininess: appSettings.frameShininess // Extra uniforms to match shared uniform block property real time: timeManager.time @@ -193,10 +194,9 @@ Item { property real displayTerminalFrame: dynamicShader.displayTerminalFrame property size scaleNoiseSize: Qt.size((width * 0.75) / (512 * appSettings.windowScaling * appSettings.totalFontScaling), (height * 0.75) / (512 * appSettings.windowScaling * appSettings.totalFontScaling)) - property real screenShadowCoeff: 0 property real frameShadowCoeff: 0 property color frameColor: backgroundColor - property size margin: Qt.size(0, 0) + property real frameSize: appSettings.frameSize property real prevLastUpdate: burnInEffect.prevLastUpdate blending: false diff --git a/app/qml/TerminalFrame.qml b/app/qml/TerminalFrame.qml index ea169c4..dd0e56c 100644 --- a/app/qml/TerminalFrame.qml +++ b/app/qml/TerminalFrame.qml @@ -22,23 +22,25 @@ import QtQuick 2.0 import "utils.js" as Utils ShaderEffect { - property color _staticFrameColor: "#fff" + property color _staticFrameColor: Utils.sum(appSettings.frameColor, Qt.rgba(0.1, 0.1, 0.1, 1.0)) property color _backgroundColor: appSettings.backgroundColor property color _fontColor: appSettings.fontColor property color _lightColor: Utils.mix(_fontColor, _backgroundColor, 0.2) - property real _ambientLight: Utils.lint(0.2, 0.8, appSettings.ambientLight) + property real _ambientLight: appSettings.ambientLight + + property color frameColor: Utils.sum( + Utils.scaleColor(_staticFrameColor, 0.8 * _ambientLight), + Utils.scaleColor(_lightColor, 0.2) + ) - property color frameColor: Utils.mix(_staticFrameColor, _lightColor, _ambientLight) property real screenCurvature: appSettings.screenCurvature * appSettings.screenCurvatureSize + // TODO FILIPPO... Get rid of those... // Coefficient of the log curve used to approximate shadowing - property real screenShadowCoeff: Utils.lint(20.0, 10.0, _ambientLight) - property real frameShadowCoeff: Utils.lint(20.0, 10.0, _ambientLight) + property real frameShadowCoeff: 0.0125//Utils.lint(0.05, 0.025, _ambientLight) + property real frameShininess: appSettings.frameShininess - property size margin: Qt.size( - appSettings.frameMargin / width * appSettings.windowScaling, - appSettings.frameMargin / height * appSettings.windowScaling - ) + property real frameSize: appSettings.frameSize // Uniforms required by the shared block property real qt_Opacity: 1.0 diff --git a/app/qml/utils.js b/app/qml/utils.js index 3cb5a67..83c1877 100644 --- a/app/qml/utils.js +++ b/app/qml/utils.js @@ -32,10 +32,29 @@ function lint(a, b, t) { } function mix(c1, c2, alpha) { - return Qt.rgba(c1.r * alpha + c2.r * (1-alpha), - c1.g * alpha + c2.g * (1-alpha), - c1.b * alpha + c2.b * (1-alpha), - c1.a * alpha + c2.a * (1-alpha)) + return Qt.rgba(c1.r * (1 - alpha) + c2.r * alpha, + c1.g * (1 - alpha) + c2.g * alpha, + c1.b * (1 - alpha) + c2.b * alpha, + c1.a * (1 - alpha) + c2.a * alpha) +} + +function sum(c1, c2) { + let result = Qt.rgba( + clamp(c1.r + c2.r, 0, 1), + clamp(c1.g + c2.g, 0, 1), + clamp(c1.b + c2.b, 0, 1), + clamp(c1.a + c2.a, 0, 1) + ); + return result +} + +function scaleColor(c1, value) { + return Qt.rgba( + clamp(c1.r * value, 0, 1), + clamp(c1.g * value, 0, 1), + clamp(c1.b * value, 0, 1), + clamp(c1.a, 0, 1) + ); } function smoothstep(min, max, value) { diff --git a/app/shaders/burn_in.frag b/app/shaders/burn_in.frag index 4868fb8..ffb4f54 100644 --- a/app/shaders/burn_in.frag +++ b/app/shaders/burn_in.frag @@ -31,10 +31,8 @@ layout(std140, binding = 0) uniform ubuf { float screen_brightness; float bloom; float rbgShift; - float screenShadowCoeff; float frameShadowCoeff; vec4 frameColor; - vec2 margin; float prevLastUpdate; }; diff --git a/app/shaders/burn_in.frag.qsb b/app/shaders/burn_in.frag.qsb index 8d51dbf..543399f 100644 Binary files a/app/shaders/burn_in.frag.qsb and b/app/shaders/burn_in.frag.qsb differ diff --git a/app/shaders/passthrough.vert b/app/shaders/passthrough.vert index bfebde5..60a78da 100644 --- a/app/shaders/passthrough.vert +++ b/app/shaders/passthrough.vert @@ -31,10 +31,10 @@ layout(std140, binding = 0) uniform ubuf { float screen_brightness; float bloom; float rbgShift; - float screenShadowCoeff; float frameShadowCoeff; + float frameShininess; vec4 frameColor; - vec2 margin; + float frameSize; float prevLastUpdate; }; diff --git a/app/shaders/passthrough.vert.qsb b/app/shaders/passthrough.vert.qsb index 2574f37..20a79f3 100644 Binary files a/app/shaders/passthrough.vert.qsb and b/app/shaders/passthrough.vert.qsb differ diff --git a/app/shaders/terminal_dynamic.frag b/app/shaders/terminal_dynamic.frag index 0eb9453..cc0b057 100644 --- a/app/shaders/terminal_dynamic.frag +++ b/app/shaders/terminal_dynamic.frag @@ -35,10 +35,10 @@ layout(std140, binding = 0) uniform ubuf { float screen_brightness; float bloom; float rbgShift; - float screenShadowCoeff; float frameShadowCoeff; + float frameShininess; vec4 frameColor; - vec2 margin; + float frameSize; float prevLastUpdate; }; @@ -52,6 +52,13 @@ float prod2(vec2 v) { return v.x * v.y; } float sum2(vec2 v) { return v.x + v.y; } float rgb2grey(vec3 v) { return dot(v, vec3(0.21, 0.72, 0.04)); } +vec2 distortCoordinates(vec2 coords){ + vec2 paddedCoords = coords * (vec2(1.0) + frameSize * 2.0) - frameSize; + vec2 cc = (paddedCoords - vec2(0.5)); + float dist = dot(cc, cc) * screenCurvature; + return (paddedCoords + cc * (1.0 + dist) * dist); +} + vec3 applyRasterization(vec2 screenCoords, vec3 texel, vec2 virtualRes, float intensity, int mode) { if (intensity <= 0.0 || mode == 0) { return texel; @@ -105,11 +112,6 @@ float randomPass(vec2 coords){ return fract(smoothstep(-120.0, 0.0, coords.y - (virtualResolution.y + 120.0) * fract(time * 0.15))); } -vec2 barrel(vec2 v, vec2 cc) { - float distortion = dot(cc, cc) * screenCurvature; - return (v - cc * (1.0 + distortion) * distortion); -} - vec3 convertWithChroma(vec3 inColor) { vec3 outColor = fontColor.rgb * rgb2grey(inColor); if (chromaColor != 0.0) { @@ -122,7 +124,7 @@ void main() { vec2 cc = vec2(0.5) - qt_TexCoord0; float distance = length(cc); - vec2 staticCoords = barrel(qt_TexCoord0, cc); + vec2 staticCoords = distortCoordinates(qt_TexCoord0); vec2 coords = qt_TexCoord0; float dst = sin((coords.y + time) * vDistortionFreq); @@ -156,7 +158,9 @@ void main() { if (displayTerminalFrame > 0.0) { vec4 frameColor = texture(frameSource, qt_TexCoord0); - finalColor = mix(finalColor, frameColor.rgb, frameColor.a); + vec3 reflection = max(finalColor - backgroundColor.rgb, vec3(0.0)); + reflection *= frameShininess; + finalColor = mix(finalColor, frameColor.rgb + reflection, frameColor.a); } fragColor = vec4(finalColor, qt_Opacity); diff --git a/app/shaders/terminal_dynamic.frag.qsb b/app/shaders/terminal_dynamic.frag.qsb index 553d5ad..ad4dd84 100644 Binary files a/app/shaders/terminal_dynamic.frag.qsb and b/app/shaders/terminal_dynamic.frag.qsb differ diff --git a/app/shaders/terminal_dynamic.vert b/app/shaders/terminal_dynamic.vert index ff301a0..7426420 100644 --- a/app/shaders/terminal_dynamic.vert +++ b/app/shaders/terminal_dynamic.vert @@ -31,10 +31,10 @@ layout(std140, binding = 0) uniform ubuf { float screen_brightness; float bloom; float rbgShift; - float screenShadowCoeff; float frameShadowCoeff; + float frameShininess; vec4 frameColor; - vec2 margin; + float frameSize; float prevLastUpdate; }; diff --git a/app/shaders/terminal_dynamic.vert.qsb b/app/shaders/terminal_dynamic.vert.qsb index 1221ad1..99a6799 100644 Binary files a/app/shaders/terminal_dynamic.vert.qsb and b/app/shaders/terminal_dynamic.vert.qsb differ diff --git a/app/shaders/terminal_frame.frag b/app/shaders/terminal_frame.frag index 01b4627..46c0b77 100644 --- a/app/shaders/terminal_frame.frag +++ b/app/shaders/terminal_frame.frag @@ -31,10 +31,10 @@ layout(std140, binding = 0) uniform ubuf { float screen_brightness; float bloom; float rbgShift; - float screenShadowCoeff; float frameShadowCoeff; + float frameShininess; vec4 frameColor; - vec2 margin; + float frameSize; float prevLastUpdate; }; @@ -42,36 +42,49 @@ float min2(vec2 v) { return min(v.x, v.y); } float max2(vec2 v) { return max(v.x, v.y); } float prod2(vec2 v) { return v.x * v.y; } float sum2(vec2 v) { return v.x + v.y; } +float hash(vec2 v) { return fract(sin(dot(v, vec2(12.9898, 78.233))) * 43758.5453); } vec2 distortCoordinates(vec2 coords){ - vec2 cc = (coords - vec2(0.5)); + vec2 paddedCoords = coords * (vec2(1.0) + frameSize * 2.0) - frameSize; + vec2 cc = (paddedCoords - vec2(0.5)); float dist = dot(cc, cc) * screenCurvature; - return (coords + cc * (1.0 + dist) * dist); -} - -vec2 positiveLog(vec2 x) { - return clamp(log(x), vec2(0.0), vec2(100.0)); + return (paddedCoords + cc * (1.0 + dist) * dist); } void main() { vec2 staticCoords = qt_TexCoord0; - vec2 coords = distortCoordinates(staticCoords) * (vec2(1.0) + margin * 2.0) - margin; + vec2 coords = distortCoordinates(staticCoords); - vec2 vignetteCoords = staticCoords * (1.0 - staticCoords.yx); - float vignette = pow(prod2(vignetteCoords) * 15.0, 0.25); + float depth = 1.0 - 5.0 * min(min2(staticCoords), min2(vec2(1.0) - staticCoords)); - vec3 color = frameColor.rgb * vec3(1.0 - vignette); - float alpha = 0.0; + float occlusionWidth = 0.025; + float seamWidth = occlusionWidth; - float frameShadow = max2(positiveLog(-coords * frameShadowCoeff + vec2(1.0)) + positiveLog(coords * frameShadowCoeff - (vec2(frameShadowCoeff) - vec2(1.0)))); - frameShadow = max(sqrt(frameShadow), 0.0); - color *= frameShadow; - alpha = sum2(1.0 - step(vec2(0.0), coords) + step(vec2(1.0), coords)); - alpha = clamp(alpha, 0.0, 1.0); - alpha *= mix(1.0, 0.9, frameShadow); + float e = min( + smoothstep(-seamWidth, seamWidth, coords.x - coords.y), + smoothstep(-seamWidth, seamWidth, coords.x - (1.0 - coords.y)) + ); + float s = min( + smoothstep(-seamWidth, seamWidth, coords.y - coords.x), + smoothstep(-seamWidth, seamWidth, coords.x - (1.0 - coords.y)) + ); + float w = min( + smoothstep(-seamWidth, seamWidth, coords.y - coords.x), + smoothstep(-seamWidth, seamWidth, (1.0 - coords.x) - coords.y) + ); + float n = min( + smoothstep(-seamWidth, seamWidth, coords.x - coords.y), + smoothstep(-seamWidth, seamWidth, (1.0 - coords.x) - coords.y) + ); - float screenShadow = 1.0 - prod2(positiveLog(coords * screenShadowCoeff + vec2(1.0)) * positiveLog(-coords * screenShadowCoeff + vec2(screenShadowCoeff + 1.0))); - alpha = max(0.8 * screenShadow, alpha); + vec2 clampedCoords = clamp(coords, vec2(0.0), vec2(1.0)); + float innerEdgeDist = length(coords - clampedCoords); + float occlusion = smoothstep(0.0, occlusionWidth, innerEdgeDist); + float frameShadow = e * 0.75 + w * 0.75 + n * 0.50 + s * 1.00; + frameShadow *= sqrt(occlusion) * depth; + + vec3 color = frameColor.rgb * frameShadow; + float alpha = clamp(sum2(1.0 - step(vec2(0.0), coords) + step(vec2(1.0), coords)), 0.0, 1.0); fragColor = vec4(color * alpha, alpha) * qt_Opacity; } diff --git a/app/shaders/terminal_frame.frag.qsb b/app/shaders/terminal_frame.frag.qsb index dfcec53..56a7760 100644 Binary files a/app/shaders/terminal_frame.frag.qsb and b/app/shaders/terminal_frame.frag.qsb differ diff --git a/app/shaders/terminal_static.frag b/app/shaders/terminal_static.frag index 6729d38..a2f3d73 100644 --- a/app/shaders/terminal_static.frag +++ b/app/shaders/terminal_static.frag @@ -31,19 +31,27 @@ layout(std140, binding = 0) uniform ubuf { float screen_brightness; float bloom; float rbgShift; - float screenShadowCoeff; float frameShadowCoeff; + float frameShininess; vec4 frameColor; - vec2 margin; + float frameSize; float prevLastUpdate; }; layout(binding = 1) uniform sampler2D source; layout(binding = 2) uniform sampler2D bloomSource; -float sum2(vec2 v) { return v.x + v.y; } +float min2(vec2 v) { return min(v.x, v.y); } +float max2(vec2 v) { return max(v.x, v.y); } float rgb2grey(vec3 v) { return dot(v, vec3(0.21, 0.72, 0.04)); } +vec2 distortCoordinates(vec2 coords){ + vec2 paddedCoords = coords * (vec2(1.0) + frameSize * 2.0) - frameSize; + vec2 cc = (paddedCoords - vec2(0.5)); + float dist = dot(cc, cc) * screenCurvature; + return (paddedCoords + cc * (1.0 + dist) * dist); +} + vec3 convertWithChroma(vec3 inColor) { vec3 outColor = fontColor.rgb * rgb2grey(inColor); if (chromaColor != 0.0) { @@ -55,16 +63,22 @@ vec3 convertWithChroma(vec3 inColor) { void main() { vec2 cc = vec2(0.5) - qt_TexCoord0; + float shownDraw = 1.0; + float isReflection = 0.0; + float isScreen = 1.0; + vec2 txt_coords = qt_TexCoord0; - if (screenCurvature != 0.0) { - float distortion = dot(cc, cc) * screenCurvature; - vec2 curvatureCoords = (qt_TexCoord0 - cc * (1.0 + distortion) * distortion); + if (screenCurvature > 0.0 || frameSize > 0.0) { + vec2 curvatureCoords = distortCoordinates(qt_TexCoord0); + shownDraw = max2(step(vec2(0.0), curvatureCoords) - step(vec2(1.0), curvatureCoords)); + isScreen = min2(step(vec2(0.0), curvatureCoords) - step(vec2(1.0), curvatureCoords)); + isReflection = shownDraw - isScreen; txt_coords = -2.0 * curvatureCoords + 3.0 * step(vec2(0.0), curvatureCoords) * curvatureCoords - 3.0 * step(vec2(1.0), curvatureCoords) * curvatureCoords; } vec3 txt_color = texture(source, txt_coords).rgb; - if (rbgShift != 0.0) { + if (rbgShift > 0.0) { vec2 displacement = vec2(12.0, 0.0) * rbgShift; vec3 rightColor = texture(source, txt_coords + displacement).rgb; vec3 leftColor = texture(source, txt_coords - displacement).rgb; @@ -76,27 +90,27 @@ void main() { txt_color += vec3(0.0001); float greyscale_color = rgb2grey(txt_color); - float reflectionMask = 1.0; - if (screenCurvature != 0.0) { - float distortion = dot(cc, cc) * screenCurvature; - vec2 curvatureCoords = (qt_TexCoord0 - cc * (1.0 + distortion) * distortion); - reflectionMask = sum2(step(vec2(0.0), curvatureCoords) - step(vec2(1.0), curvatureCoords)); - reflectionMask = clamp(reflectionMask, 0.0, 1.0); - } - vec3 finalColor; - if (chromaColor != 0.0) { + if (chromaColor > 0.0) { vec3 foregroundColor = mix(fontColor.rgb, txt_color * fontColor.rgb / greyscale_color, chromaColor); - finalColor = mix(backgroundColor.rgb, foregroundColor, greyscale_color * reflectionMask); + finalColor = mix(backgroundColor.rgb, foregroundColor, greyscale_color * shownDraw); } else { - finalColor = mix(backgroundColor.rgb, fontColor.rgb, greyscale_color * reflectionMask); + finalColor = mix(backgroundColor.rgb, fontColor.rgb, greyscale_color * shownDraw); } - if (bloom != 0.0) { - vec4 bloomFullColor = texture(bloomSource, txt_coords); - vec3 bloomColor = convertWithChroma(bloomFullColor.rgb); - float bloomAlpha = bloomFullColor.a; - finalColor += clamp(bloomColor * bloom * bloomAlpha, 0.0, 0.5); + vec4 bloomFullColor = texture(bloomSource, txt_coords); + vec3 bloomColor = convertWithChroma(bloomFullColor.rgb); + float bloomAlpha = bloomFullColor.a; + + if (bloom > 0.0) { + vec3 bloomOnScreen = bloomColor * isScreen; + finalColor += clamp(bloomOnScreen * bloom * bloomAlpha, 0.0, 0.5); + } + + if (frameShininess > 0.0) { + float shine = clamp(frameShininess, 0.0, 1.0); + vec3 reflectionColor = mix(bloomColor, finalColor, shine * 0.5); + finalColor = mix(finalColor, reflectionColor, isReflection); } finalColor *= screen_brightness; diff --git a/app/shaders/terminal_static.frag.qsb b/app/shaders/terminal_static.frag.qsb index 3bc2be5..2cf21ec 100644 Binary files a/app/shaders/terminal_static.frag.qsb and b/app/shaders/terminal_static.frag.qsb differ