<?xml version="1.0" encoding="utf-8"?>
<feed xml:lang="en-us" xmlns="http://www.w3.org/2005/Atom"><title>Simon Willison's Weblog: webgl</title><link href="http://simonwillison.net/" rel="alternate"/><link href="http://simonwillison.net/tags/webgl.atom" rel="self"/><id>http://simonwillison.net/</id><updated>2025-02-04T20:53:29+00:00</updated><author><name>Simon Willison</name></author><entry><title>Animating Rick and Morty One Pixel at a Time</title><link href="https://simonwillison.net/2025/Feb/4/animating-rick-and-morty-one-pixel-at-a-time/#atom-tag" rel="alternate"/><published>2025-02-04T20:53:29+00:00</published><updated>2025-02-04T20:53:29+00:00</updated><id>https://simonwillison.net/2025/Feb/4/animating-rick-and-morty-one-pixel-at-a-time/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="https://danielchasehooper.com/posts/code-animated-rick/"&gt;Animating Rick and Morty One Pixel at a Time&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
Daniel Hooper says he spent 8 months working on the post, the culmination of which is an animation of Rick from Rick and Morty, implemented in 240 lines of GLSL - the OpenGL Shading Language which apparently has been directly supported by browsers for many years.&lt;/p&gt;
&lt;p&gt;The result is a comprehensive GLSL tutorial, complete with interactive examples of each of the steps used to generate the final animation which you can tinker with directly on the page. It feels a bit like Logo!&lt;/p&gt;
&lt;p&gt;&lt;img alt="Animated demo - as I edit the shader code Rick's half-drawn eye pupils move from side to side live with my edits" src="https://static.simonwillison.net/static/2025/rick-edit.gif" /&gt;&lt;/p&gt;
&lt;p&gt;Shaders work by running code for each pixel to return that pixel's color - in this case the &lt;code&gt;color_for_pixel()&lt;/code&gt; function is wired up as the core logic of the shader.&lt;/p&gt;
&lt;p&gt;Here's &lt;a href="https://gist.github.com/danielchasehooper/72da5d9c286e5e94fdfb8e82bea288cc"&gt;Daniel's code for the live shader editor&lt;/a&gt; he built for this post. It looks like &lt;a href="https://gist.github.com/danielchasehooper/72da5d9c286e5e94fdfb8e82bea288cc#file-inline_shader-js-L47-L60"&gt;this&lt;/a&gt; is the function that does the most important work:&lt;/p&gt;
&lt;div class="highlight highlight-source-js"&gt;&lt;pre&gt;&lt;span class="pl-k"&gt;function&lt;/span&gt; &lt;span class="pl-en"&gt;loadShader&lt;/span&gt;&lt;span class="pl-kos"&gt;(&lt;/span&gt;&lt;span class="pl-s1"&gt;shaderSource&lt;/span&gt;&lt;span class="pl-kos"&gt;,&lt;/span&gt; &lt;span class="pl-s1"&gt;shaderType&lt;/span&gt;&lt;span class="pl-kos"&gt;)&lt;/span&gt; &lt;span class="pl-kos"&gt;{&lt;/span&gt;
    &lt;span class="pl-k"&gt;const&lt;/span&gt; &lt;span class="pl-s1"&gt;shader&lt;/span&gt; &lt;span class="pl-c1"&gt;=&lt;/span&gt; &lt;span class="pl-s1"&gt;gl&lt;/span&gt;&lt;span class="pl-kos"&gt;.&lt;/span&gt;&lt;span class="pl-en"&gt;createShader&lt;/span&gt;&lt;span class="pl-kos"&gt;(&lt;/span&gt;&lt;span class="pl-s1"&gt;shaderType&lt;/span&gt;&lt;span class="pl-kos"&gt;)&lt;/span&gt;&lt;span class="pl-kos"&gt;;&lt;/span&gt;
    &lt;span class="pl-s1"&gt;gl&lt;/span&gt;&lt;span class="pl-kos"&gt;.&lt;/span&gt;&lt;span class="pl-en"&gt;shaderSource&lt;/span&gt;&lt;span class="pl-kos"&gt;(&lt;/span&gt;&lt;span class="pl-s1"&gt;shader&lt;/span&gt;&lt;span class="pl-kos"&gt;,&lt;/span&gt; &lt;span class="pl-s1"&gt;shaderSource&lt;/span&gt;&lt;span class="pl-kos"&gt;)&lt;/span&gt;&lt;span class="pl-kos"&gt;;&lt;/span&gt;
    &lt;span class="pl-s1"&gt;gl&lt;/span&gt;&lt;span class="pl-kos"&gt;.&lt;/span&gt;&lt;span class="pl-en"&gt;compileShader&lt;/span&gt;&lt;span class="pl-kos"&gt;(&lt;/span&gt;&lt;span class="pl-s1"&gt;shader&lt;/span&gt;&lt;span class="pl-kos"&gt;)&lt;/span&gt;&lt;span class="pl-kos"&gt;;&lt;/span&gt;
    &lt;span class="pl-k"&gt;const&lt;/span&gt; &lt;span class="pl-s1"&gt;compiled&lt;/span&gt; &lt;span class="pl-c1"&gt;=&lt;/span&gt; &lt;span class="pl-s1"&gt;gl&lt;/span&gt;&lt;span class="pl-kos"&gt;.&lt;/span&gt;&lt;span class="pl-en"&gt;getShaderParameter&lt;/span&gt;&lt;span class="pl-kos"&gt;(&lt;/span&gt;&lt;span class="pl-s1"&gt;shader&lt;/span&gt;&lt;span class="pl-kos"&gt;,&lt;/span&gt; &lt;span class="pl-s1"&gt;gl&lt;/span&gt;&lt;span class="pl-kos"&gt;.&lt;/span&gt;&lt;span class="pl-c1"&gt;COMPILE_STATUS&lt;/span&gt;&lt;span class="pl-kos"&gt;)&lt;/span&gt;&lt;span class="pl-kos"&gt;;&lt;/span&gt;
    &lt;span class="pl-k"&gt;if&lt;/span&gt; &lt;span class="pl-kos"&gt;(&lt;/span&gt;&lt;span class="pl-c1"&gt;!&lt;/span&gt;&lt;span class="pl-s1"&gt;compiled&lt;/span&gt;&lt;span class="pl-kos"&gt;)&lt;/span&gt; &lt;span class="pl-kos"&gt;{&lt;/span&gt;
        &lt;span class="pl-k"&gt;const&lt;/span&gt; &lt;span class="pl-s1"&gt;lastError&lt;/span&gt; &lt;span class="pl-c1"&gt;=&lt;/span&gt; &lt;span class="pl-s1"&gt;gl&lt;/span&gt;&lt;span class="pl-kos"&gt;.&lt;/span&gt;&lt;span class="pl-en"&gt;getShaderInfoLog&lt;/span&gt;&lt;span class="pl-kos"&gt;(&lt;/span&gt;&lt;span class="pl-s1"&gt;shader&lt;/span&gt;&lt;span class="pl-kos"&gt;)&lt;/span&gt;&lt;span class="pl-kos"&gt;;&lt;/span&gt;
        &lt;span class="pl-s1"&gt;gl&lt;/span&gt;&lt;span class="pl-kos"&gt;.&lt;/span&gt;&lt;span class="pl-en"&gt;deleteShader&lt;/span&gt;&lt;span class="pl-kos"&gt;(&lt;/span&gt;&lt;span class="pl-s1"&gt;shader&lt;/span&gt;&lt;span class="pl-kos"&gt;)&lt;/span&gt;&lt;span class="pl-kos"&gt;;&lt;/span&gt;
        &lt;span class="pl-k"&gt;return&lt;/span&gt; &lt;span class="pl-s1"&gt;lastError&lt;/span&gt;&lt;span class="pl-kos"&gt;;&lt;/span&gt;
    &lt;span class="pl-kos"&gt;}&lt;/span&gt;
    &lt;span class="pl-k"&gt;return&lt;/span&gt; &lt;span class="pl-s1"&gt;shader&lt;/span&gt;&lt;span class="pl-kos"&gt;;&lt;/span&gt;
&lt;span class="pl-kos"&gt;}&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Where &lt;code&gt;gl&lt;/code&gt; is a &lt;code&gt;canvas.getContext("webgl2")&lt;/code&gt; &lt;code&gt;WebGL2RenderingContext&lt;/code&gt; object, &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/WebGL2RenderingContext"&gt;described by MDN here&lt;/a&gt;.

    &lt;p&gt;&lt;small&gt;&lt;/small&gt;Via &lt;a href="https://lobste.rs/s/ycbpnz/animating_rick_morty_one_pixel_at_time"&gt;lobste.rs&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/animation"&gt;animation&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/canvas"&gt;canvas&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/javascript"&gt;javascript&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/webgl"&gt;webgl&lt;/a&gt;&lt;/p&gt;



</summary><category term="animation"/><category term="canvas"/><category term="javascript"/><category term="webgl"/></entry><entry><title>Write shaders for the Vegas sphere</title><link href="https://simonwillison.net/2023/Dec/1/write-shaders-for-the-vegas-sphere/#atom-tag" rel="alternate"/><published>2023-12-01T18:45:27+00:00</published><updated>2023-12-01T18:45:27+00:00</updated><id>https://simonwillison.net/2023/Dec/1/write-shaders-for-the-vegas-sphere/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="https://whenistheweekend.com/theSphere.html"&gt;Write shaders for the Vegas sphere&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
Alexandre Devaux built this phenomenal three.js / WebGL demo, which displays a rotating flyover of the Vegas Sphere and lets you directly edit shader code to render your own animations on it and see what they would look like. The via Hacker News thread includes dozens of examples of scripts you can paste in.

    &lt;p&gt;&lt;small&gt;&lt;/small&gt;Via &lt;a href="https://news.ycombinator.com/item?id=38463832"&gt;Hacker News&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/3d"&gt;3d&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/graphics"&gt;graphics&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/webgl"&gt;webgl&lt;/a&gt;&lt;/p&gt;



</summary><category term="3d"/><category term="graphics"/><category term="webgl"/></entry><entry><title>three.js examples: webgl_postprocessing_pixel</title><link href="https://simonwillison.net/2022/Dec/1/threejs-examples/#atom-tag" rel="alternate"/><published>2022-12-01T21:57:44+00:00</published><updated>2022-12-01T21:57:44+00:00</updated><id>https://simonwillison.net/2022/Dec/1/threejs-examples/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="https://threejs.org/examples/?q=pixel#webgl_postprocessing_pixel"&gt;three.js examples: webgl_postprocessing_pixel&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
Neat new example for three.js that uses a pixel-shader postprocessor to apply an isometric pixel-art feel to a 3D scene.

    &lt;p&gt;&lt;small&gt;&lt;/small&gt;Via &lt;a href="https://news.ycombinator.com/item?id=33814573"&gt;Hacker News&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/3d"&gt;3d&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/javascript"&gt;javascript&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/pixelart"&gt;pixelart&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/webgl"&gt;webgl&lt;/a&gt;&lt;/p&gt;



</summary><category term="3d"/><category term="javascript"/><category term="pixelart"/><category term="webgl"/></entry><entry><title>deeplearn.js imagenet webcam demo</title><link href="https://simonwillison.net/2017/Dec/5/deeplearnjs-imagenet-webcam-demo/#atom-tag" rel="alternate"/><published>2017-12-05T23:15:15+00:00</published><updated>2017-12-05T23:15:15+00:00</updated><id>https://simonwillison.net/2017/Dec/5/deeplearnjs-imagenet-webcam-demo/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="https://deeplearnjs.org/demos/imagenet/"&gt;deeplearn.js imagenet webcam demo&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
This is pretty astonishing... deeplearn.js is a Google Brain research tool that implements a GPU-accelerated neural network in browser-friendly JavaScript (using WebGL fragment shaders to run the algorithms). This demo hooks into your webcam and runs the SqueezeNet image recognition model against it, showing classification in real-time and providing a live-updating visualization of the different layers of the network.

    &lt;p&gt;&lt;small&gt;&lt;/small&gt;Via &lt;a href="https://www.robinwieruch.de/neural-networks-deeplearnjs-javascript/"&gt;Neural Networks in JavaScript with deeplearn.js&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/javascript"&gt;javascript&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/machine-learning"&gt;machine-learning&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/webgl"&gt;webgl&lt;/a&gt;&lt;/p&gt;



</summary><category term="javascript"/><category term="machine-learning"/><category term="webgl"/></entry></feed>