Open Vipitis opened 10 months ago
checked on my Laptop (nvidia T500) and there is also texture and geometry issues... but they are different. Will try to grab a a screenshot later. Something is wrong in the wgpu math, and I will try to break it down to a minimal example... could take a bit
Could be driver or hardware differences relating to precision. Are you comparing against official shadertoy on those devices too?
The experience on the website is consistent across devices (and good). According to the comments on the website, something might be going on... breaking it down to a minimal example might help.
I have been encountering other Shadertoys that look vastly different on the website versus with wgpu. At least some of this seems to be down to pow()
with negative numbers (but only when there is expressions). In fact, the website even warns you about using negative numbers here.
I produced this minimal example
website:
wgpu-shadertoy:
This might be one case where we can't really have a solution. Since it is undefined in GLSL so the behavior could really be anything.
I am looking at some other shaders where the behavior is different, and will try to reduce them to something minimal. Then post their differences here as well. Perhaps this Issue could become a "differences between the website and our implementation" thread.
Is the behaviour also undefined in WGSL?
The wgsl spec doesn't mention anything, it could be defined via exp
too.
I tried it with a quick translation and it behaves the same as GLSL in wgpu. The hole might go deeper, since hard coding any even number like 2.0
or 4.0
to be y, gives you the yellow, while hardcoding any odd number gives you the green. What happens in between is what differs between wgpu and website
E: it's still an open issue - https://github.com/gpuweb/gpuweb/issues/2765#issuecomment-1100112786
If you were to replace the implementation of pow()
with this macro, you get a matching result for the minimal example. Doesn't seem to fix stone tho. I will have to try some more.
#define pow(base, exponent) (exp2(log2(base) * (exponent)))
The other inconsistency I found was with a shadertoy like this: https://www.shadertoy.com/view/4sySRG and it seems to be down to nested loops. But that might really be a wgpu issue, could be similar to this: https://github.com/gfx-rs/wgpu/issues/5246
wgpu-py
v0.15.0 includes the fix for nested loops. And that fixed quite a lot of visual glitches with shaders like the one linked above.
However the example stone has not been fixed by this. I will have to take some time and dig deeper...
After some hours of trying to deconstruct this shader and find the function at the root of this errors... it seems to be sin
which lead to a different rabbit hole. But it seems like using sin with really large numbers behaves differently between GPUs and APIs.
I even got to the point where the website seems to behave more wrong than wgpu... (but that could be due to my Intel graphics card too). One of those examples is here: https://www.shadertoy.com/view/7tV3RV which finally lead me to this investigation: https://danilw.github.io/blog/Hash_Noise_in_GPU_Shaders/
So it seems like there won't be a good solution to this problem.
So essentially the shader in this example is relying on a broken noise function?
it's seems to be a common method for hash and noise functions. But those should just be slightly inconsistent across devices. Not straight up broken. So I believe there is another issue compounding onto it.
I will try to fork the shader and replace the noise functions with something that should be consistent to see if that solves it.
here is my attempt at a fork with different hash functions. https://www.shadertoy.com/view/M32SR3 however the issue remains. Will have to keep digging when I am back in a week
the example shadertoy_stone does not quite match with it's reference on the website:
website:
wgpu-shadertoy: