From f2e4f23c42268c96f962525eedcfd84e42d52322 Mon Sep 17 00:00:00 2001 From: code002lover Date: Mon, 8 Dec 2025 15:42:23 +0100 Subject: [PATCH] add second shader bg --- .../assets/{ichannel1.png => small_noise.png} | Bin frontend/src/App.tsx | 23 +- frontend/src/ShaderBackground.tsx | 31 ++- .../assets/{shader.glsl => blackhole.glsl} | 2 +- frontend/src/assets/star.glsl | 200 ++++++++++++++++++ 5 files changed, 237 insertions(+), 19 deletions(-) rename frontend/public/assets/{ichannel1.png => small_noise.png} (100%) rename frontend/src/assets/{shader.glsl => blackhole.glsl} (99%) create mode 100644 frontend/src/assets/star.glsl diff --git a/frontend/public/assets/ichannel1.png b/frontend/public/assets/small_noise.png similarity index 100% rename from frontend/public/assets/ichannel1.png rename to frontend/public/assets/small_noise.png diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index b279a8e..841f99f 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -16,15 +16,18 @@ function App() { const [token, setToken] = useState( localStorage.getItem("token") || "" ); - const [isShaderTheme, setIsShaderTheme] = useState(false); + const [theme, setTheme] = useState("default"); + const [isShaderTheme, setIsShaderTheme] = useState(false); useEffect(() => { - if (isShaderTheme) { + if (theme !== "default") { document.body.classList.add("shader-theme"); + setIsShaderTheme(true); } else { document.body.classList.remove("shader-theme"); + setIsShaderTheme(false); } - }, [isShaderTheme]); + }, [theme]); const fetchPeople = () => { if (!token) return; @@ -76,15 +79,13 @@ function App() { - + - {isShaderTheme && } + {isShaderTheme && } } /> } /> diff --git a/frontend/src/ShaderBackground.tsx b/frontend/src/ShaderBackground.tsx index b7ba933..fe9725e 100644 --- a/frontend/src/ShaderBackground.tsx +++ b/frontend/src/ShaderBackground.tsx @@ -1,6 +1,7 @@ import { useEffect, useRef } from "react"; -import SHADER_CODE from "./assets/shader.glsl?raw"; +import BLACKHOLE_SHADER_CODE from "./assets/blackhole.glsl?raw"; +import STAR_SHADER_CODE from "./assets/star.glsl?raw"; function buildProgram( ctx: WebGL2RenderingContext, @@ -112,8 +113,11 @@ function isPowerOf2(value: number) { return (value & (value - 1)) === 0; } +type ShaderBackgroundProps = { + theme: string; +}; -export const ShaderBackground = () => { +export const ShaderBackground: React.FC = ({ theme }) => { const canvasRef = useRef(null); useEffect(() => { @@ -127,12 +131,25 @@ export const ShaderBackground = () => { gl.clearColor(0, 0, 0, 1); gl.clear(gl.COLOR_BUFFER_BIT); - const shader = buildShader(gl, gl.FRAGMENT_SHADER, SHADER_CODE); + let shader_code; + switch (theme) { + case "blackhole": + shader_code = BLACKHOLE_SHADER_CODE; + break; + case "star": + shader_code = STAR_SHADER_CODE; + break; + default: + console.error("Unknown shader theme:", theme); + return; + } + + const shader = buildShader(gl, gl.FRAGMENT_SHADER, shader_code); const vertexShader = buildShader( gl, gl.VERTEX_SHADER, `#version 300 es - precision lowp float; + precision highp float; in vec2 a_position; @@ -172,7 +189,7 @@ export const ShaderBackground = () => { const final_iChannel1 = gl.getUniformLocation(finalProgram, "iChannel1"); - const ichannel1_texture = loadTexture(gl, "assets/ichannel1.png"); + const ichannel1_texture = loadTexture(gl, "assets/small_noise.png"); gl!.viewport(0, 0, canvas!.width, canvas!.height); @@ -186,7 +203,7 @@ export const ShaderBackground = () => { function update(now: number) { // time in seconds - const time = (now) / 1000; + const time = now / 1000; gl!.clear(gl!.COLOR_BUFFER_BIT); setTime(finalProgram!, time); @@ -197,7 +214,7 @@ export const ShaderBackground = () => { } requestAnimationFrame(update); - }); + }, [theme]); return ( r) { + n = noise4q(vec4(pr * 10.0f, -anim + c)); + ns = noise4q(vec4(pr * 50.0f, -anim * 2.5f + c * 2.0f)) * 2.0f; + } + n = n * n * nd * ns; + + return pow(s, 4.0f) + s * s * n; +} + +vec4 noiseSpace(vec3 ray, vec3 pos, float r, mat3 mr, float zoom, vec3 subnoise, float anim) { + float b = dot(ray, pos); + float c = dot(pos, pos) - b * b; + + vec3 r1 = vec3(0.0f); + + float s = 0.0f; + float d = 0.0625f * 1.5f; + float d2 = zoom / d; + + float rq = r * r; + float l1 = sqrt(abs(rq - c)); + r1 = (ray * (b - l1) - pos) * mr; + + r1 *= d2; + s += abs(noise4q(vec4(r1 + subnoise, anim)) * d); + s += abs(noise4q(vec4(r1 * 0.5f + subnoise, anim)) * d * 2.0f); + s += abs(noise4q(vec4(r1 * 0.25f + subnoise, anim)) * d * 4.0f); + //return s; + return vec4(s * 2.0f, abs(noise4q(vec4(r1 * 0.1f + subnoise, anim))), abs(noise4q(vec4(r1 * 0.1f + subnoise * 6.0f, anim))), abs(noise4q(vec4(r1 * 0.1f + subnoise * 13.0f, anim)))); +} + +float sphereZero(vec3 ray, vec3 pos, float r) { + float b = dot(ray, pos); + float c = dot(pos, pos) - b * b; + float s = 1.0f; + if(c < r * r) + s = 0.0f; + return s; +} + +void mainImage(out vec4 fragColor, in vec2 fragCoord) { + vec2 p = (-iResolution.xy + 2.0f * fragCoord.xy) / iResolution.y; + + float time = iTime * 1.0f; + + float mx = time * 0.025f; + float my = -0.6f; + vec2 rotate = vec2(mx, my); + + vec2 sins = sin(rotate); + vec2 coss = cos(rotate); + mat3 mr = mat3(vec3(coss.x, 0.0f, sins.x), vec3(0.0f, 1.0f, 0.0f), vec3(-sins.x, 0.0f, coss.x)); + mr = mat3(vec3(1.0f, 0.0f, 0.0f), vec3(0.0f, coss.y, sins.y), vec3(0.0f, -sins.y, coss.y)) * mr; + + mat3 imr = mat3(vec3(coss.x, 0.0f, -sins.x), vec3(0.0f, 1.0f, 0.0f), vec3(sins.x, 0.0f, coss.x)); + imr = imr * mat3(vec3(1.0f, 0.0f, 0.0f), vec3(0.0f, coss.y, -sins.y), vec3(0.0f, sins.y, coss.y)); + + vec3 ray = normalize(vec3(p, 2.0f)); + vec3 pos = vec3(0.0f, 0.0f, 3.0f); + + float s1 = noiseSpere(ray, pos, 1.0f, mr, 0.5f, vec3(0.0f), time); + s1 = pow(min(1.0f, s1 * 2.4f), 2.0f); + float s2 = noiseSpere(ray, pos, 1.0f, mr, 4.0f, vec3(83.23f, 34.34f, 67.453f), time); + s2 = min(1.0f, s2 * 2.2f); + fragColor = vec4(mix(vec3(1.0f, 1.0f, 0.0f), vec3(1.0f), pow(s1, 60.0f)) * s1, 1.0f); + fragColor += vec4(mix(mix(vec3(1.0f, 0.0f, 0.0f), vec3(1.0f, 0.0f, 1.0f), pow(s2, 2.0f)), vec3(1.0f), pow(s2, 10.0f)) * s2, 1.0f); + + fragColor.xyz -= vec3(ring(ray, pos, 1.03f, 11.0f)) * 2.0f; + fragColor = max(vec4(0.0f), fragColor); + + float s3 = ringRayNoise(ray, pos, 0.96f, 1.0f, mr, time); + fragColor.xyz += mix(vec3(1.0f, 0.6f, 0.1f), vec3(1.0f, 0.95f, 1.0f), pow(s3, 3.0f)) * s3; + + float zero = sphereZero(ray, pos, 0.9f); + if(zero > 0.0f) { + + vec4 s4 = noiseSpace(ray, pos, 100.0f, mr, 0.05f, vec3(1.0f, 2.0f, 4.0f), 0.0f); + + s4.x = pow(s4.x, 3.0f); + + fragColor.xyz += mix(mix(vec3(1.0f, 0.0f, 0.0f), vec3(0.0f, 0.0f, 1.0f), s4.y * 1.9f), vec3(0.9f, 1.0f, 0.1f), s4.w * 0.75f) * s4.x * pow(s4.z * 2.5f, 3.0f) * 0.2f * zero; + + } + + fragColor = max(vec4(0.0f), fragColor); + fragColor = min(vec4(1.0f), fragColor); +} + +void main() { + mainImage(FragColor, gl_FragCoord.xy); +} \ No newline at end of file