🔥🔥🔥
quoting
naddr1qq…2wmkBrief intro
#glostr is a pet-project of mine to better understand how #nostr works. Since I'm an engineer, and somewhere between a game programmer and a graphics programmer, I'll do what I do best: write some graphics thing no one (but me) will use.
Zappable Shadertoy
So, the idea is to create a small platform on top of #nostr where people can create, visualize, and share computer graphics programs (aka: shaders). Code shiny thing, see shiny, share shiny thing, and zap shiny thing. If you're familiar with Shadertoy, #glostr is just that: zappable shadertoy.
Milestone Zero
So, first step was to write a quick and dirty prototype client (remember, I specc'd into game dev, not into web dev, so I really mean quick and I really mean dirty). I got an ace editor thing working, duct-taped it to a basic WebGL render, stole a couple shaders from shadertoy (jk, I gave credit), poured some CSS magic, glued some
nostr-rx, and published it to GitHub pages.After 2 or 3 days of iterating, and with some assistance from an LLM, you can see the result linked on my notes.
Yes. I used
kind 1posts to spam GLSL code.I AM SORRY. I KNOW BETTER NOW. I SWEAR.
So, right now #glostr is: - Taking an npub on the url after the # - Rendering all
kind 1posts from that npub containing GLSL code between ```s - Allowing the user to edit the code in real time
Next Steps
What now? Gorila made me realize my obvious
kind 1spamming. After some brainstorming and skimming through NIPs and kinds, we arrived at the conclusion that Long-form Notes (NIP-23) are best suited for the content I want #glostr to display: - Format is Markdown, which I like and which I was already somewhat expecting. - It's editable content, so mistakes can be amended, which is more than usual in shader programming.So, the next features I want to add are: - Logging in - Posting NIP-23 Notes - Getting, parsing, and showing NIP-23 Notes
When
I'll only work on this on the weekends for now, so I don't know. This is a pet project for fun right now.
Wrapping Up
As this is a Long-Form Note in itself, I'll finish it by sharing a shader based on Inigo Quilez's awesome polygon shader. This note should show as a shader on #glostr in the next iteration, but you can copy and paste the code in the editor for now:
#version 300 es precision mediump float; uniform vec2 u_resolution; uniform float u_time; out vec4 fragColor; const int N = 6; vec3 yellow = vec3(0.45, 0.3, 0.15); vec3 lightBlue = vec3(0.65, 0.85, 1.0); float polygon(in vec2 p, in vec2[N] v) { const int num = v.length(); float d = dot(p - v[0], p - v[0]); float s = 1.; for(int i=0, j=num-1; i < num; j=i, i++ ) { vec2 e = v[j] - v[i]; vec2 w = p - v[i]; vec2 b = w - e * clamp(dot(w, e) / dot(e, e), 0.0, 1.0); d = min(d, dot(b,b)); bvec3 condition = bvec3( p.y >= v[i].y, p.y < v[j].y, e.x * w.y > e.y * w.x ); if (all(condition) || all(not(condition))) s =- s; } return s * sqrt(d); } void main() { vec2 p = (2.0 * gl_FragCoord.xy - u_resolution.xy) / u_resolution.y; float d = polygon(p, vec2[]( vec2( .2, .8), vec2(-.5, -.125), vec2( .0, -.125), vec2(-.2, -.8), vec2( .5, .125), vec2( .0, .125) )); vec3 color = d < 0.0 ? yellow : lightBlue; color *= 1. - exp(-40. * abs(d)); color *= .8 + .2 * sin(10.0 * d - 10. * u_time) * sin(-1.25 * u_time); color *= exp(1. - d * 2.25); fragColor = vec4(color, 1.0); }


