[HN Gopher] Show HN: Make 3D art in your browser using Lisp and ...
       ___________________________________________________________________
        
       Show HN: Make 3D art in your browser using Lisp and math
        
       Bauble is a toy that I've been working on for a few weeks, and I
       think it's reached the point where other people could have fun with
       it!  Bauble is based on raymarching signed distance functions,
       which are kind of like... 3D vector art? They're pretty common in
       the procedural art community and you can do some amazing things
       with them, but normally writing SDFs means writing low-level shader
       code.  I wanted to play with SDFs, but I found it very frustrating
       to translate "I want to rotate this" into "okay, that means I have
       to construct a rotation matrix, and then apply it to the current
       point, and _then_ evaluate the shape... ". So I made a high-level
       Janet DSL that compiles down to GLSL shader code so I could more
       easily play with mathematically defined shapes.  For more about
       SDFs, this mind-blowing video is what got me interested in the
       first place, and shows you what they're capable of in the hands of
       an expert: https://www.youtube.com/watch?v=8--5LwHRhjk
        
       Author : ianthehenry
       Score  : 160 points
       Date   : 2022-09-06 15:41 UTC (7 hours ago)
        
 (HTM) web link (bauble.studio)
 (TXT) w3m dump (bauble.studio)
        
       | dejongh wrote:
       | Nice!
        
       | chaosprint wrote:
       | Wow, this is so beautiful! Your web app demo is very neat.
       | 
       | Do you think this can be used for live coding visuals?
       | 
       | I'd love to use it together with Glicol(https://glicol.org).
       | 
       | So far I have tested Hydra and p5.js; they can be used as CDN
       | link or NPM packages.
       | 
       | Look forward to its progress.
        
         | ianthehenry wrote:
         | Thanks! I'm not really sure how to make it work with Glicol --
         | I don't know anything about the livecoding world. But _in
         | theory_ it would be easy to add a new  "magic variable" (shader
         | uniform) for like "mean root squared audio sample amplitude
         | over the last frame..."? You'd just need some way for Glicol to
         | tell Bauble what the value should be. I don't know how they'd
         | communicate or if there's some standard for integrating music
         | and visuals...?
         | 
         | Apart from that big question mark I think it would be very
         | suitable for livecoding visuals, as you can write some
         | impressive effects with very little code. Easy CSS change to
         | make the canvas full-screen and like overlay the code on top of
         | it. That's a thing that livecoders do, right?
        
           | ynx wrote:
           | > if there's some standard for integrating music and
           | visuals...?
           | 
           | In terms of translating audio to variables useful for driving
           | visuals, ColorChord is getting some traction; it's an
           | algorithm that powers a technology called AudioLink, which is
           | growing beyond its origins in VRChat.
           | 
           | https://github.com/cnlohr/colorchord
           | 
           | https://www.colorchord.net/
           | 
           | https://github.com/llealloo/vrc-udon-audio-link
           | 
           | https://github.com/llealloo/vrc-udon-audio-
           | link/blob/master/...
        
           | chaosprint wrote:
           | Something like this:
           | 
           | https://youtu.be/iKj7IibG0OU
           | 
           | I think both Hydra and p5.js render things to a <canvas>,
           | which is probably the same as what your demo does, right?
           | 
           | Then we just need to set some CSS for the Canvas to make it
           | full screen and hide behind the code editor.
        
             | ianthehenry wrote:
             | Ohhh I think I misunderstood how this works. You write the
             | visualization ahead of time, and then you livecode the
             | music only? Bauble would work well for that -- you could
             | just grab the compiled shader source and integrate it into
             | your livecoding environment; wouldn't even need to
             | integrate the Bauble runtime. All you'd need to do is set a
             | few uniforms and issue a draw call.
             | 
             | I was imagining something where you switch between coding
             | audio and visuals on the fly -- which is still totally
             | possible, but would require a bit of work to get them
             | talking to each other.
        
               | chaosprint wrote:
               | Well sometimes you change the visual code also in real-
               | time. The video above was just for showing the canvas
               | works so I did not edit the visuals code there.
               | 
               | I post the hydra link here. There are lots of demo there:
               | 
               | https://hydra.ojack.xyz/
               | 
               | So far I haven't tried to make them talk such as sync the
               | beat etc. But I think with web worker it is doable.
        
               | ianthehenry wrote:
               | Ohhh I totally missed that you're the author of Glicol.
               | Okay. So you integrated Hydra as like a first-class thing
               | -- I see I see. I thought you were plugging two 3rd party
               | things together.
               | 
               | So I'm guessing that the best case scenario for you is to
               | import Bauble as like a normal JavaScript dependency, and
               | then use the editor built into the Glicol UI to write
               | scripts, and then just call like Bauble.compile(canvas,
               | script). Right?
               | 
               | Bauble doesn't really know how to be embedded in another
               | page right now -- it's more like an app than a library.
               | But it would be possible to extract the core parts. It's
               | a little tricky because it uses WASM, so it kinda needs
               | to load itself a little specially, but I'm sure there's
               | some way around that.
               | 
               | Would be cool to sync something like this to music! https
               | ://twitter.com/ianthehenry/status/1567228698373533696
               | (ignore the terrible lighting. lights are coming one day)
        
               | chaosprint wrote:
               | Yeah. Glicol language and audio engine is written in Rust
               | and compiled to WASM. I still manage to export the WASM
               | module to an NPM package (https://glicol.js.org/). But
               | Emscripten may be a little bit different, but there will
               | always be some solution I guess. I've watched your repo
               | haha.
        
       | anhner wrote:
       | Sorry for my ignorance, but what kind of lisp has piping? Or what
       | is the vertical line operator called?                   (torus :z
       | 60 30         | twist :y 0.07         | rotate-pi :y t :z 0.05
       | ...
        
         | ianthehenry wrote:
         | This is described later in the tutorial (ctrl-f "lisp heresy").
         | It's a macro that I wrote, not something built into Janet --
         | I'm sure I'm not the first person to do this, but I'm not aware
         | of any lisps that have such a construct built-in.
        
           | spapas82 wrote:
           | Clojure has the thread first/last macros -> and ->> which
           | pipes each result to the next form.
        
             | ianthehenry wrote:
             | Yeah, and Janet copies Clojure's threading macros (that's
             | how I implemented pipe syntax -- split on pipes, add some
             | parens, and stick them into a -> form). I've just never
             | seen it done infix like this -- it's very convenient when
             | you don't have something like paredit to quickly wrap an
             | expression.
        
       | tehsauce wrote:
       | Shamelessly mentioning our project shaderpark, which is also a
       | live-coding interface for working with SDFs but using javascript!
       | 
       | https://shaderpark.com/
        
         | stasilo wrote:
         | cool! never heard of your project, I've actually written
         | something a bit similar :D
         | https://github.com/stasilo/retrace.gl
        
           | tehsauce wrote:
           | Oh cool, that looks really nice! One of the fun things that
           | our library does is that while it has built-in abstractions
           | for SDFs, you can also just write pretty much whatever kind
           | of shader (2D or anything) you want.
        
         | chaosprint wrote:
         | looks nice
        
       | billconan wrote:
       | Is there a good framework for creating the same online ide/code
       | demo as yours?
       | 
       | I want to make a live tutorial, I'm thinking about creating a
       | static site generator to generate the same kind of demo you have
       | here.
        
         | [deleted]
        
         | ianthehenry wrote:
         | I'm using https://codemirror.net/ as the editor, and I'm
         | basically just running an onchange event on every keystroke.
         | Not very fancy or sophisticated. The details of what exactly
         | happens in that event are very specific to WASM/Janet/Bauble,
         | but I think you could do something similar with JavaScript code
         | pretty trivially.
         | 
         | Long-term I think I'd rather break this out into a separate
         | page with multiple canvases inline in the text -- so you can
         | more easily scan through it/go back to previous sections -- but
         | I was lazy and this was the easiest way to get it done.
         | 
         | Also, this is just a static site. With hand-written HTML
         | because I've been too lazy to configure a static site generator
         | yet...
        
       | averysmallbird wrote:
       | This is beautiful. My apologies if I missed it, but is it
       | possible to download the produced figure as an STL (or something
       | equivalent)?
        
         | stasilo wrote:
         | I've written a tool somewhat similar that can export meshes of
         | sdf's created using a javascript api, check it out:
         | https://github.com/stasilo/retrace.gl
        
         | ianthehenry wrote:
         | No; Bauble doesn't know how to "rasterize" SDFs into meshes; it
         | only knows how to raymarch them. It's theoretically possible,
         | but it's a pretty complex problem that would take me much too
         | long to figure out and implement. So Bauble is relegated to
         | just making pretty pictures for now. If you want to produce
         | meshes using SDFs, check out https://libfive.com/
        
           | averysmallbird wrote:
           | Thanks!
        
         | frabert wrote:
         | I think that would be quite difficult, as raymarching does not
         | produce polygons, so you'd need a way to polygonize the
         | resulting sdf. Maybe marching cubes?
        
         | jcynix wrote:
         | Surely not "something equivalent" that you are expecting, but
         | my smartphone can do screen recordings, so here's a cropped
         | version of what's displayed in its browser:
         | http://www.cynix.net/2022/screenrecording-baubel.mp4
         | 
         | I cropped the screen recording to square format with the online
         | service at clideo.com so they added their watermark.
        
           | ianthehenry wrote:
           | STL is a format for 3D geometry, so the GP is asking if
           | there's a way to export the 3D models themselves. Bauble
           | _will_ have a way to export recordings eventually! That 's
           | much easier to do than meshing surfaces.
        
             | jcynix wrote:
             | Thanks, I did guess that it might be some specific format
             | and not just a screen recording, but all these TLAs are
             | hard to memorize.
             | 
             | BTW, it's a really nice example of the possibilities of
             | Lisp, which reminds me to refresh my memories and start
             | coding in Lisp again.
        
       | icu wrote:
       | This is awesome, how did you implement the live code editor?
        
         | ianthehenry wrote:
         | It's CodeMirror! All I had to do was write a Janet grammar for
         | it -- very easy to do. CodeMirror is pretty amazing -- I was
         | able to implement the "edit values with your mouse" by just
         | asking CodeMirror for the syntax node under the cursor,
         | checking if it parsed as a number, and if so replacing it with
         | a different string.
         | 
         | https://codemirror.net/
         | 
         | https://github.com/ianthehenry/codemirror-lang-janet
         | 
         | I went with CodeMirror after reading this post:
         | https://blog.replit.com/codemirror and I've been super happy
         | with it.
        
       | fros1y wrote:
       | You should check out libfive! https://libfive.com/studio/.
       | Previously discussed here:
       | https://news.ycombinator.com/item?id=26930822. It is the child of
       | Ao, previously discussed here:
       | https://news.ycombinator.com/item?id=12319406.
        
         | ianthehenry wrote:
         | libfive is great! And if you're into SDFs, libfive will give
         | you something Bauble probably never will: the ability to export
         | shapes as meshes, so you can 3D print them or import them into
         | Blender or whatever.
         | 
         | libfive is only concerned with geometry, though, so you can't
         | do any of the coloring/shading/procedural graphics stuff. And
         | no animations. I think of Bauble as closer to Shadertoy than
         | libfive in purpose, although they appear very similar.
        
         | [deleted]
        
       | andrewstuart wrote:
       | If you like this sort of thing then also
       | 
       | https://www.glslsandbox.com/?page=4
       | 
       | and
       | 
       | https://www.shadertoy.com
       | 
       | Unfortunately glslsanbox is not moderated very well so there's
       | lots of spammy garbage there but also lots of really great stuff.
        
       ___________________________________________________________________
       (page generated 2022-09-06 23:00 UTC)