Glynn Set Curve: GigaTron, Lulu and Boleeman Versions lazarus / 39-Graphics ---------------------------------------------------------------------- Boleeman · 2026-01-04 12:52 Glynn Set Curve A curve with Beautiful Geometry The Glynn Set is a special Julia Set, named after Earl Glynn. It kind of looks like a tree (Mine looks like a monkey's face). Get the Super Duper Lulu OpenGL version 5 Replies down I tried making a multicolored one, but it renders very slowly. I tried speeding it up using scanline, but it is still very slow at rending. Got up to version 9, but the multi-threading did not work so here is version 8. Perhaps someone can do a quicker rendering multi-threaded or OpenGL version for the forum? PS: Needed to reduce the size of the png as it was too big in size (many colours) Enjoy. ---------------------------------------------------------------------- Boleeman · 2026-01-04 13:00 Also made a plain coloured one using setpixel )version 3). ---------------------------------------------------------------------- Boleeman · 2026-01-04 14:44 Ah, finally found the whole set and special effects. 2nd png looks a bit like an "owl's face". ---------------------------------------------------------------------- Lulu · 2026-01-04 22:56 Hi Boleeman, I converted your project to an OpenGL version with OGLCScene library. To use, you have to install package BGRABitmap from OPM and OGLCScene from https://github.com/Lulu04/OGLCScene/releases/tag/v2.3 With this version I can't reach the last beautifull result you have posted. Did you have another version of the project ? ---------------------------------------------------------------------- Boleeman · 2026-01-05 00:48 Many thanks Lulu for doing the conversion. I tried it out and it certainly is responsive, but lacks colours and has tiny pixel dots. (I think it is due to the HSL function I was using, it is not the one from TBgrabmp)) Attached is another version using HSLA from bgrabmp. Please give that a go. Thanks for helping out with the OpenGL version. Also attached is a modified one png which I did just now using Paint.Net using a capture of yesterday's version of the Glynn Set Maker. ---------------------------------------------------------------------- Boleeman · 2026-01-05 12:37 Lulu, After many hours of tinkering about with your code I finally got the OpenGL working. I learnt heaps about how to do it from your code. Thanks Lulu for helping out with the conversion. As shown, in the RGB mode the tree has a nice gradient colour. In the HSB modes the tree consists of multi-colours (Took me ages to figure that one out the OpenGL way with your 2048 texture) Enjoy. Fixed up the startup bug so I re-uploaded everything (Did not set some initial values) ---------------------------------------------------------------------- Lulu · 2026-01-05 17:26 Boleeman, you are a magician ! This demo is very nice and work perfectly. I like it ---------------------------------------------------------------------- Boleeman · 2026-01-05 21:35 Thanks again Lulu for the initial conversion. My knowledge of OpenGL was limited so I would have found it difficult to know where to start from. Initially I was going in and out of the various units trying to work out the code logic. The more I looked at your code, the better the understanding. The shader code was interesting. Saw something like it in other programs, but did not really pay much attention until I worked on your conversion. You are very welcome to put it on your GitHub page if you want to? I read from from your Github page: "'I  am an amateur programmer who loves the Pascal language. OGLCScene is an attempt to go as far as possible in my understanding of OpenGL and game engines. The path has been sometimes frustrating, sometimes happy, but very interesting." Reply: Boleeman too "is an amateur programmer" The adventure is "usually frustrating" but "becomes very rewarding when a good end result is achieved" I am not sure, but ... with the OpenGL version is there a way in the shader the make the edges of the curve where the colors change bleed slightly, sort of like running/fade ink when a paper gets wet with ink writing on it? Perhaps GigaTron might also know, as he is very knowledgeable with OpenGL programming? ---------------------------------------------------------------------- Boleeman · 2026-01-06 01:56 With a small modification we can see the whole Glynn set. That previous program showed only one of the trees in the whole set. Don't know how Earl Glynn stumbled across that set? ---------------------------------------------------------------------- Lulu · 2026-01-08 20:36 Hi Boleeman, sorry for the late answer, I was busy this last time. QuoteYou are very welcome to put it on your GitHub page if you want to? With pleasure! If you are agree, I will put the version 3.0, I like this one. I'll do it as soon as possible. ---------------------------------------------------------------------- Gigatron · 2026-01-08 23:55 Hi I ve looked your sahder code and made some modification to include this shader on glCanvas. Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i glJuliaFractal(0, 0, cw, ch, tmr,               64*2,         // iterations               80 ,        // minHueOffset               1.0,        // zoom               0.0, 0.0,   // offset X, Y             12.0,       // bleedAmount                2);         // colorMode     0-1-2 What used : FBM (Fractal Brownian Motion) - distort the UV coordinates before the fractal calculation.  Noise/dithering -   noise to the normalized iteration value before sampling the palette.  Multi-sampling - You could also sample neighboring palette positions and blend them together. All these fonctions are from WWW ; but i understand the technique . Shaders are not easy if it's complex  ... vec2, vec3, vec4(x,y,z,w) mat2, mat3,mat4 float int ivec bvec etc.. if you understand this you can create a millions fx but you can replace without effort some fonctions like noise, fract , some multisample etc.... This one is not good but working ... hope you like it; Regards ---------------------------------------------------------------------- Boleeman · 2026-01-09 07:24 Wow that animation was amazing GigaTron. Almost like a school of Squids. I needed to shift the curve a little to keep it on the screen. Was hoping that you would make a glCanvas version, so I could see the bleeding. Sort of got a fine mist of Blue trail happening. Was trying to get like a smoky gas trail effect. I am very new to Shaders, so need to play around more with them. Thanks GigaTron for the nice animated Glynn Set curve. As I know you like DemoScene, I recently came across some German Demoscenes at https://keyj.emphy.de/projects/demoscene/ I especially like the games: BlockOut 8k / 6k  and Kakiarts 8-Ball and Think inside the box I wanted to make a 3D Blockout game in Lazarus. I had a VB6 version source somewhere, so I might try to convert it someday. Thanks GigaTron for your nice Glenn Set Animation. I really appreciate it. ---------------------------------------------------------------------- Gigatron · 2026-01-09 16:42 Ok ... nice Boleeman ; You can test and make online shader Faster Than light ; I've quickly prepared the shader for shadertoy.. 1 - Go to : https://www.shadertoy.com/new 2 - Copy & past shader to the right 3 - Click compile to see the result in the left 4 - Good Luck Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i // For friend Boleeman   const float u_iterations   = 128.0;  const float u_minHueOffset = 50.0;  const float u_zoom = 1.0;  const vec2 u_offset = vec2(0.0,0.0);  const float u_bleedAmount  = 12.0;  const int u_colorMode      =  2;  // FBMotion function  vec2 fbm(vec2 uv, float time, float amount) {    float f = 2.0;    float a = amount;    for(int s = 0; s < 3; s++) {      uv += vec2(sin(uv.y*f + time*0.3), cos(uv.x*f + time*0.3)) * a;      f = f * 1.5;      a = a * 0.5;    }    return uv;  }  // HSL to RGB  vec3 hsl2rgb(float h, float s, float l) {    float c = (1.0 - abs(2.0 * l - 1.0)) * s;    float x = c * (1.0 - abs(mod(h / 60.0, 2.0) - 1.0));    float m = l - c / 2.0;    vec3 rgb;    if (h < 60.0) rgb = vec3(c, x, 0.0);    else if (h < 120.0) rgb = vec3(x, c, 0.0);    else if (h < 180.0) rgb = vec3(0.0, c, x);    else if (h < 240.0) rgb = vec3(0.0, x, c);    else if (h < 300.0) rgb = vec3(x, 0.0, c);    else rgb = vec3(c, 0.0, x);    return rgb + vec3(m, m, m);  } void mainImage( out vec4 fragColor, in vec2 fragCoord ){    vec2 uv = fragCoord.xy /iResolution.xy;    vec2 distortedUV = fbm(uv, iTime, u_bleedAmount * 0.01); // uv distortion avant calcul etc..    float zx = (-0.8 + distortedUV.x * (1.4 - (-0.8)))   *  -u_zoom + u_offset.x; // on inverse le zoom ici plus tard    float zy = (-0.72 + distortedUV.y * (0.7 - (-0.72))) *  -u_zoom + u_offset.y; // et ici pour val param    float i = u_iterations;    while (zx*zx + zy*zy < 4.0 && i > 1.0) {      float r = sqrt(zx*zx + zy*zy);      float theta = atan(zy, zx);      float r15 = pow(r, 1.5);      float tmp = r15 * cos(1.5*theta) - 0.2;      zy = r15 * sin(1.5*theta);      zx = tmp;      i = i - 1.0;    }    float t = i / u_iterations; // multisample    float noise = fract(sin(dot(uv, vec2(12.9898, 78.233))) * 43758.5453);  // bruit    t = clamp(t + noise * u_bleedAmount * 0.02, 0.0, 1.0);   // lissage    vec3 color;  if (u_colorMode == 0) {      float r = mod(t * 7.0 * 255.0 + u_minHueOffset, 256.0) / 255.0;      float g = mod(t * 5.0 * 255.0 + u_minHueOffset * 2.0, 256.0) / 255.0;      float b = mod(t * 3.0 * 255.0 + u_minHueOffset * 3.0, 256.0) / 255.0;      color = vec3(r, g, b);    } else if (u_colorMode == 1) {      float hue = mod(0.0 + u_minHueOffset + t * 360.0, 360.0);      color = hsl2rgb(hue, 0.6, 0.52);    } else if (u_colorMode == 2) {      float hue = mod(120.0 + u_minHueOffset + t * 360.0, 360.0);      color = hsl2rgb(hue, 0.6, 0.52);    } else {      float hue = mod(240.0 + u_minHueOffset + t * 360.0, 360.0);      color = hsl2rgb(hue, 0.6, 0.52);    }    // Output to screen    fragColor = vec4(color,1.0);} // End of Transmission :) Regards Gigatron ---------------------------------------------------------------------- Gigatron · 2026-01-09 19:02 Hi Here is mixed function to make Eclipse like shader took 30 min; Copy code to shadertoy ; https://www.shadertoy.com/new You can now play and understand this basic shader.. Have fun Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i // functions formula from WWWfloat hash(vec2 p) {    return fract(sin(dot(p, vec2(12.9898, 78.233))) * 43758.5453);} float noise(vec2 p) {    vec2 i = floor(p);    vec2 f = fract(p);    f = f * f * (3.0 - 2.0 * f);        float a = hash(i);    float b = hash(i + vec2(1.0, 0.0));    float c = hash(i + vec2(0.0, 1.0));    float d = hash(i + vec2(1.0, 1.0));        return mix(mix(a, b, f.x), mix(c, d, f.x), f.y);} float fbm(vec2 p) {    float value = 0.0;    float amplitude = 0.8;        for(int i = 0; i < 5; i++) {        value += amplitude * noise(p);        p *= 2.0;        amplitude *= 0.8;    }      return value;} // End fonctions void mainImage(out vec4 fragColor, in vec2 fragCoord) {    vec2 uv = (fragCoord - 0.5 * iResolution.xy) / iResolution.y;        float dist = length(uv);  // distance pour cercle     float angle = atan(uv.y, uv.x); // autour du soleil        float sunRadius = 0.3;    float turbulence = fbm(vec2(angle * 5.0, dist * 10.0) + iTime * 0.1) * 0.02;    float sunEdge = sunRadius + turbulence;    float sun = smoothstep(sunEdge + 0.02, sunEdge, dist); // le cercle soleil lissage        float ejection = fbm(uv * 8.0 + iTime * 0.3);    ejection += 2.8 * fbm(uv * 16.0 - iTime * 0.5);        vec3 sunCol = vec3(1.0, 0.7, 0.2);  // soleil  couleur    sunCol += vec3(0.5, 0.2, 0.0) * ejection;    sunCol *= (1.5 + ejection * 0.5);        float corona = exp(-abs(dist - sunRadius) * 8.0); // couronne soleil    float flares = fbm(vec2(angle * 3.0, 1.0) + iTime * 0.2) * 0.1;    corona += flares * smoothstep(sunRadius + 0.3, sunRadius , dist );        vec3 coronaCol = vec3(1.0, 0.5, 0.1) * corona * 0.5;        float moonX = sin(iTime * 0.0) * 0.15; // posx     vec2  moonPos = vec2(moonX, 0.0);      // just xpos     float moonDist = length(0.83*uv - moonPos);  // cercle lune avec sa taille        float moonRadius = 0.28;    float moon = smoothstep(moonRadius + 0.01, moonRadius, moonDist); // lissage cercle        vec3 col = sunCol * sun;    col += coronaCol;    col = mix(col, vec3(0.0), moon);  // mélange col + black + moon            fragColor = vec4(col, 1.0);} ---------------------------------------------------------------------- Boleeman · 2026-01-09 22:19 Hi GigaTron. Thanks for letting me know about shadertoy. I have seen ShadrToy before, but never really understood what it was about until now. So that is how you prototype the shader code. I was the Shader code in Lazarus and it was time consuming, wait for the compiling to complete and then altering it with new additions. Had a bit of a heat wave where I live. The eclipse shader reminds me a bit of yesterday''s extreme hot solar flare weather. Looking at the color mode of the Glynn set shader code, the colors are offset by intervals of 120 plus further offsets. Do you know what type of noise is being used? (Perlin, simplex, etc ?). Shader code has interesting vector code (so that's probably why it is used in 3D rendering, makes sense). I came across some C# Buddhabrot code which rendered the fractal in OpenCL at https://github.com/nikvoronin/BuddhabrotCL and thought of perhaps doing something similar in Lazarus. You can download the exe at https://github.com/nikvoronin/BuddhabrotCL/releases and it even has other fractals in the Kernel Menu. I (and DZandaa) made a BuddhaBrot in Lazarus ages ago in TBgrabmp ( at https://forum.lazarus.freepascal.org/index.php/topic,67464.msg519357.h tml#msg519357 ), but with OpenGL and Shader it probably would have rendered much more nicely. I was after the similar trippy effects as the C# Buddhabrot code. Thanks for the great info. on Shader GigaTron. ---------------------------------------------------------------------- Gigatron · 2026-01-09 23:54 QuoteDo you know what type of noise is being used? (Perlin, simplex, etc ?) The noise used in the example of shader i've sent is  simple 2D Value noise working in grid based in other word random pixel. I think it's by IQ from shadertoy author ; Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i // simle 2d value noise , or random pixel on UV screen float hash(vec2 p) {    return fract(sin(dot(p, vec2(12.9898, 78.233))) * 43758.5453);} float noise(vec2 p) {    vec2 i = floor(p);    vec2 f = fract(p);    f = f * f * (3.0 - 2.0 * f);       float a = hash(i);    float b = hash(i + vec2(1.0, 0.0));    float c = hash(i + vec2(0.0, 1.0));    float d = hash(i + vec2(1.0, 1.0));       return mix(mix(a, b, f.x), mix(c, d, f.x), f.y);}