🔧 Tweak portal effect

This commit is contained in:
Simon Schneegans
2022-12-22 19:58:06 +01:00
parent 4b6a76fbea
commit 41fbab48f6
6 changed files with 475 additions and 26 deletions
+22 -20
View File
@@ -14,28 +14,30 @@
// The content from common.glsl is automatically prepended to each shader effect.
uniform vec3 uColor;
uniform vec2 uSeed;
uniform vec3 uColor;
uniform float uRotationSpeed;
uniform float uWhirl;
uniform float uDetails;
const float PORTAL_OPEN_TIME = 0.3;
const float PORTAL_WOBBLE_TIME = 0.8;
const float PORTAL_WOBBLE_STRENGTH = 1.2;
const float PORTAL_CLOSE_TIME = 0.3;
const float PORTAL_ROTATION_SPEED = 0.3;
const float PORTAL_WARPING = 3.0;
const float GLOW_EDGE_WIDTH = 5.0;
const float WINDOW_ANIMATION_TIME = 0.3;
const float WINDOW_SCALE = 0.3;
const float WINDOW_SQUISH = 1.0;
const float WINDOW_TILT = -1.0;
const float WINDOW_SCALE = 0.3;
const float WINDOW_SQUISH = 1.0;
const float WINDOW_TILT = -1.0;
float PORTAL_OPEN_TIME = 0.3 * 1.5 / uDuration;
float PORTAL_CLOSE_TIME = 0.3 * 1.5 / uDuration;
float WINDOW_OPEN_TIME = 0.3 * 1.5 / uDuration;
// This will distort the given coordinate to achieve the wobble effect of the portal when
// the window passes through. The wobble happens around the point where the window appears
// or disappears (which is controlled by WINDOW_ANIMATION_TIME) and takes
// or disappears (which is controlled by WINDOW_OPEN_TIME) and takes
// PORTAL_WOBBLE_TIME.
vec2 getPortalWobble(vec2 coords) {
float progress = (uForOpening ? (1.0 - uProgress) : uProgress) / WINDOW_ANIMATION_TIME;
float progress = (uForOpening ? (1.0 - uProgress) : uProgress) / WINDOW_OPEN_TIME;
progress = clamp(1.0 - abs((progress - 1.0) / PORTAL_WOBBLE_TIME), 0.0, 1.0);
progress = easeInBack(progress, 1.7);
float dist = length(coords);
@@ -70,8 +72,8 @@ vec2 getRandomDisplace(vec2 seed, float scale) {
// twisting (higher multipliers will make coordinates which are closer to the origin be
// rotated more than coordinates farther away).
vec2 getWhirledCoords(vec2 coords, float speedMultiplier, float warpMultiplier) {
float rotation = PORTAL_ROTATION_SPEED * uProgress * uDuration * speedMultiplier;
float warping = PORTAL_WARPING * (2.0 + 0.5 * uProgress) * warpMultiplier;
float rotation = uRotationSpeed * uProgress * uDuration * speedMultiplier;
float warping = uWhirl * (6.0 + 1.5 * uProgress) * warpMultiplier;
return whirl(coords, warping, rotation);
}
@@ -101,13 +103,13 @@ vec4 getPortalColor() {
// This is used below to scale the detail level of the layers. If the portal is small,
// we want to have less details, if the portal is huge on the screen, theres plenty of
// space for details.
float detailScale = 1000.0 / (uSize.x + uSize.y);
float detailScale = 10000.0 / (uSize.x + uSize.y) / uDetails;
// ---------------------------------------------------------------------------- 1. layer
// We start with the background layer. This is a radial gradient from a dark color in
// the center to a not-so-dark color in the outer regions. We distort the coordinates to
// add some variations to the colors and to the shape of the portal.
vec2 layerCoords = getWhirledCoords(coords - wobble * 1.0, 0.5, 1.0);
vec2 layerCoords = getWhirledCoords(coords - wobble * 1.0, 0.25, 1.0);
vec2 displace = getRandomDisplace(layerCoords, 2.1);
layerCoords += displace * 0.1;
float dist = length(layerCoords);
@@ -124,7 +126,7 @@ vec4 getPortalColor() {
// ---------------------------------------------------------------------------- 3. layer
// The second layer of whirly bands uses a lighter color and a different set of
// distorted coordinates.
layerCoords = getWhirledCoords(coords - wobble * 1.5, 1.5, 0.5);
layerCoords = getWhirledCoords(coords - wobble * 1.5, 0.75, 0.5);
displace = getRandomDisplace(layerCoords, 12.2);
layerCoords += displace * 0.1;
noise = simplex2D(layerCoords / detailScale * 1.3 + uSeed);
@@ -145,9 +147,9 @@ vec4 getPortalColor() {
// ---------------------------------------------------------------------------- 5. layer
// Finally, we add some sparkling lights.
layerCoords = getWhirledCoords(coords - wobble * 1.8, 2.5, 0.0);
layerCoords = getWhirledCoords(coords - wobble * 1.8, 1.25, 0.0);
noise = simplex2D(layerCoords / detailScale * 3.0 + uSeed);
layer.rgb = lighten(uColor, 0.5) * clamp(pow(noise * rand + 0.9, 50.0), 0.0, 1.0);
layer.rgb = lighten(uColor, 0.8) * clamp(pow(noise * rand + 0.9, 50.0), 0.0, 1.0);
color.rgb += layer.rgb;
// Finally, fade in / out the portal when it appears / disappears.
@@ -160,9 +162,9 @@ vec4 getPortalColor() {
// animation will happen in a fraction of the full animation time (at the end of the
// animation when opening a window and at the beginning of the animation when closing the
// window). The fraction of the animation time take for the window animation is defined by
// WINDOW_ANIMATION_TIME.
// WINDOW_OPEN_TIME.
vec4 getWindowColor() {
float progress = (uForOpening ? (1.0 - uProgress) : uProgress) / WINDOW_ANIMATION_TIME;
float progress = (uForOpening ? (1.0 - uProgress) : uProgress) / WINDOW_OPEN_TIME;
// Add some elastic easing to make the effect more dynamic.
progress = easeInBack(clamp(progress, 0.0, 1.0), 1.2);
+100 -1
View File
@@ -22,7 +22,7 @@ SPDX-License-Identifier: GPL-3.0-or-later
<property name="adjustment">
<object class="GtkAdjustment" id="portal-animation-time">
<property name="upper">5000</property>
<property name="lower">100</property>
<property name="lower">1000</property>
<property name="step-increment">1</property>
<property name="page-increment">100</property>
</object>
@@ -42,6 +42,105 @@ SPDX-License-Identifier: GPL-3.0-or-later
</object>
</child>
<child>
<object class="AdwActionRow">
<property name="title" translatable="yes">Rotation Speed</property>
<child>
<object class="GtkScale">
<property name="valign">center</property>
<property name="draw-value">1</property>
<property name="digits">2</property>
<property name="value-pos">left</property>
<property name="width-request">300</property>
<property name="adjustment">
<object class="GtkAdjustment" id="portal-rotation-speed">
<property name="upper">2</property>
<property name="lower">-2</property>
<property name="step-increment">0.1</property>
<property name="page-increment">1</property>
</object>
</property>
</object>
</child>
<child>
<object class="GtkButton" id="reset-portal-rotation-speed">
<property name="icon-name">edit-clear-symbolic</property>
<property name="valign">center</property>
<property name="tooltip-text" translatable="yes">Reset to Default Value</property>
<style>
<class name="flat" />
</style>
</object>
</child>
</object>
</child>
<child>
<object class="AdwActionRow">
<property name="title" translatable="yes">Whirl</property>
<child>
<object class="GtkScale">
<property name="valign">center</property>
<property name="draw-value">1</property>
<property name="digits">2</property>
<property name="value-pos">left</property>
<property name="width-request">300</property>
<property name="adjustment">
<object class="GtkAdjustment" id="portal-whirl">
<property name="upper">2</property>
<property name="lower">-2</property>
<property name="step-increment">0.1</property>
<property name="page-increment">1</property>
</object>
</property>
</object>
</child>
<child>
<object class="GtkButton" id="reset-portal-whirl">
<property name="icon-name">edit-clear-symbolic</property>
<property name="valign">center</property>
<property name="tooltip-text" translatable="yes">Reset to Default Value</property>
<style>
<class name="flat" />
</style>
</object>
</child>
</object>
</child>
<child>
<object class="AdwActionRow">
<property name="title" translatable="yes">Details</property>
<child>
<object class="GtkScale">
<property name="valign">center</property>
<property name="draw-value">1</property>
<property name="digits">1</property>
<property name="value-pos">left</property>
<property name="width-request">300</property>
<property name="adjustment">
<object class="GtkAdjustment" id="portal-details">
<property name="upper">100</property>
<property name="lower">1</property>
<property name="step-increment">1</property>
<property name="page-increment">10</property>
</object>
</property>
</object>
</child>
<child>
<object class="GtkButton" id="reset-portal-details">
<property name="icon-name">edit-clear-symbolic</property>
<property name="valign">center</property>
<property name="tooltip-text" translatable="yes">Reset to Default Value</property>
<style>
<class name="flat" />
</style>
</object>
</child>
</object>
</child>
<child>
<object class="AdwActionRow">
<property name="title" translatable="yes">Color</property>
+178 -1
View File
@@ -9,11 +9,32 @@ SPDX-License-Identifier: GPL-3.0-or-later
<object class="GtkAdjustment" id="portal-animation-time">
<property name="upper">5000</property>
<property name="lower">100</property>
<property name="lower">1000</property>
<property name="step-increment">1</property>
<property name="page-increment">100</property>
</object>
<object class="GtkAdjustment" id="portal-rotation-speed">
<property name="upper">2</property>
<property name="lower">-2</property>
<property name="step-increment">0.1</property>
<property name="page-increment">1</property>
</object>
<object class="GtkAdjustment" id="portal-whirl">
<property name="upper">2</property>
<property name="lower">-2</property>
<property name="step-increment">0.1</property>
<property name="page-increment">1</property>
</object>
<object class="GtkAdjustment" id="portal-details">
<property name="upper">100</property>
<property name="lower">1</property>
<property name="step-increment">1</property>
<property name="page-increment">10</property>
</object>
<object class="GtkBox" id="portal-prefs">
<property name="orientation">vertical</property>
@@ -78,6 +99,162 @@ SPDX-License-Identifier: GPL-3.0-or-later
</object>
</child>
<child>
<object class="GtkListBoxRow">
<property name="margin-start">10</property>
<property name="margin-end">10</property>
<property name="margin-top">10</property>
<property name="margin-bottom">10</property>
<property name="activatable">0</property>
<child>
<object class="GtkBox">
<property name="spacing">8</property>
<child>
<object class="GtkLabel">
<property name="label" translatable="yes">Rotation Speed</property>
<property name="xalign">0</property>
<property name="halign">start</property>
<property name="valign">center</property>
<property name="hexpand">1</property>
</object>
</child>
<child>
<object class="GtkScale">
<property name="halign">end</property>
<property name="valign">center</property>
<property name="draw-value">1</property>
<property name="digits">2</property>
<property name="value-pos">left</property>
<property name="width-request">300</property>
<property name="adjustment">
portal-rotation-speed</property>
</object>
</child>
<child>
<object class="GtkButton"
id="reset-portal-rotation-speed">
<child>
<object class="GtkImage">
<property name="icon-name">
edit-clear-symbolic</property>
<property name="icon-size">1</property>
</object>
</child>
<property name="tooltip-text" translatable="yes">Reset to Default Value</property>
<style>
<class name="flat" />
</style>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkListBoxRow">
<property name="margin-start">10</property>
<property name="margin-end">10</property>
<property name="margin-top">10</property>
<property name="margin-bottom">10</property>
<property name="activatable">0</property>
<child>
<object class="GtkBox">
<property name="spacing">8</property>
<child>
<object class="GtkLabel">
<property name="label" translatable="yes">Whirl</property>
<property name="xalign">0</property>
<property name="halign">start</property>
<property name="valign">center</property>
<property name="hexpand">1</property>
</object>
</child>
<child>
<object class="GtkScale">
<property name="halign">end</property>
<property name="valign">center</property>
<property name="draw-value">1</property>
<property name="digits">2</property>
<property name="value-pos">left</property>
<property name="width-request">300</property>
<property name="adjustment">
portal-whirl</property>
</object>
</child>
<child>
<object class="GtkButton"
id="reset-portal-whirl">
<child>
<object class="GtkImage">
<property name="icon-name">
edit-clear-symbolic</property>
<property name="icon-size">1</property>
</object>
</child>
<property name="tooltip-text" translatable="yes">Reset to Default Value</property>
<style>
<class name="flat" />
</style>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkListBoxRow">
<property name="margin-start">10</property>
<property name="margin-end">10</property>
<property name="margin-top">10</property>
<property name="margin-bottom">10</property>
<property name="activatable">0</property>
<child>
<object class="GtkBox">
<property name="spacing">8</property>
<child>
<object class="GtkLabel">
<property name="label" translatable="yes">Details</property>
<property name="xalign">0</property>
<property name="halign">start</property>
<property name="valign">center</property>
<property name="hexpand">1</property>
</object>
</child>
<child>
<object class="GtkScale">
<property name="halign">end</property>
<property name="valign">center</property>
<property name="draw-value">1</property>
<property name="digits">1</property>
<property name="value-pos">left</property>
<property name="width-request">300</property>
<property name="adjustment">
portal-details</property>
</object>
</child>
<child>
<object class="GtkButton"
id="reset-portal-details">
<child>
<object class="GtkImage">
<property name="icon-name">
edit-clear-symbolic</property>
<property name="icon-size">1</property>
</object>
</child>
<property name="tooltip-text" translatable="yes">Reset to Default Value</property>
<style>
<class name="flat" />
</style>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkListBoxRow">
<property name="margin-start">10</property>
+145 -1
View File
@@ -46,7 +46,7 @@ SPDX-License-Identifier: GPL-3.0-or-later
<object class="GtkAdjustment"
id="portal-animation-time">
<property name="upper">5000</property>
<property name="lower">100</property>
<property name="lower">1000</property>
<property name="step-increment">1</property>
<property name="page-increment">100</property>
</object>
@@ -68,6 +68,150 @@ SPDX-License-Identifier: GPL-3.0-or-later
</object>
</child>
<child>
<object class="GtkListBoxRow">
<property name="activatable">0</property>
<child>
<object class="GtkBox">
<child>
<object class="GtkLabel">
<property name="label" translatable="yes">Whirl</property>
<property name="xalign">0</property>
<property name="halign">start</property>
<property name="valign">center</property>
<property name="hexpand">1</property>
</object>
</child>
<child>
<object class="GtkScale">
<property name="halign">end</property>
<property name="valign">center</property>
<property name="draw-value">1</property>
<property name="digits">2</property>
<property name="value-pos">left</property>
<property name="width-request">300</property>
<property name="adjustment">
<object class="GtkAdjustment"
id="portal-whirl">
<property name="upper">2</property>
<property name="lower">-2</property>
<property name="step-increment">0.1</property>
<property name="page-increment">1</property>
</object>
</property>
</object>
</child>
<child>
<object class="GtkButton"
id="reset-portal-whirl">
<property name="icon-name">edit-clear-symbolic</property>
<property name="tooltip-text" translatable="yes">Reset to Default Value</property>
<style>
<class name="flat" />
</style>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkListBoxRow">
<property name="activatable">0</property>
<child>
<object class="GtkBox">
<child>
<object class="GtkLabel">
<property name="label" translatable="yes">Rotation Speed</property>
<property name="xalign">0</property>
<property name="halign">start</property>
<property name="valign">center</property>
<property name="hexpand">1</property>
</object>
</child>
<child>
<object class="GtkScale">
<property name="halign">end</property>
<property name="valign">center</property>
<property name="draw-value">1</property>
<property name="digits">2</property>
<property name="value-pos">left</property>
<property name="width-request">300</property>
<property name="adjustment">
<object class="GtkAdjustment"
id="portal-rotation-speed">
<property name="upper">2</property>
<property name="lower">-2</property>
<property name="step-increment">0.1</property>
<property name="page-increment">1</property>
</object>
</property>
</object>
</child>
<child>
<object class="GtkButton"
id="reset-portal-rotation-speed">
<property name="icon-name">edit-clear-symbolic</property>
<property name="tooltip-text" translatable="yes">Reset to Default Value</property>
<style>
<class name="flat" />
</style>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkListBoxRow">
<property name="activatable">0</property>
<child>
<object class="GtkBox">
<child>
<object class="GtkLabel">
<property name="label" translatable="yes">Details</property>
<property name="xalign">0</property>
<property name="halign">start</property>
<property name="valign">center</property>
<property name="hexpand">1</property>
</object>
</child>
<child>
<object class="GtkScale">
<property name="halign">end</property>
<property name="valign">center</property>
<property name="draw-value">1</property>
<property name="digits">1</property>
<property name="value-pos">left</property>
<property name="width-request">300</property>
<property name="adjustment">
<object class="GtkAdjustment"
id="portal-details">
<property name="upper">100</property>
<property name="lower">1</property>
<property name="step-increment">1</property>
<property name="page-increment">10</property>
</object>
</property>
</object>
</child>
<child>
<object class="GtkButton"
id="reset-portal-details">
<property name="icon-name">edit-clear-symbolic</property>
<property name="tooltip-text" translatable="yes">Reset to Default Value</property>
<style>
<class name="flat" />
</style>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkListBoxRow">
<property name="activatable">0</property>
@@ -740,11 +740,29 @@ SPDX-License-Identifier: CC0-1.0
</key>
<key name="portal-color" type="s">
<default>"rgb(155, 255, 50)"</default>
<default>"rgb(121, 233, 24)"</default>
<summary>Portal Color</summary>
<description>The color of the effect.</description>
</key>
<key name="portal-rotation-speed" type="d">
<default>0.3</default>
<summary>Portal Rotation Speed</summary>
<description>The angular speed of the portal.</description>
</key>
<key name="portal-whirl" type="d">
<default>1.0</default>
<summary>Portal Whirl</summary>
<description>The amount of distortion.</description>
</key>
<key name="portal-details" type="d">
<default>15.0</default>
<summary>Portal Details</summary>
<description>The amount of details in the portal.</description>
</key>
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
<!-- Snap of Disintegration Effect Options -->
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+11 -2
View File
@@ -43,8 +43,11 @@ var Portal = class {
const Clutter = imports.gi.Clutter;
// Store uniform locations of newly created shaders.
shader._uColor = shader.get_uniform_location('uColor');
shader._uSeed = shader.get_uniform_location('uSeed');
shader._uColor = shader.get_uniform_location('uColor');
shader._uDetails = shader.get_uniform_location('uDetails');
shader._uRotationSpeed = shader.get_uniform_location('uRotationSpeed');
shader._uWhirl = shader.get_uniform_location('uWhirl');
// Write all uniform values at the start of each animation.
shader.connect('begin-animation', (shader, settings) => {
@@ -54,8 +57,11 @@ var Portal = class {
const testMode = settings.get_boolean('test-mode');
// clang-format off
shader.set_uniform_float(shader._uColor, 3, [c.red / 255, c.green / 255, c.blue / 255]);
shader.set_uniform_float(shader._uSeed, 2, [testMode ? 0 : Math.random(), testMode ? 0 : Math.random()]);
shader.set_uniform_float(shader._uColor, 3, [c.red / 255, c.green / 255, c.blue / 255]);
shader.set_uniform_float(shader._uDetails, 1, [settings.get_double('portal-details')]);
shader.set_uniform_float(shader._uRotationSpeed, 1, [settings.get_double('portal-rotation-speed')]);
shader.set_uniform_float(shader._uWhirl, 1, [settings.get_double('portal-whirl')]);
// clang-format on
});
});
@@ -94,6 +100,9 @@ var Portal = class {
// Bind all properties.
dialog.bindAdjustment('portal-animation-time');
dialog.bindAdjustment('portal-rotation-speed');
dialog.bindAdjustment('portal-whirl');
dialog.bindAdjustment('portal-details');
dialog.bindColorButton('portal-color');
// Finally, return the new settings page.