pygfx / shadertoy

Shadertoy implementation based on wgpu-py
BSD 2-Clause "Simplified" License
11 stars 1 forks source link

Issue with example stone #11

Open Vipitis opened 8 months ago

Vipitis commented 8 months ago

the example shadertoy_stone does not quite match with it's reference on the website:

  1. mouse event stops the rotation #14
  2. odd lines in the "texture" (will test this on a different system too)
  3. straight cut in the geometry

website: website reference

wgpu-shadertoy: snapshot method

Vipitis commented 8 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

Korijn commented 8 months ago

Could be driver or hardware differences relating to precision. Are you comparing against official shadertoy on those devices too?

Vipitis commented 8 months ago

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.

Vipitis commented 7 months ago

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: website screenshot

wgpu-shadertoy: snapshot_method

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.

Korijn commented 7 months ago

Is the behaviour also undefined in WGSL?

Vipitis commented 7 months ago

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

Vipitis commented 7 months ago

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

Vipitis commented 6 months ago

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...

Vipitis commented 6 months ago

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.

Korijn commented 6 months ago

So essentially the shader in this example is relying on a broken noise function?

Vipitis commented 6 months ago

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.

Vipitis commented 6 months ago

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