[HN Gopher] Three.js Shading Language
       ___________________________________________________________________
        
       Three.js Shading Language
        
       Author : bpierre
       Score  : 118 points
       Date   : 2024-05-29 10:41 UTC (12 hours ago)
        
 (HTM) web link (github.com)
 (TXT) w3m dump (github.com)
        
       | stanleykm wrote:
       | Almost like the old days of fixed function pipelines. The example
       | at the top seems a little contrived, I wonder why you would build
       | a shader like that.
        
         | bhouston wrote:
         | Huh? It allows for programming via JavaScript which is then
         | transpiled for WebGL or WebGPU. It doesn't seem fixed function
         | at all.
        
           | stanleykm wrote:
           | Yeah I get what it is, I was just making an observation of
           | how the api appears.
        
         | dahart wrote:
         | It's common in lots of modern tools to build shader trees using
         | UI, this is analogous to that. It's not really fixed function
         | because you can make your tree/shader as big as you want and it
         | has all of the math functions that GLSL has. Fixed function
         | usually means something like a limited fixed set of nodes and
         | you can turn the constant knobs.
         | 
         | Unless I missed it somewhere, the two nodes that seem to be
         | missing here are an if() node and a loop() node. I'm guessing a
         | loop() node can be done on the JavaScript side for small loops
         | - it'd be the same as loop unrolling. For big loops or loops
         | with unknown bounds at compile time, it's not clear if there's
         | a way with TSL. You can simulate if() behavior using the nodes
         | provided, but you can't avoid executing both sides of the if().
         | 
         | It's been a long time since I wrote a three.js shader, so I'm
         | not sure what the "old" example is doing. It looks like it
         | might be a little dynamic code injection to convert from a
         | typical GLSL shader to something three.js needs.
        
           | hansworst wrote:
           | > big loops or loops with unknown bounds at compile time
           | 
           | That's not allowed in webgl, so I doubt TSL can make it work
           | somehow.
        
             | dahart wrote:
             | What do you mean, and are you sure? It works in ShaderToy.
             | Big loops will happily unroll until the compiler crashes.
             | There's a standard trick for doing variable length loops
             | (and preventing unrolling): https://shadertoyunofficial.wor
             | dpress.com/2017/11/19/avoidin...
        
         | araes wrote:
         | Some of the other examples in Three.js are quite a bit more
         | complex. https://threejs.org/examples/#webgl_lights_physical
         | 
         | Probably just for introductory ease. Although, admittedly,
         | appears to give the impression of nerfed features, rather than
         | easy.
        
       | lifthrasiir wrote:
       | TSL is not really a language to be pedantic, because it is an
       | EDSL to build a common AST that can be translated to the target
       | shader language later. All caveats for the overly eager
       | evaluation and usual impedance mismatch between JS and TSL data
       | model also apply here.
        
         | javawizard wrote:
         | Without discounting any of your other points, I just have to
         | note the irony in saying:
         | 
         | > TSL is not really a language to be pedantic, because it is an
         | EDSL
         | 
         | where the "L" in "EDSL" stands for "language" :)
        
           | btown wrote:
           | Just like any sufficiently complex program inevitably grows
           | to have both a reimplementation of Lisp _and_ a homegrown
           | email client... any sufficiently complex library inevitably
           | grows to have people arguing about whether it deserves the
           | term language or not!
           | 
           | EDIT: I wish I were smart enough to have come up with these
           | references, but I'm entirely riffing on
           | https://en.wikipedia.org/wiki/Greenspun%27s_tenth_rule and
           | https://en.wikipedia.org/wiki/Jamie_Zawinski#Zawinski's_Law .
           | I can say from personal experience that both adages are
           | resoundingly true.
        
       | bhouston wrote:
       | I've seen this done in C++ for generating GLSL before a few
       | times.
       | 
       | One from Waterloo Univeesity in the early 2000s became RapidMind:
       | http://web.cs.ucla.edu/~palsberg/course/cs239/papers/rapidmi...
       | 
       | There were a few others, but I can not remember their names.
       | 
       | Generally these techniques work, but for some reason they tend to
       | die out.
        
       | 10000truths wrote:
       | One thing I'd love to see is whether bundlers can "statically
       | compile" the TSL nodes via constant propagation into a single
       | template literal.
        
       | CountHackulus wrote:
       | What if we stopped adding layers of abstraction? The idea of
       | renderer-agnostic shaders is cool, but in general you want to
       | write your shaders for a specific renderer for best performance.
        
         | nh23423fefe wrote:
         | What if we have different objectives?
        
         | onion2k wrote:
         | If you're writing for three.js and GLSL you've already forgone
         | best performance. This is for render agnostic web code - it
         | could be running on anything from a low end android tablet to a
         | gaming PC, in any browser engine new enough to support WebGL.
         | Most developers who use it are looking for a usable API that
         | works everywhere possible, and they don't really care _that_
         | much about perf because it 'll be faster than all the
         | alternatives (JS, canvas, SVG, CSS) even if it's pretty slow
         | for a GPU.
        
       | stevebmark wrote:
       | Looks interesting! There is always a tension between high level
       | paradigms like this and just writing the damn GLSL. glslify is
       | another solution in this space that lets you have more fine
       | control over the GLSL, which is usually way less verbose than a
       | high level API.
        
       | jasonjmcghee wrote:
       | Has anyone taken a crack at building a shading language debugger?
       | 
       | I want to be able to step through a shader and see the values at
       | each step (ideally for any / every pixel)
       | 
       | The best case scenario would be while it's actually running, but
       | simulating it seems like a great solution too.
       | 
       | These are the best I could find: https://github.com/burg/glsl-
       | simulator and https://github.com/cdave1/shdr - both seem to be
       | missing a fair amount of features, though shdr seems like much
       | better support.
       | 
       | There's also: https://glsl-debugger.github.io/ but it doesn't
       | support OS X and feels quite out of date.
       | 
       | There's "print statements" for wgsl:
       | https://github.com/looran/wgsl-debug
       | 
       | I guess WGSL is the up and comer... as opposed to GLSL - but both
       | would be great.
       | 
       | Anyone else have this hope/dream?
       | 
       | The hacks I use today are crazy - like conditionally exiting
       | early based on a time variable and mapping values to colors.
       | 
       | So many folks I talk to are like, "yeah that's how it is". But
       | this just seems not good enough to me...
        
         | kevingadd wrote:
         | RenderDoc has step-through debugging at a pixel and fragment
         | level. Click a pixel in the render target view, then open the
         | history and select the fragment to debug.
        
         | colonwqbang wrote:
         | There is good tooling available, but it tends to be vendor-
         | specific and sometimes quite expensive. Here is Arm's tool:
         | https://developer.arm.com/Tools%20and%20Software/Graphics%20...
        
         | xpl wrote:
         | I think with that threejs' TSL approach there is an opportunity
         | to simulate computations in JS instead of translating it to
         | GLSL. Just need to write an eagerly-evaluating runtime for
         | those EDSL expressions.
         | 
         | Once it's done, you'll be able to use the regular Chrome's
         | Devtools debugger to step through TSL logic.
         | 
         | A nice thing is that would also allow you to unit-test your
         | shading code using regular JS frameworks for testing.
        
       | pjmlp wrote:
       | This is what happens when everyone decides to break compatibility
       | with the shading languages for the Web, instead of what happened
       | with Khronos APIs on the native side.
       | 
       | On the other side, it is business as usual given GLSL, HLSL, MSL,
       | Slang, PSSL,...
        
         | dahart wrote:
         | What do you mean? This is GLSL... a light abstraction on top of
         | it anyway, but not a different shading language or breaking
         | compatibility. The goal is just to write the GLSL shaders in
         | JavaScript.
        
           | pjmlp wrote:
           | WebGPU uses WGSL, completely different shading language, Rust
           | inspired.
           | 
           | Naturally ThreeJS has to now take care how to provide shaders
           | that work across both backends.
        
             | rahkiin wrote:
             | GLSL is pretty bad though. Terrible typing system, terrible
             | inference, terrible archaic requirements. Awful
             | annotations.
             | 
             | Metal and HLSL are more modern. Mostly because Metal
             | started as such and HLSL was updated. Both C++ inspired or
             | even using clang. WGSL has a rust-like syntax but Metal-
             | like semantics and structure.
        
       ___________________________________________________________________
       (page generated 2024-05-29 23:01 UTC)