0.00
60.0 fps
Portal / Void
Fully customizable
Log in to post a comment.
#version 300 es
precision highp float;
uniform float iTime;
uniform vec2 iResolution;
// ==== BASE EFFECT ====
uniform float angleDensity; // value=3.0, min=1.0, max=20.0, step=0.01
uniform float distanceDensity; // value=1.0, min=0.0, max=20.0, step=0.01
uniform float spotBrightness; // value=0.3, min=0.0, max=2.0, step=0.01
uniform float brightness; // value=0.3, min=0.0, max=2.0, step=0.01
uniform float contrast; // value=1.0, min=0.0, max=4.0, step=0.01
uniform float velocity; // value=0.2, min=-2.0, max=2.0, step=0.01
// ==== EFFECT COLORS ====
uniform vec3 colorInner; // value=1.0,0.4,0.9
uniform vec3 colorOuter; // value=0.2,0.7,1.0
// ==== BACKGROUND ====
uniform vec3 bgInner; // value=0.04,0.02,0.08
uniform vec3 bgOuter; // value=0.00,0.00,0.01
uniform float bgGradientPower; // value=1.0, min=0.1, max=4.0, step=0.01
// ==== ANIMATION / MOTION ====
uniform float rotationSpeed; // value=0.15, min=-5.0, max=5.0, step=0.01
uniform float pulseSpeed; // value=1.5, min=0.0, max=10.0, step=0.01
uniform float pulseAmount; // value=0.12, min=0.0, max=1.0, step=0.01
// ==== DISTORTION ====
uniform float distortAmount; // value=0.03, min=0.0, max=0.5, step=0.001
uniform float distortScale; // value=8.0, min=0.1, max=40.0, step=0.01
uniform float distortSpeed; // value=1.0, min=-10.0,max=10.0, step=0.01
// ==== RINGS / SHOCK WAVES ====
uniform float ringStrength; // value=0.15, min=0.0, max=2.0, step=0.01
uniform float ringScale; // value=18.0, min=0.1, max=80.0, step=0.01
uniform float ringSpeed; // value=2.0, min=-20.0,max=20.0, step=0.01
uniform float ringSharpness; // value=3.0, min=1.0, max=16.0, step=0.01
// ==== STAR / ANGULAR FLARE ====
uniform float starStrength; // value=0.12, min=0.0, max=2.0, step=0.01
uniform float starArms; // value=4.0, min=1.0, max=12.0, step=0.01
uniform float starSharpness; // value=10.0, min=1.0, max=40.0, step=0.01
// ==== DETAILS LAYER ====
uniform float detailStrength; // value=0.35, min=0.0, max=2.0, step=0.01
uniform float detailScale; // value=2.5, min=0.1, max=10.0, step=0.01
uniform float detailSpeed; // value=0.3, min=-5.0, max=5.0, step=0.01
// ==== FINISHING ====
uniform float bloomBoost; // value=0.8, min=0.0, max=4.0, step=0.01
uniform float vignette; // value=0.25, min=0.0, max=2.0, step=0.01
uniform float saturation; // value=1.1, min=0.0, max=3.0, step=0.01
in vec2 vScreen;
out vec4 fragColor;
// ------------------------------------------------------------
// Hash without Sine (David Hoskins)
// ------------------------------------------------------------
float hash13(vec3 p3) {
p3 = fract(p3 * 0.1031);
p3 += dot(p3, p3.yzx + 33.33);
return fract((p3.x + p3.y) * p3.z);
}
float noise(vec3 x) {
vec3 p = floor(x);
vec3 f = smoothstep(0.0, 1.0, fract(x));
return mix(
mix(
mix(hash13(p + vec3(0,0,0)), hash13(p + vec3(1,0,0)), f.x),
mix(hash13(p + vec3(0,1,0)), hash13(p + vec3(1,1,0)), f.x),
f.y
),
mix(
mix(hash13(p + vec3(0,0,1)), hash13(p + vec3(1,0,1)), f.x),
mix(hash13(p + vec3(0,1,1)), hash13(p + vec3(1,1,1)), f.x),
f.y
),
f.z
);
}
const mat3 m3 = mat3(
-0.7373, 0.4562, 0.4980,
0.0000, -0.7373, 0.6754,
0.6754, 0.4980, 0.5437
) * 2.0;
float fbm(vec3 p) {
float a = 1.0;
float n = 0.0;
for (int i = 0; i < 5; i++) {
n += abs(noise(p) * 2.0 - 1.0) * a;
a *= 0.5;
p *= m3;
}
return n;
}
mat2 rot2(float a) {
float s = sin(a);
float c = cos(a);
return mat2(c, -s, s, c);
}
vec3 saturateColor(vec3 c, float sat) {
float luma = dot(c, vec3(0.299, 0.587, 0.114));
return mix(vec3(luma), c, sat);
}
void main() {
vec2 uv = vScreen; // предполагается диапазон примерно [-1..1]
float r = length(uv);
float rr = max(r * r, 1e-4);
// --- Rotation ---
vec2 uvRot = rot2(iTime * rotationSpeed) * uv;
// --- Distortion (subtle heat/plasma wobble) ---
vec2 duv = uvRot;
duv += vec2(
sin(uvRot.y * distortScale + iTime * distortSpeed),
cos(uvRot.x * distortScale - iTime * distortSpeed)
) * distortAmount;
float rd = length(duv);
vec2 dir = (rd > 1e-6) ? normalize(duv) : vec2(0.0);
// --- Base noise field ---
float zBase = rd * distanceDensity - iTime * velocity;
float f1 = fbm(vec3(dir * angleDensity, zBase));
// --- Detail layer (finer animated turbulence) ---
float f2 = fbm(vec3(dir * angleDensity * detailScale, zBase * detailScale + iTime * detailSpeed));
float f = f1 + detailStrength * f2;
// --- Pulse ("breathing") ---
float pulse = 1.0 + sin(iTime * pulseSpeed) * pulseAmount;
f *= pulse;
// --- Radial energy shaping ---
f = (f * f) / rr;
f += spotBrightness / rr;
// --- Shock rings ---
// ring signal strongest on bright areas; optional radial wave
float rings = sin(rd * ringScale - iTime * ringSpeed);
rings = pow(max(rings, 0.0), max(ringSharpness, 1.0)) * ringStrength;
f += rings / (1.0 + rd * 2.0);
// --- Angular star flare ---
float ang = atan(duv.y, duv.x);
float arms = max(starArms, 1.0);
float star = pow(abs(cos(ang * arms)), max(starSharpness, 1.0)) * starStrength;
f += star / rr;
// --- Global brightness ---
f *= brightness;
f = max(f, 0.0);
// --- Background gradient (behind the effect) ---
float bgT = pow(clamp(smoothstep(0.0, 1.25, r), 0.0, 1.0), max(bgGradientPower, 0.001));
vec3 bg = mix(bgInner, bgOuter, bgT);
// --- Radial color gradient for the glow itself ---
float colorT = clamp(smoothstep(0.0, 1.0, r), 0.0, 1.0);
vec3 glowColor = mix(colorInner, colorOuter, colorT);
// --- Tone response for the effect ---
vec3 effect = 1.0 - exp(-glowColor * pow(f, max(contrast, 0.001)));
effect = clamp(effect, 0.0, 1.0);
// --- Cheap bloom-like boost on hot areas ---
vec3 hot = effect * effect * bloomBoost;
effect = clamp(effect + hot, 0.0, 1.0);
// --- Composite: background behind shader ---
float effectMask = clamp(max(effect.r, max(effect.g, effect.b)), 0.0, 1.0);
vec3 col = mix(bg, effect, effectMask);
// --- Saturation ---
col = saturateColor(col, saturation);
// --- Vignette ---
float vig = 1.0 - smoothstep(0.35, 1.35, r) * vignette;
col *= clamp(vig, 0.0, 1.0);
fragColor = vec4(clamp(col, 0.0, 1.0), 1.0);
}