@gregermendle
#extension GL_OES_standard_derivatives : enableprecision highp float;uniform float time;uniform vec2 resolution;uniform vec2 mouse;const float PI = 3.14159;// Fresnel calculationfloat fresnel(vec3 normal, vec3 viewDir, float power) { return pow(1.0 - max(0.0, dot(normal, viewDir)), power);}void main() { // Normalize coordinates to center with aspect ratio correction float aspect = resolution.x / resolution.y; vec2 uv = (gl_FragCoord.xy * 2.0 - resolution.xy) / min(resolution.x, resolution.y); // Circle properties float angle = atan(uv.y, uv.x); float radius = 0.5 + 0.02 * sin(angle + 1.5 * pow(dot(vec3(uv, 2.2), vec3(0.9, -0.9, 1.)), 2.) + time * 2.0); float dist = length(uv); // Early discard for performance if (dist > radius + 0.1) { gl_FragColor = vec4(.0); return; } // Calculate surface normal vec3 normal = normalize(vec3(uv, sqrt(max(0.0, radius * radius - dist * dist)))); // View direction (straight on) vec3 viewDir = normalize(vec3(0.0, 0.0, 1.0)); // Calculate fresnel effect float fresnelPower = 0.1; // Adjust for stronger/weaker effect float fresnelTerm = fresnel(normal, viewDir, fresnelPower); // Base color and fresnel color vec3 baseColor = vec3(0.1, 0.9, 0.02); // Dark blue-ish base vec3 fresnelColor = baseColor + 0.1; // White rim light // Mix colors based on fresnel vec3 color = mix(baseColor, fresnelColor, fresnelTerm); // Add slight inner glow float innerGlow = smoothstep(radius, 0.0, dist) * 1.9; color -= vec3(innerGlow); // Fade out the edges smoothly float alpha = smoothstep(radius + 0.01, radius - 0.1, dist); // Output final color gl_FragColor = vec4(color, alpha);}
@gregermendle
vewy nice actors read: https://ryhl.io/blog/actors-with-tokio/
@Chacal
Hey Greg, which language did you use to build this platform, and what tools were used?
Bro, aren’t the costs too high?
right now this app runs completely free on fly and SES. The only thing that I pay for is the storage bucket lol, which right now is a penny each month.
@gregermendle
#extension GL_OES_standard_derivatives : enableprecision highp float;uniform float time;uniform vec2 mouse;uniform vec2 resolution;#define PI 3.14159265358979323846float rand(vec2 c){ return fract(sin(dot(c.xy ,vec2(12.9898,78.233))) * 43758.5453);}float noise(vec2 p, float freq ){ float unit = resolution.x/freq; vec2 ij = floor(p/unit); vec2 xy = mod(p,unit)/unit; //xy = 3.*xy*xy-2.*xy*xy*xy; xy = .5*(1.-cos(PI*xy)); float a = rand((ij+vec2(0.,0.))); float b = rand((ij+vec2(1.,0.))); float c = rand((ij+vec2(0.,1.))); float d = rand((ij+vec2(1.,1.))); float x1 = mix(a, b, xy.x); float x2 = mix(c, d, xy.x); return mix(x1, x2, xy.y);}float pNoise(vec2 p, int res){ float persistance = .5; float n = 0.4; float normK = 0.; float f = 4.; float amp = 1.; int iCount = 0; for (int i = 0; i<50; i++){ n+=amp*noise(p, f); f*=2.; normK+=amp; amp*=persistance; if (iCount == res) break; iCount++; } float nf = n/normK; return nf*nf*nf*nf;}void main( void ) { vec2 c = gl_FragCoord.xy / 2.; float t = time; t *= 0.5; float a = tan(((c.y * c.x) + t)) - sin(t); gl_FragColor = vec4(0.4,0.4,0.1, a) / 2.;}
@gregermendle
#ifdef GL_ESprecision highp float;#endifuniform float time;uniform vec2 resolution;// Simplex noise functionvec3 mod289(vec3 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; }vec4 mod289(vec4 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; }vec4 permute(vec4 x) { return mod289(((x*34.0)+1.0)*x); }vec4 taylorInvSqrt(vec4 r) { return 1.79284291400159 - 0.85373472095314 * r; }float snoise(vec3 v) { const vec2 C = vec2(1.0/6.0, 1.0/3.0); const vec4 D = vec4(0.0, 0.5, 1.0, 2.0); vec3 i = floor(v + dot(v, C.yyy)); vec3 x0 = v - i + dot(i, C.xxx); vec3 g = step(x0.yzx, x0.xyz); vec3 l = 1.0 - g; vec3 i1 = min(g.xyz, l.zxy); vec3 i2 = max(g.xyz, l.zxy); vec3 x1 = x0 - i1 + C.xxx; vec3 x2 = x0 - i2 + C.yyy; vec3 x3 = x0 - D.yyy; i = mod289(i); vec4 p = permute(permute(permute( i.z + vec4(0.0, i1.z, i2.z, 1.0)) + i.y + vec4(0.0, i1.y, i2.y, 1.0)) + i.x + vec4(0.0, i1.x, i2.x, 1.0)); float n_ = 0.142857142857; vec3 ns = n_ * D.wyz - D.xzx; vec4 j = p - 49.0 * floor(p * ns.z * ns.z); vec4 x_ = floor(j * ns.z); vec4 y_ = floor(j - 7.0 * x_); vec4 x = x_ *ns.x + ns.yyyy; vec4 y = y_ *ns.x + ns.yyyy; vec4 h = 1.0 - abs(x) - abs(y); vec4 b0 = vec4(x.xy, y.xy); vec4 b1 = vec4(x.zw, y.zw); vec4 s0 = floor(b0)*2.0 + 1.0; vec4 s1 = floor(b1)*2.0 + 1.0; vec4 sh = -step(h, vec4(0.0)); vec4 a0 = b0.xzyw + s0.xzyw*sh.xxyy; vec4 a1 = b1.xzyw + s1.xzyw*sh.zzww; vec3 p0 = vec3(a0.xy, h.x); vec3 p1 = vec3(a0.zw, h.y); vec3 p2 = vec3(a1.xy, h.z); vec3 p3 = vec3(a1.zw, h.w); vec4 norm = taylorInvSqrt(vec4(dot(p0,p0), dot(p1,p1), dot(p2, p2), dot(p3,p3))); p0 *= norm.x; p1 *= norm.y; p2 *= norm.z; p3 *= norm.w; vec4 m = max(0.6 - vec4(dot(x0,x0), dot(x1,x1), dot(x2,x2), dot(x3,x3)), 0.0); m = m * m; return 42.0 * dot(m*m, vec4(dot(p0,x0), dot(p1,x1), dot(p2,x2), dot(p3,x3)));}void main() { vec2 uv = gl_FragCoord.xy / resolution.xy; vec2 pos = uv * 2.0 - 1.0; pos.x *= resolution.x / resolution.y; float time = time * 0.4; // Basic flocking behavior vec3 flockPos = vec3(pos * 1.0, time); float flockNoise = snoise(flockPos) * 0.9 + 0.1; // Add some swirling motion vec2 swirl = vec2( sin(pos.y * 3.0 + time) * 0.3, cos(pos.x * 3.0 + time) * 0.3 ); pos += swirl; // Generate multiple layers of noise float n1 = snoise(vec3(pos * 1.0, time * 0.5)) * 0.5 + 0.5; float n2 = snoise(vec3(pos * 5.0, time * 0.7)) * 0.25 + 0.25; float n3 = snoise(vec3(pos * 10.0, time * 0.9)) * 0.125 + 0.125; // Combine noise layers float finalNoise = n1 + n2 + n3; // Apply flocking influence finalNoise = mix(finalNoise, flockNoise, 0.4); // Threshold and smooth the result float threshold = 0.5; finalNoise = smoothstep(threshold - 0.3, threshold + 0.1, finalNoise); // Output color vec3 color = vec3(finalNoise); gl_FragColor = vec4(color, 1.0);}
@gregermendle
#extension GL_OES_standard_derivatives : enableprecision highp float;uniform float time;uniform vec2 mouse;uniform vec2 resolution;#define PI 3.14159265358979323846float rand(vec2 c){ return fract(sin(dot(c.xy ,vec2(12.9898,78.233))) * 43758.5453);}float noise(vec2 p, float freq ){ float unit = resolution.x/freq; vec2 ij = floor(p/unit); vec2 xy = mod(p,unit)/unit; //xy = 3.*xy*xy-2.*xy*xy*xy; xy = .5*(1.-cos(PI*xy)); float a = rand((ij+vec2(0.,0.))); float b = rand((ij+vec2(1.,0.))); float c = rand((ij+vec2(0.,1.))); float d = rand((ij+vec2(1.,1.))); float x1 = mix(a, b, xy.x); float x2 = mix(c, d, xy.x); return mix(x1, x2, xy.y);}float pNoise(vec2 p, int res){ float persistance = .5; float n = 0.4; float normK = 0.; float f = 4.; float amp = 1.; int iCount = 0; for (int i = 0; i<50; i++){ n+=amp*noise(p, f); f*=2.; normK+=amp; amp*=persistance; if (iCount == res) break; iCount++; } float nf = n/normK; return nf*nf*nf*nf;}void main( void ) { float n = cos(((gl_FragCoord.y * gl_FragCoord.x) + time)); float a = tan(((gl_FragCoord.y * gl_FragCoord.x) + time)); float b = cos(((gl_FragCoord.y * gl_FragCoord.x) + time)); gl_FragColor = vec4(n,n * b,n * b, a);}
@gregermendle
div { position: relative; background-color: #0a0a0a; width: 100px; height: 100px; border-radius: 30px; border: 1px solid #262626; background-image: radial-gradient(ellipse at bottom left, #121212, #0a0a0a 50%); box-shadow: inset rgba(255, 255, 255, 0.2) -5px 5px 10px, inset rgba(0, 0, 0, 0.6) 5px -5px 10px;}div::before { content: ""; position: absolute; z-index: 1; top: -1px; right: -1px; height: 30px; width: 45px; background-repeat: no-repeat; background-size: contain; background-image: url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjgiIGhlaWdodD0iMTkiIHZpZXdCb3g9IjAgMCAyOCAxOSIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPGcgZmlsdGVyPSJ1cmwoI2ZpbHRlcjBfZl81ODZfMTIzKSI+CjxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBkPSJNMTEuMzQ4OCA2QzE4LjUyODUgNiAyNC4zNDg4IDEwLjQ3NzIgMjQuMzQ4OCAxNkMyNC4zNDg4IDguODIwMyAxOC41Mjg1IDMgMTEuMzQ4OCAzSDNWNkgxMS4zNDg4WiIgZmlsbD0idXJsKCNwYWludDBfcmFkaWFsXzU4Nl8xMjMpIi8+CjwvZz4KPGRlZnM+CjxmaWx0ZXIgaWQ9ImZpbHRlcjBfZl81ODZfMTIzIiB4PSIwLjMiIHk9IjAuMyIgd2lkdGg9IjI2Ljc0ODYiIGhlaWdodD0iMTguNCIgZmlsdGVyVW5pdHM9InVzZXJTcGFjZU9uVXNlIiBjb2xvci1pbnRlcnBvbGF0aW9uLWZpbHRlcnM9InNSR0IiPgo8ZmVGbG9vZCBmbG9vZC1vcGFjaXR5PSIwIiByZXN1bHQ9IkJhY2tncm91bmRJbWFnZUZpeCIvPgo8ZmVCbGVuZCBtb2RlPSJub3JtYWwiIGluPSJTb3VyY2VHcmFwaGljIiBpbjI9IkJhY2tncm91bmRJbWFnZUZpeCIgcmVzdWx0PSJzaGFwZSIvPgo8ZmVHYXVzc2lhbkJsdXIgc3RkRGV2aWF0aW9uPSIxLjM1IiByZXN1bHQ9ImVmZmVjdDFfZm9yZWdyb3VuZEJsdXJfNTg2XzEyMyIvPgo8L2ZpbHRlcj4KPHJhZGlhbEdyYWRpZW50IGlkPSJwYWludDBfcmFkaWFsXzU4Nl8xMjMiIGN4PSIwIiBjeT0iMCIgcj0iMSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIGdyYWRpZW50VHJhbnNmb3JtPSJ0cmFuc2xhdGUoMjMuODYzNiAzLjY0NDg0KSByb3RhdGUoMTM3LjMzNCkgc2NhbGUoMjMuMDA4OSAxNC43MzgpIj4KPHN0b3Agc3RvcC1jb2xvcj0id2hpdGUiLz4KPHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSJ3aGl0ZSIgc3RvcC1vcGFjaXR5PSIwIi8+CjwvcmFkaWFsR3JhZGllbnQ+CjwvZGVmcz4KPC9zdmc+');}
@gregermendle
ok so a few people have joined and i really appreciate that. i honestly didnt think anyone would so i haven't worked on this for a few months (also am unemployed so ya know, searching for jobies.)
what would you use something like this for? the main reason i made this months and months ago was to be able to post software related stuff with code blocks lol. mainly inspired by people posting code in plain text on twitter, or just images of code you cant interact with.
again, thanks to everyone who has joined :)
@Chacal
whoa they have a really nice site. will take a look. im currently using SES and its giving my a belly ache
@alextingworld
shadcn is goated dont worry
shads nutty, huge fan, every project as of yet has been made using shad and a design system has become less of a worry.
@gregermendle
my gorsh, apparently when you use hono and openapi you can only use zod string for query parameters. https://github.com/honojs/middleware/issues/200
/*** {* query: QueryParamsSchema,* }*/const QueryParamsSchema = z.object({ page: z .string() .optional() .openapi({ param: { name: "page", in: "query", }, description: "The page you would like to view.", example: "1", })});
looks like you can also use a transform which gives the correct type:
const QueryParamsSchema = z.object({ page: ...transform((p) => parseInt(p))});
@gregermendle
running postcss and tailwindcss programmatically from this github discussion
const tailwind = require("tailwindcss");const postcss = require("postcss");const html = '<div class="bg-red-300"></div>';(async () => { const result = await postcss([ tailwind({ //...config, content: [{ raw: html, extension: "html" }], }), ]).process(`@tailwind base;@tailwind components;@tailwind utilities;`, { from: undefined, }); console.log(result.css);})();
@gregermendle
in case anyone wants to use geist
but not in next:
@font-face { src: url(/fonts/geist-sans/Geist-Thin.woff2) format("woff2"); font-weight: 100; font-style: normal; font-family: "Geist"; font-display: swap;}@font-face { src: url(/fonts/geist-sans/Geist-UltraLight.woff2) format("woff2"); font-weight: 200; font-style: normal; font-family: "Geist"; font-display: swap;}@font-face { src: url(/fonts/geist-sans/Geist-Light.woff2) format("woff2"); font-weight: 300; font-style: normal; font-family: "Geist"; font-display: swap;}@font-face { src: url(/fonts/geist-sans/Geist-Regular.woff2) format("woff2"); font-weight: 400; font-style: normal; font-family: "Geist"; font-display: swap;}@font-face { src: url(/fonts/geist-sans/Geist-Medium.woff2) format("woff2"); font-weight: 500; font-style: normal; font-family: "Geist"; font-display: swap;}@font-face { src: url(/fonts/geist-sans/Geist-SemiBold.woff2) format("woff2"); font-weight: 600; font-style: normal; font-family: "Geist"; font-display: swap;}@font-face { src: url(/fonts/geist-sans/Geist-Bold.woff2) format("woff2"); font-weight: 700; font-style: normal; font-family: "Geist"; font-display: swap;}@font-face { src: url(/fonts/geist-sans/Geist-Black.woff2) format("woff2"); font-weight: 800; font-style: normal; font-family: "Geist"; font-display: swap;}@font-face { src: url(/fonts/geist-sans/Geist-UltraBlack.woff2) format("woff2"); font-weight: 900; font-style: normal; font-family: "Geist"; font-display: swap;}
@gregermendle
i made avatar service for my other project: https://riptar.gregermendle.com/