earth-tattoo6 hours ago
Nice article. What a joy to read. Reminds me of what hacker news was until a few years ago!
I haven't worked with opengl/shaders in a while, but was thinking about some algorithm I wrote a few years ago, while in shower yesterday. It brought back the memories of how difficult it was for me to first understand the whole concept of shaders. There's basically no main function, no for loops etc. Your shader is called for each pixel, for every frame. I was wondering how easy it would have been in today's world. I spent like 2 months on something that is just a prompt now.
jasonjmcgheean hour ago
There absolutely is a "main" function in GLSL. This is the entry point.
And there are for loops- and if statements, and function declarations, etc. It's very c-like without dynamic memory allocation and executed in a highly parallel context.
Your shader is also not necessarily called every frame, you control this. It could be called multiple times per frame or only at certain times.
Fragment shaders (one type of shader) is called for each fragment of the rendered geometry - in 2D or in screen space this is just a quad so effectively a panel of pixels.
You get to know your own location with something like UV or a pixel coordinate if you pass it from a vertex shader, so that you can sample input textures as needed to build whatever it is you're building.
If you're not doing multiple render targets, your only responsibility is setting to the fragment color variable which will be the final color of that pixel for the output texture.
And that could in turn be the input to another shader etc.
I usually recommend https://thebookofshaders.com/
It's very sad this was never completed. It's so good.
mitxela4 hours ago
If you prompted a shader today, you still wouldn't understand shaders. The LLM also has absolutely no understanding of whether a graphical effect looks good.
ACS_Solver2 hours ago
I'm in game dev but I also have very poor abilities for mentally operating on visual or geometrical data. I'm normally far away from the graphics parts but sometimes I take a look and shaders are by far the least intuitive type of code to me. I've learned enough about what shaders do to sort of parse the simple ones, but anything with shaders definitely feels like working against my brain's natural tendencies.
onion2k3 hours ago
Claude is good[1] at writing shaders. It can take a description and turn it into working GLSL code for relatively complex effects.
[1] Better than me anyway.
Sharlin3 hours ago
Should be noted that `fract(x)` is importantly only equivalent to `x - floor(x)` when x >= 0. Which it was in this case, but often negative values are also possible/expected and the latter should be used instead. This is an easy mistake to make.
SomeonesAccount42 minutes ago
*former
Good catch. OP should probably update the article
Sharlin14 minutes ago
No, the latter. Usually we want to decompose x to floor(x) and whatever's left over, which is x - floor(x) and always nonnegative. fract(x) gives the leftover of trunc(x) instead and is negative when x is negative, and it's usually a logic error for a lerp variable to be outside [0, 1]. In this case, it creates artifacts along the coordinate axes.
[deleted]7 minutes agocollapsed
flohofwoe4 hours ago
It turned out to be something different, but another much more common source of shader output differences is when a float value is clamped to integer (with the value being very close to the closest integer), and then use the clamped value as index (or tex coord with an unfiltered sampler). This may result in an off-by-one error on some gpu/driver combos but not others. Completely understandable why it happens, but hard to catch unless testing on a wide range of GPUs and drivers.
TL;DR: don't expect that floating point operations on GPUs are strictly IEEE-754 compatible
kg4 hours ago
The classic HLSL compiler is infamous for being full of bugs (and slow, for that matter) so I wasn't surprised to see it come up here...
Fantastic seeing the author lay out all the steps involved in getting a renderdoc capture of a browser and what's involved in debugging shader issues in a webpage.
It's interesting that the issue only manifested on the geforce 40xx if it was an fxc issue though... wonder if it's fxc combined with a driver issue and not just one or the other?
CrociDB4 hours ago
hey! author here. I think I missed the opportunity to mention that, it wasn't only reproducible on the 40xx. it was my first hypothesis, but after I figured out it was a DirectX11 issue, i was able to reproduce on another windows machine with a different configuration. I just didn't have enough windows machines available to begin with. :)
LoganDark4 hours ago
> Root cause: Nvidia driver 595.79 (RTX 4070) miscompiles GLSL fract() usage in this shader’s context for large-magnitude operands (~100–1000): the returned fractional part is temporally discontinuous (moves smoothly, then jumps).
It looks like the LLM hallucinated a diagnosis of a miscompilation based on which fix worked. I would not treat its claim as accurate without further investigation.
Edit: Read the rest of the article and it looks like further investigation was performed, and it had nothing to do with the GPU driver after all. Good stuff.
xyzsparetimexyz3 hours ago
Good investigation! The whole webgl stack is such a piece of shit huh