This commit is contained in:
lavafroth
2026-01-20 16:11:31 +00:00
parent 0559e52990
commit 7f139b16ce
4 changed files with 139 additions and 19 deletions

View File

@@ -1,9 +1,69 @@
<!doctype html><html lang=en-us><head><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge"><meta name=viewport content="width=device-width,initial-scale=1,shrink-to-fit=no"><title>Step to the 💗 beat - lavafroth</title><meta name=description content='My first procedurally generated animation drawing concentric heart
growing from the center of the screen. The source code for the
program used to create this piece is available on my GitHub.
<!doctype html><html lang=en-us><head><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge"><meta name=viewport content="width=device-width,initial-scale=1,shrink-to-fit=no"><title>Step to the 💗 beat - lavafroth</title><meta name=description content='My first procedurally generated animation using shaders.
The shader can be visualized with glslViewer.
uniform vec2 u_mouse;
uniform vec2 u_resolution;
uniform float u_time;
void main (void) {
vec2 st = gl_FragCoord.xy/u_resolution.xy;
float aspect = u_resolution.x/u_resolution.y;
st.x *= aspect;
// positioning shenanigans
st.x = st.x * 2.0 - 1.8;
st.y = st.y * 2.0 - 0.9;
float r = st.x*st.x + st.y*st.y - abs(st.x)*st.y;
r *= 2.0;
float duration = 3.0;
float bin = 0.1;
float scaled_time = fract(u_time/duration);
float loop = scaled_time * 2.0 - 1.0;
float r_disc = floor((r + loop*loop)/bin) * bin;
vec3 deep_pink = vec3(0.917, 0.235, 0.478);
vec3 light_pink = vec3(0.976, 0.780, 0.803);
if (r_disc >= 1.0) {
gl_FragColor = vec4(deep_pink, 1.0);
return;
}
vec3 color = mix(deep_pink, light_pink, r_disc);
gl_FragColor = vec4(color,1.0);
}
I tinkered around for quite a while before discovering that I can intersect two xyxy skewed ellipses
with the absolute value operator. Here&rsquo;s my custom equation for the heart shape.
x2+y2xy=r x^2 + y^2 - |x|y = r have fun!'><meta name=author content><link rel="preload stylesheet" as=style href=https://lavafroth.is-a.dev/app.min.css><link rel=preload as=image href=../../header.svg><link as=font href=https://lavafroth.is-a.dev/latinmodern-math.otf><link rel=preload as=image href=https://lavafroth.is-a.dev/github.svg><link rel=preload as=image href=https://lavafroth.is-a.dev/about.svg><link rel=preload as=image href=https://lavafroth.is-a.dev/art.svg><link rel=preload as=image href=https://lavafroth.is-a.dev/rss.svg><link rel=icon href=https://lavafroth.is-a.dev/favicon.png><link rel=blog-icon href=https://lavafroth.is-a.dev/icon.png></head><body><header><a class=site-name href=https://lavafroth.is-a.dev/><svg viewBox="0 0 8790 2080"><path d="M80 1935V465h216v1270h286v2e2zm853 0 222-1470h264l222 1470h-210l-40-3e2h-208l-40 3e2zm280-528h148l-62-494-6-78h-12l-6 78zm1025 528L2014 465h210l108 868 8 142h12l8-142 108-868h210l-224 1470zm813 0 222-1470h264l222 1470h-210l-40-3e2h-208l-40 3e2zm280-528h148l-62-494-6-78h-12l-6 78zm851 528V465h514v222h-298v386h2e2v222h-2e2v640zm910 0V465h216q194 0 286 108 92 107 92 316 0 124-43 215-44 90-106 132l147 699h-216l-122-620h-38v620zm216-820q60 0 95-26 35-27 50-76t15-116q0-105-34-161-35-57-126-57zm1084 836q-90 0-154-42-65-42-99-114-35-72-35-162V767q0-91 35-162 34-72 99-114 64-42 154-42t155 42q64 42 99 114 34 72 34 162v866q0 90-34 162-35 72-99 114-65 42-155 42zm0-210q40 0 56-33 16-34 16-75V767q0-41-17-74-17-34-55-34-37 0-54 34-18 33-18 74v866q0 41 17 75 17 33 55 33zm890 194V687h-204V465h624v222h-204v1248zm828 0V465h216v608h168V465h216v1470h-216v-640h-168v640z"/></svg></a><nav><a style=--url:url(./github.svg) href=https://github.com/lavafroth aria-label=github target=_blank></a><a href=../../about/ aria-label=about style=--url:url(./about.svg)></a><a class=active href=../../art/ aria-label=art style=--url:url(./art.svg)></a><a href=../../index.xml aria-label=rss style=--url:url(./rss.svg)></a><nav></header><main><hgroup><p>Jan 18, 2026</p><h1>Step to the 💗 beat</h1></hgroup><section class=post-content><p>My first procedurally generated animation drawing concentric heart
growing from the center of the screen. The source code for the
program used to create this piece is <a href=https://github.com/lavafroth/drawhearts>available on my GitHub</a>.</p><p>I tinkered around for quite a while before discovering that I can intersect two <span class=katex><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>x</mi><mi>y</mi></mrow><annotation encoding="application/x-tex">xy</annotation></semantics></math></span> skewed ellipses
with the absolute value operator. Here&rsquo;s my custom equation for the heart shape.'><meta name=author content><link rel="preload stylesheet" as=style href=https://lavafroth.is-a.dev/app.min.css><link rel=preload as=image href=../../header.svg><link as=font href=https://lavafroth.is-a.dev/latinmodern-math.otf><link rel=preload as=image href=https://lavafroth.is-a.dev/github.svg><link rel=preload as=image href=https://lavafroth.is-a.dev/about.svg><link rel=preload as=image href=https://lavafroth.is-a.dev/art.svg><link rel=preload as=image href=https://lavafroth.is-a.dev/rss.svg><link rel=icon href=https://lavafroth.is-a.dev/favicon.png><link rel=blog-icon href=https://lavafroth.is-a.dev/icon.png></head><body><header><a class=site-name href=https://lavafroth.is-a.dev/><svg viewBox="0 0 8790 2080"><path d="M80 1935V465h216v1270h286v2e2zm853 0 222-1470h264l222 1470h-210l-40-3e2h-208l-40 3e2zm280-528h148l-62-494-6-78h-12l-6 78zm1025 528L2014 465h210l108 868 8 142h12l8-142 108-868h210l-224 1470zm813 0 222-1470h264l222 1470h-210l-40-3e2h-208l-40 3e2zm280-528h148l-62-494-6-78h-12l-6 78zm851 528V465h514v222h-298v386h2e2v222h-2e2v640zm910 0V465h216q194 0 286 108 92 107 92 316 0 124-43 215-44 90-106 132l147 699h-216l-122-620h-38v620zm216-820q60 0 95-26 35-27 50-76t15-116q0-105-34-161-35-57-126-57zm1084 836q-90 0-154-42-65-42-99-114-35-72-35-162V767q0-91 35-162 34-72 99-114 64-42 154-42t155 42q64 42 99 114 34 72 34 162v866q0 90-34 162-35 72-99 114-65 42-155 42zm0-210q40 0 56-33 16-34 16-75V767q0-41-17-74-17-34-55-34-37 0-54 34-18 33-18 74v866q0 41 17 75 17 33 55 33zm890 194V687h-204V465h624v222h-204v1248zm828 0V465h216v608h168V465h216v1470h-216v-640h-168v640z"/></svg></a><nav><a style=--url:url(./github.svg) href=https://github.com/lavafroth aria-label=github target=_blank></a><a href=../../about/ aria-label=about style=--url:url(./about.svg)></a><a class=active href=../../art/ aria-label=art style=--url:url(./art.svg)></a><a href=../../index.xml aria-label=rss style=--url:url(./rss.svg)></a><nav></header><main><hgroup><p>Jan 18, 2026</p><h1>Step to the 💗 beat</h1></hgroup><section class=post-content><p>My first procedurally generated animation using shaders.</p><p>The shader can be visualized with <code>glslViewer</code>.</p><div class=highlight><pre tabindex=0 style=color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-glsl data-lang=glsl><span style=display:flex><span><span style=color:#66d9ef>uniform</span> <span style=color:#66d9ef>vec2</span> u_mouse;
</span></span><span style=display:flex><span><span style=color:#66d9ef>uniform</span> <span style=color:#66d9ef>vec2</span> u_resolution;
</span></span><span style=display:flex><span><span style=color:#66d9ef>uniform</span> <span style=color:#66d9ef>float</span> u_time;
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span><span style=color:#66d9ef>void</span> main (<span style=color:#66d9ef>void</span>) {
</span></span><span style=display:flex><span> <span style=color:#66d9ef>vec2</span> st <span style=color:#f92672>=</span> gl_FragCoord.xy<span style=color:#f92672>/</span>u_resolution.xy;
</span></span><span style=display:flex><span> <span style=color:#66d9ef>float</span> aspect <span style=color:#f92672>=</span> u_resolution.x<span style=color:#f92672>/</span>u_resolution.y;
</span></span><span style=display:flex><span> st.x <span style=color:#f92672>*=</span> aspect;
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span> <span style=color:#75715e>// positioning shenanigans</span>
</span></span><span style=display:flex><span> st.x <span style=color:#f92672>=</span> st.x <span style=color:#f92672>*</span> <span style=color:#ae81ff>2.0</span> <span style=color:#f92672>-</span> <span style=color:#ae81ff>1.8</span>;
</span></span><span style=display:flex><span> st.y <span style=color:#f92672>=</span> st.y <span style=color:#f92672>*</span> <span style=color:#ae81ff>2.0</span> <span style=color:#f92672>-</span> <span style=color:#ae81ff>0.9</span>;
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span> <span style=color:#66d9ef>float</span> r <span style=color:#f92672>=</span> st.x<span style=color:#f92672>*</span>st.x <span style=color:#f92672>+</span> st.y<span style=color:#f92672>*</span>st.y <span style=color:#f92672>-</span> abs(st.x)<span style=color:#f92672>*</span>st.y;
</span></span><span style=display:flex><span> r <span style=color:#f92672>*=</span> <span style=color:#ae81ff>2.0</span>;
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span> <span style=color:#66d9ef>float</span> duration <span style=color:#f92672>=</span> <span style=color:#ae81ff>3.0</span>;
</span></span><span style=display:flex><span> <span style=color:#66d9ef>float</span> bin <span style=color:#f92672>=</span> <span style=color:#ae81ff>0.1</span>;
</span></span><span style=display:flex><span> <span style=color:#66d9ef>float</span> scaled_time <span style=color:#f92672>=</span> fract(u_time<span style=color:#f92672>/</span>duration);
</span></span><span style=display:flex><span> <span style=color:#66d9ef>float</span> loop <span style=color:#f92672>=</span> scaled_time <span style=color:#f92672>*</span> <span style=color:#ae81ff>2.0</span> <span style=color:#f92672>-</span> <span style=color:#ae81ff>1.0</span>;
</span></span><span style=display:flex><span> <span style=color:#66d9ef>float</span> r_disc <span style=color:#f92672>=</span> floor((r <span style=color:#f92672>+</span> loop<span style=color:#f92672>*</span>loop)<span style=color:#f92672>/</span>bin) <span style=color:#f92672>*</span> bin;
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span> <span style=color:#66d9ef>vec3</span> deep_pink <span style=color:#f92672>=</span> <span style=color:#66d9ef>vec3</span>(<span style=color:#ae81ff>0.917</span>, <span style=color:#ae81ff>0.235</span>, <span style=color:#ae81ff>0.478</span>);
</span></span><span style=display:flex><span> <span style=color:#66d9ef>vec3</span> light_pink <span style=color:#f92672>=</span> <span style=color:#66d9ef>vec3</span>(<span style=color:#ae81ff>0.976</span>, <span style=color:#ae81ff>0.780</span>, <span style=color:#ae81ff>0.803</span>);
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span> <span style=color:#66d9ef>if</span> (r_disc <span style=color:#f92672>&gt;=</span> <span style=color:#ae81ff>1.0</span>) {
</span></span><span style=display:flex><span> gl_FragColor <span style=color:#f92672>=</span> <span style=color:#66d9ef>vec4</span>(deep_pink, <span style=color:#ae81ff>1.0</span>);
</span></span><span style=display:flex><span> <span style=color:#66d9ef>return</span>;
</span></span><span style=display:flex><span> }
</span></span><span style=display:flex><span> <span style=color:#66d9ef>vec3</span> color <span style=color:#f92672>=</span> mix(deep_pink, light_pink, r_disc);
</span></span><span style=display:flex><span> gl_FragColor <span style=color:#f92672>=</span> <span style=color:#66d9ef>vec4</span>(color,<span style=color:#ae81ff>1.0</span>);
</span></span><span style=display:flex><span>}
</span></span></code></pre></div><p>I tinkered around for quite a while before discovering that I can intersect two <span class=katex><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>x</mi><mi>y</mi></mrow><annotation encoding="application/x-tex">xy</annotation></semantics></math></span> skewed ellipses
with the absolute value operator. Here&rsquo;s my custom equation for the heart shape.</p><span class=katex><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><msup><mi>x</mi><mn>2</mn></msup><mo>+</mo><msup><mi>y</mi><mn>2</mn></msup><mo></mo><mi mathvariant="normal"></mi><mi>x</mi><mi mathvariant="normal"></mi><mi>y</mi><mo>=</mo><mi>r</mi></mrow><annotation encoding="application/x-tex"> x^2 + y^2 - |x|y = r </annotation></semantics></math></span><p>have fun!</p><img src=../../hearts.avif style=border-radius:1rem></section></main><footer class=footer><p>&copy; 2026 <a href=https://lavafroth.is-a.dev/>lavafroth</a></p><p><a href=https://github.com/lavafroth/lavafroth.github.io/issues/new/choose>Report an issue</a></p><p><a href=https://github.com/lavafroth/lavafroth.github.io/discussions/>Discuss</a></p><p><a href=https://lavafroth.is-a.dev/privacy>Privacy</a></p><p><a href=https://creativecommons.org/licenses/by-sa/4.0/legalcode>License</a></p></footer></body></html>

View File

@@ -1,9 +1,39 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Art on lavafroth</title><link>https://lavafroth.is-a.dev/art/</link><description>Recent content in Art on lavafroth</description><generator>Hugo</generator><language>en-us</language><lastBuildDate>Sun, 18 Jan 2026 08:06:06 +0530</lastBuildDate><atom:link href="https://lavafroth.is-a.dev/art/index.xml" rel="self" type="application/rss+xml"/><item><title>Step to the 💗 beat</title><link>https://lavafroth.is-a.dev/art/drawhearts/</link><pubDate>Sun, 18 Jan 2026 08:06:06 +0530</pubDate><guid>https://lavafroth.is-a.dev/art/drawhearts/</guid><description>&lt;p&gt;My first procedurally generated animation drawing concentric heart
growing from the center of the screen. The source code for the
program used to create this piece is &lt;a href="https://github.com/lavafroth/drawhearts"&gt;available on my GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I tinkered around for quite a while before discovering that I can intersect two &lt;span class="katex"&gt;&lt;math xmlns="http://www.w3.org/1998/Math/MathML"&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mi&gt;y&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding="application/x-tex"&gt;xy&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt; skewed ellipses
with the absolute value operator. Here&amp;rsquo;s my custom equation for the heart shape.&lt;/p&gt;
&lt;span class="katex"&gt;&lt;math xmlns="http://www.w3.org/1998/Math/MathML" display="block"&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;msup&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;/msup&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;msup&gt;&lt;mi&gt;y&lt;/mi&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;/msup&gt;&lt;mo&gt;&lt;/mo&gt;&lt;mi mathvariant="normal"&gt;&lt;/mi&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mi mathvariant="normal"&gt;&lt;/mi&gt;&lt;mi&gt;y&lt;/mi&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mi&gt;r&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding="application/x-tex"&gt; x^2 + y^2 - |x|y = r &lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;p&gt;have fun!&lt;/p&gt;</description></item><item><title></title><link>https://lavafroth.is-a.dev/art/sparkles/</link><pubDate>Tue, 15 Jul 2025 11:52:20 +0530</pubDate><guid>https://lavafroth.is-a.dev/art/sparkles/</guid><description/></item><item><title>Amateur Blender Sculpture</title><link>https://lavafroth.is-a.dev/art/amateur-blender-sculpture/</link><pubDate>Sat, 03 Aug 2024 17:50:00 +0530</pubDate><guid>https://lavafroth.is-a.dev/art/amateur-blender-sculpture/</guid><description>&lt;p&gt;This is my first time trying out sculpting in blender, so forgive me for the
<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Art on lavafroth</title><link>https://lavafroth.is-a.dev/art/</link><description>Recent content in Art on lavafroth</description><generator>Hugo</generator><language>en-us</language><lastBuildDate>Sun, 18 Jan 2026 08:06:06 +0530</lastBuildDate><atom:link href="https://lavafroth.is-a.dev/art/index.xml" rel="self" type="application/rss+xml"/><item><title>Step to the 💗 beat</title><link>https://lavafroth.is-a.dev/art/drawhearts/</link><pubDate>Sun, 18 Jan 2026 08:06:06 +0530</pubDate><guid>https://lavafroth.is-a.dev/art/drawhearts/</guid><description>&lt;p&gt;My first procedurally generated animation using shaders.&lt;/p&gt;
&lt;p&gt;The shader can be visualized with &lt;code&gt;glslViewer&lt;/code&gt;.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-glsl" data-lang="glsl"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;uniform&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;vec2&lt;/span&gt; u_mouse;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;uniform&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;vec2&lt;/span&gt; u_resolution;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;uniform&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;float&lt;/span&gt; u_time;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; main (&lt;span style="color:#66d9ef"&gt;void&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;vec2&lt;/span&gt; st &lt;span style="color:#f92672"&gt;=&lt;/span&gt; gl_FragCoord.xy&lt;span style="color:#f92672"&gt;/&lt;/span&gt;u_resolution.xy;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;float&lt;/span&gt; aspect &lt;span style="color:#f92672"&gt;=&lt;/span&gt; u_resolution.x&lt;span style="color:#f92672"&gt;/&lt;/span&gt;u_resolution.y;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; st.x &lt;span style="color:#f92672"&gt;*=&lt;/span&gt; aspect;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// positioning shenanigans&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; st.x &lt;span style="color:#f92672"&gt;=&lt;/span&gt; st.x &lt;span style="color:#f92672"&gt;*&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2.0&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1.8&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; st.y &lt;span style="color:#f92672"&gt;=&lt;/span&gt; st.y &lt;span style="color:#f92672"&gt;*&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2.0&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0.9&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;float&lt;/span&gt; r &lt;span style="color:#f92672"&gt;=&lt;/span&gt; st.x&lt;span style="color:#f92672"&gt;*&lt;/span&gt;st.x &lt;span style="color:#f92672"&gt;+&lt;/span&gt; st.y&lt;span style="color:#f92672"&gt;*&lt;/span&gt;st.y &lt;span style="color:#f92672"&gt;-&lt;/span&gt; abs(st.x)&lt;span style="color:#f92672"&gt;*&lt;/span&gt;st.y;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; r &lt;span style="color:#f92672"&gt;*=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2.0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;float&lt;/span&gt; duration &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;3.0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;float&lt;/span&gt; bin &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0.1&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;float&lt;/span&gt; scaled_time &lt;span style="color:#f92672"&gt;=&lt;/span&gt; fract(u_time&lt;span style="color:#f92672"&gt;/&lt;/span&gt;duration);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;float&lt;/span&gt; loop &lt;span style="color:#f92672"&gt;=&lt;/span&gt; scaled_time &lt;span style="color:#f92672"&gt;*&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2.0&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1.0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;float&lt;/span&gt; r_disc &lt;span style="color:#f92672"&gt;=&lt;/span&gt; floor((r &lt;span style="color:#f92672"&gt;+&lt;/span&gt; loop&lt;span style="color:#f92672"&gt;*&lt;/span&gt;loop)&lt;span style="color:#f92672"&gt;/&lt;/span&gt;bin) &lt;span style="color:#f92672"&gt;*&lt;/span&gt; bin;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;vec3&lt;/span&gt; deep_pink &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;vec3&lt;/span&gt;(&lt;span style="color:#ae81ff"&gt;0.917&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0.235&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0.478&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;vec3&lt;/span&gt; light_pink &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;vec3&lt;/span&gt;(&lt;span style="color:#ae81ff"&gt;0.976&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0.780&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0.803&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (r_disc &lt;span style="color:#f92672"&gt;&amp;gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1.0&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; gl_FragColor &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;vec4&lt;/span&gt;(deep_pink, &lt;span style="color:#ae81ff"&gt;1.0&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;vec3&lt;/span&gt; color &lt;span style="color:#f92672"&gt;=&lt;/span&gt; mix(deep_pink, light_pink, r_disc);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; gl_FragColor &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;vec4&lt;/span&gt;(color,&lt;span style="color:#ae81ff"&gt;1.0&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I tinkered around for quite a while before discovering that I can intersect two &lt;span class="katex"&gt;&lt;math xmlns="http://www.w3.org/1998/Math/MathML"&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mi&gt;y&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding="application/x-tex"&gt;xy&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt; skewed ellipses
with the absolute value operator. Here&amp;rsquo;s my custom equation for the heart shape.&lt;/p&gt;</description></item><item><title></title><link>https://lavafroth.is-a.dev/art/sparkles/</link><pubDate>Tue, 15 Jul 2025 11:52:20 +0530</pubDate><guid>https://lavafroth.is-a.dev/art/sparkles/</guid><description/></item><item><title>Amateur Blender Sculpture</title><link>https://lavafroth.is-a.dev/art/amateur-blender-sculpture/</link><pubDate>Sat, 03 Aug 2024 17:50:00 +0530</pubDate><guid>https://lavafroth.is-a.dev/art/amateur-blender-sculpture/</guid><description>&lt;p&gt;This is my first time trying out sculpting in blender, so forgive me for the
quality of the sculpt. I&amp;rsquo;m still pretty much in the learning stage. Big thank
you to &lt;a href="https://www.pexels.com/@nichole-sebastian-1592975/"&gt;Nichole Sebastian&lt;/a&gt;
for the reference photo. Also apologies if the empty eye sockets gave you a

Binary file not shown.

Before

Width:  |  Height:  |  Size: 53 KiB

After

Width:  |  Height:  |  Size: 130 KiB

View File

@@ -1,9 +1,39 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>lavafroth</title><link>https://lavafroth.is-a.dev/</link><description>Recent content on lavafroth</description><generator>Hugo</generator><language>en-us</language><lastBuildDate>Sun, 18 Jan 2026 08:06:06 +0530</lastBuildDate><atom:link href="https://lavafroth.is-a.dev/index.xml" rel="self" type="application/rss+xml"/><item><title>Step to the 💗 beat</title><link>https://lavafroth.is-a.dev/art/drawhearts/</link><pubDate>Sun, 18 Jan 2026 08:06:06 +0530</pubDate><guid>https://lavafroth.is-a.dev/art/drawhearts/</guid><description>&lt;p&gt;My first procedurally generated animation drawing concentric heart
growing from the center of the screen. The source code for the
program used to create this piece is &lt;a href="https://github.com/lavafroth/drawhearts"&gt;available on my GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I tinkered around for quite a while before discovering that I can intersect two &lt;span class="katex"&gt;&lt;math xmlns="http://www.w3.org/1998/Math/MathML"&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mi&gt;y&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding="application/x-tex"&gt;xy&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt; skewed ellipses
with the absolute value operator. Here&amp;rsquo;s my custom equation for the heart shape.&lt;/p&gt;
&lt;span class="katex"&gt;&lt;math xmlns="http://www.w3.org/1998/Math/MathML" display="block"&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;msup&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;/msup&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;msup&gt;&lt;mi&gt;y&lt;/mi&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;/msup&gt;&lt;mo&gt;&lt;/mo&gt;&lt;mi mathvariant="normal"&gt;&lt;/mi&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mi mathvariant="normal"&gt;&lt;/mi&gt;&lt;mi&gt;y&lt;/mi&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mi&gt;r&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding="application/x-tex"&gt; x^2 + y^2 - |x|y = r &lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;p&gt;have fun!&lt;/p&gt;</description></item><item><title>Working With LUKS File Stashes</title><link>https://lavafroth.is-a.dev/post/working-with-luks-file-stashes/</link><pubDate>Thu, 01 Jan 2026 07:24:36 +0530</pubDate><guid>https://lavafroth.is-a.dev/post/working-with-luks-file-stashes/</guid><description>&lt;p&gt;LUKS is an incredible solution for encrypting entire partitions in Linux.
<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>lavafroth</title><link>https://lavafroth.is-a.dev/</link><description>Recent content on lavafroth</description><generator>Hugo</generator><language>en-us</language><lastBuildDate>Sun, 18 Jan 2026 08:06:06 +0530</lastBuildDate><atom:link href="https://lavafroth.is-a.dev/index.xml" rel="self" type="application/rss+xml"/><item><title>Step to the 💗 beat</title><link>https://lavafroth.is-a.dev/art/drawhearts/</link><pubDate>Sun, 18 Jan 2026 08:06:06 +0530</pubDate><guid>https://lavafroth.is-a.dev/art/drawhearts/</guid><description>&lt;p&gt;My first procedurally generated animation using shaders.&lt;/p&gt;
&lt;p&gt;The shader can be visualized with &lt;code&gt;glslViewer&lt;/code&gt;.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-glsl" data-lang="glsl"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;uniform&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;vec2&lt;/span&gt; u_mouse;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;uniform&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;vec2&lt;/span&gt; u_resolution;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;uniform&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;float&lt;/span&gt; u_time;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; main (&lt;span style="color:#66d9ef"&gt;void&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;vec2&lt;/span&gt; st &lt;span style="color:#f92672"&gt;=&lt;/span&gt; gl_FragCoord.xy&lt;span style="color:#f92672"&gt;/&lt;/span&gt;u_resolution.xy;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;float&lt;/span&gt; aspect &lt;span style="color:#f92672"&gt;=&lt;/span&gt; u_resolution.x&lt;span style="color:#f92672"&gt;/&lt;/span&gt;u_resolution.y;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; st.x &lt;span style="color:#f92672"&gt;*=&lt;/span&gt; aspect;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// positioning shenanigans&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; st.x &lt;span style="color:#f92672"&gt;=&lt;/span&gt; st.x &lt;span style="color:#f92672"&gt;*&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2.0&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1.8&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; st.y &lt;span style="color:#f92672"&gt;=&lt;/span&gt; st.y &lt;span style="color:#f92672"&gt;*&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2.0&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0.9&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;float&lt;/span&gt; r &lt;span style="color:#f92672"&gt;=&lt;/span&gt; st.x&lt;span style="color:#f92672"&gt;*&lt;/span&gt;st.x &lt;span style="color:#f92672"&gt;+&lt;/span&gt; st.y&lt;span style="color:#f92672"&gt;*&lt;/span&gt;st.y &lt;span style="color:#f92672"&gt;-&lt;/span&gt; abs(st.x)&lt;span style="color:#f92672"&gt;*&lt;/span&gt;st.y;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; r &lt;span style="color:#f92672"&gt;*=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2.0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;float&lt;/span&gt; duration &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;3.0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;float&lt;/span&gt; bin &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0.1&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;float&lt;/span&gt; scaled_time &lt;span style="color:#f92672"&gt;=&lt;/span&gt; fract(u_time&lt;span style="color:#f92672"&gt;/&lt;/span&gt;duration);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;float&lt;/span&gt; loop &lt;span style="color:#f92672"&gt;=&lt;/span&gt; scaled_time &lt;span style="color:#f92672"&gt;*&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2.0&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1.0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;float&lt;/span&gt; r_disc &lt;span style="color:#f92672"&gt;=&lt;/span&gt; floor((r &lt;span style="color:#f92672"&gt;+&lt;/span&gt; loop&lt;span style="color:#f92672"&gt;*&lt;/span&gt;loop)&lt;span style="color:#f92672"&gt;/&lt;/span&gt;bin) &lt;span style="color:#f92672"&gt;*&lt;/span&gt; bin;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;vec3&lt;/span&gt; deep_pink &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;vec3&lt;/span&gt;(&lt;span style="color:#ae81ff"&gt;0.917&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0.235&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0.478&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;vec3&lt;/span&gt; light_pink &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;vec3&lt;/span&gt;(&lt;span style="color:#ae81ff"&gt;0.976&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0.780&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0.803&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (r_disc &lt;span style="color:#f92672"&gt;&amp;gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1.0&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; gl_FragColor &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;vec4&lt;/span&gt;(deep_pink, &lt;span style="color:#ae81ff"&gt;1.0&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;vec3&lt;/span&gt; color &lt;span style="color:#f92672"&gt;=&lt;/span&gt; mix(deep_pink, light_pink, r_disc);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; gl_FragColor &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;vec4&lt;/span&gt;(color,&lt;span style="color:#ae81ff"&gt;1.0&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I tinkered around for quite a while before discovering that I can intersect two &lt;span class="katex"&gt;&lt;math xmlns="http://www.w3.org/1998/Math/MathML"&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mi&gt;y&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding="application/x-tex"&gt;xy&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt; skewed ellipses
with the absolute value operator. Here&amp;rsquo;s my custom equation for the heart shape.&lt;/p&gt;</description></item><item><title>Working With LUKS File Stashes</title><link>https://lavafroth.is-a.dev/post/working-with-luks-file-stashes/</link><pubDate>Thu, 01 Jan 2026 07:24:36 +0530</pubDate><guid>https://lavafroth.is-a.dev/post/working-with-luks-file-stashes/</guid><description>&lt;p&gt;LUKS is an incredible solution for encrypting entire partitions in Linux.
Often times, however, we can&amp;rsquo;t afford to create new partitions inside a disk
without having to completely format the drive anew.&lt;/p&gt;
&lt;p&gt;This post will guide you through the process of creating and working