forked from BRETT/BRETT
Initial Commit
This commit is contained in:
@@ -0,0 +1,152 @@
|
||||
<script setup lang="ts">
|
||||
import { hexToRgbTuple, shadeHex } from '@/lib/color'
|
||||
|
||||
// Portiert aus Vue Bits (DavidHDev/vue-bits), vereinfacht auf color-Prop,
|
||||
// Blur-Post-Pass entfernt (blur: 0 war Standard)
|
||||
const props = withDefaults(defineProps<{ color?: string }>(), {
|
||||
color: '#6366f1',
|
||||
})
|
||||
|
||||
const VERT = `#version 300 es
|
||||
in vec2 position;
|
||||
void main() {
|
||||
gl_Position = vec4(position, 0.0, 1.0);
|
||||
}
|
||||
`
|
||||
|
||||
const FRAG = `#version 300 es
|
||||
precision highp float;
|
||||
uniform float iTime;
|
||||
uniform float uSpeed;
|
||||
uniform float uWaveDepth;
|
||||
uniform float uZoom;
|
||||
uniform float uDensity;
|
||||
uniform float uSpread;
|
||||
uniform float uStepSize;
|
||||
uniform float uGlow;
|
||||
uniform float uExposure;
|
||||
uniform float uColorShift;
|
||||
uniform float uContrast;
|
||||
uniform float uBrightness;
|
||||
uniform float uOpacity;
|
||||
uniform float uSteps;
|
||||
uniform vec3 uColor1;
|
||||
uniform vec3 uColor2;
|
||||
uniform vec3 uColor3;
|
||||
uniform vec2 uMouse;
|
||||
uniform float uMouseStrength;
|
||||
uniform float uMouseRadius;
|
||||
uniform float uMouseActive;
|
||||
uniform float uGrainIntensity;
|
||||
uniform vec2 uCardRes;
|
||||
uniform float uRadius;
|
||||
out vec4 fragColor;
|
||||
|
||||
float cardMask(vec2 fc) {
|
||||
vec2 p = fc - uCardRes * 0.5;
|
||||
vec2 hb = uCardRes * 0.5 - vec2(uRadius);
|
||||
float rd = length(max(abs(p) - hb, 0.0)) - uRadius;
|
||||
return 1.0 - smoothstep(-0.75, 0.75, rd);
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec2 frag = gl_FragCoord.xy;
|
||||
float zoom = max(uZoom, 0.05);
|
||||
// Pixelkonsistent: Referenzhöhe 180px, damit die Zellen in flachen
|
||||
// Containern ihre reale Pixelgröße behalten statt zu stauchen
|
||||
vec2 ndc = (2.0 * frag - uCardRes.xy) / 180.0;
|
||||
vec2 dir = ndc * (0.5 / zoom);
|
||||
|
||||
vec2 mouseNdc = uMouse * (uCardRes / 360.0);
|
||||
float mr = max(uMouseRadius, 0.01);
|
||||
vec2 md = ndc - mouseNdc;
|
||||
float dent = exp(-dot(md, md) / (mr * mr)) * (3.0 * uMouseStrength * uMouseActive);
|
||||
|
||||
float travel = sin(iTime * uSpeed) * uWaveDepth;
|
||||
float density = max(uDensity, 1.0);
|
||||
float spread = clamp(uSpread, 0.05, 0.6);
|
||||
float stepSize = max(uStepSize, 0.0005);
|
||||
float glowGain = max(uGlow, 0.0);
|
||||
|
||||
vec3 tOffset = vec3(0.0, dent, travel);
|
||||
vec3 p = vec3(0.0);
|
||||
float s = 0.0;
|
||||
float glow = 0.0;
|
||||
|
||||
for (int i = 0; i < 64; i++) {
|
||||
if (float(i) >= uSteps) break;
|
||||
p += vec3(dir * s, s);
|
||||
vec3 q = p + tOffset;
|
||||
s += density - length(q.xz) + length(ceil(q).xy);
|
||||
s = stepSize + abs(s) * spread;
|
||||
glow += glowGain / s;
|
||||
}
|
||||
|
||||
float e = glow / max(uExposure, 1.0);
|
||||
float shimmer = 0.5 + 0.5 * dot(cos(iTime * uColorShift + p), vec3(0.3333));
|
||||
float v = tanh(e * uBrightness * mix(0.7, 1.05, shimmer));
|
||||
v = clamp((v - 0.5) * uContrast + 0.5, 0.0, 1.0);
|
||||
|
||||
vec3 col = mix(uColor1, uColor2, smoothstep(0.0, 0.55, v));
|
||||
col = mix(col, uColor3, smoothstep(0.55, 1.0, v));
|
||||
col *= v;
|
||||
|
||||
float a = clamp(v, 0.0, 1.0) * uOpacity;
|
||||
vec3 outRgb = col;
|
||||
if (a > 0.01) {
|
||||
float gv = (fract(sin(dot(gl_FragCoord.xy, vec2(12.9898, 78.233)) + iTime) * 43758.5453) - 0.5) * uGrainIntensity;
|
||||
outRgb = clamp(outRgb + gv, 0.0, 1.0);
|
||||
a = clamp(a + gv, 0.0, 1.0);
|
||||
}
|
||||
|
||||
a *= cardMask(frag);
|
||||
fragColor = vec4(outRgb * a, a);
|
||||
}
|
||||
`
|
||||
|
||||
const ctnDom = ref<HTMLDivElement | null>(null)
|
||||
|
||||
useCardShader(ctnDom, {
|
||||
vertex: VERT,
|
||||
fragment: FRAG,
|
||||
mouse: true,
|
||||
uniforms: {
|
||||
iTime: { value: 0 },
|
||||
uSpeed: { value: 0.7 },
|
||||
uWaveDepth: { value: 1 },
|
||||
uZoom: { value: 1.3 },
|
||||
uDensity: { value: 10.0 },
|
||||
uSpread: { value: 0.3 },
|
||||
uStepSize: { value: 0.002 },
|
||||
uGlow: { value: 1.0 },
|
||||
uExposure: { value: 2700 },
|
||||
uColorShift: { value: 0 },
|
||||
uContrast: { value: 1 },
|
||||
uBrightness: { value: 1.0 },
|
||||
uOpacity: { value: 1.0 },
|
||||
uSteps: { value: 32 },
|
||||
uColor1: { value: new Float32Array(hexToRgbTuple(shadeHex(props.color, -0.35))) },
|
||||
uColor2: { value: new Float32Array(hexToRgbTuple(props.color)) },
|
||||
uColor3: { value: new Float32Array([1, 1, 1]) },
|
||||
uMouse: { value: new Float32Array([0, 0]) },
|
||||
uMouseStrength: { value: 0.1 },
|
||||
uMouseRadius: { value: 0.35 },
|
||||
uMouseActive: { value: 0 },
|
||||
uGrainIntensity: { value: 0.05 },
|
||||
},
|
||||
color: () => props.color,
|
||||
colorUniforms: { uColor1: -0.35, uColor2: 0 },
|
||||
frame: ({ t, program, mouse }) => {
|
||||
const u = program.uniforms
|
||||
u.iTime.value = t * 0.001
|
||||
const m = u.uMouse.value as Float32Array
|
||||
m[0] = mouse.x * 2 - 1
|
||||
m[1] = mouse.y * 2 - 1
|
||||
u.uMouseActive.value = mouse.active
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div ref="ctnDom" class="relative size-full overflow-hidden rounded-[inherit]" />
|
||||
</template>
|
||||
Reference in New Issue
Block a user