Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WebGL x regl different results #62

Open
augustoicaro opened this issue Oct 29, 2024 · 5 comments
Open

WebGL x regl different results #62

augustoicaro opened this issue Oct 29, 2024 · 5 comments

Comments

@augustoicaro
Copy link

augustoicaro commented Oct 29, 2024

Thank you Jeremy for this amazing work!

I found this project a few years ago. Finally, last week, I started my journey to adapt your matrix rain as Vivaldi background start page, as I did before with a simpler matrix rain, and then adapt the shader for Unity so we can have something like the Apple Vision Pro matrix effect.

On the Vivaldi browser adaptation, my first problem was a CORS related policy on Vivaldi that prevented regl from compiling the shaders. So I switched to webGL and noticed a huge difference in the bloom effect on my computer:

Screenshot from 2024-10-29 09-10-50

Investigating the bloom shader, I noticed a slightly different implementation from the regl shader, but even matching the shader code and decreasing the bloomStrength value, I didn't get the crisp text as in regl variant. So, testing the animation without the bloom effect, I noticed yesterday that webgl animation has a blur in the text:

Screenshot from 2024-10-29 09-09-02

I will investigate this blur today, but I decided to bring this issue up to see if you know what can be the cause of this issue.

Thanks for sharing this amazing matrix effect! 🫂

@Rezmason
Copy link
Owner

Rezmason commented Nov 3, 2024

Hi! Thank you for your interest, and your kind words. 😃 I'll look into this in more detail, but off the top of my head, I can confirm that the bloom implementation in my regl and webgpu regions of this project are different, produce slightly different results, and therefore may contain different bugs. 😆

image
🎶 we come from the land of the ice and snow, from the midnight sun, where the code rains flow 🎶

Speaking of subtle whoopsies, it looks like you misspelled bloomStrength in the WebGPU tab of your second screenshot, and so it may still be applying the bloom pass. That doesn't rule out a bug, but it might explain the blur in there.

I'll keep you posted. Thanks for pointing this out, and also for pointing out that what I do for free is selling for fifteen bucks on Apple's headset. 😆💸

@augustoicaro
Copy link
Author

Hi! Thank you for your interest, and your kind words. 😃 I'll look into this in more detail, but off the top of my head, I can confirm that the bloom implementation in my regl and webgpu regions of this project are different, produce slightly different results, and therefore may contain different bugs. 😆

I was wondering that. Can you confirm that the webgpu implementation produces different results with the default parameters? I will check that on my wife's Windows laptop.

image
🎶 we come from the land of the ice and snow, from the midnight sun, where the code rains flow 🎶

Lol! Nice catch! Was on point! 🤘

Speaking of subtle whoopsies, it looks like you misspelled bloomStrength in the WebGPU tab of your second screenshot, and so it may still be applying the bloom pass. That doesn't rule out a bug, but it might explain the blur in there.

Oh, thanks! I misspelled bloomSize. Let me fix the url and reduce the column number:
Screenshot from 2024-11-04 16-20-40
If we pick a 7 with similar brightness from each side, it will be easier to see that the font on the WebGL implementation is blurry:
7

I think this is related to a problem that I faced these past 2 days on the Unity port and is related to the regl rounding of symbol brightness on symbol.r = clamp(screenPxDistance + 0.5, 0.0, 1.0). On Unity, and I believe the same problem is happening on WebGL, this calculation results in a smooth transition from the font shape to the outside, creating the blur effect. I solved that by rounding the symbol.rg. I will try that on webgl later this week, and I will let you know.

I'll keep you posted. Thanks for pointing this out, and also for pointing out that what I do for free is selling for fifteen bucks on Apple's headset. 😆💸

You're welcome! But you still have time. You can publish for the Meta store focusing on Quest 3. Let me know if you want access to my Unity port.
My goal is to make a PoC Unity shader for the free productivity VR app called Immersed. Hopefully, they can create an environment with the shader, and I will finally be able to work inside the Matrix 😎

Today, I figured out the main problems on Unity to make it work with raindrop and palette pass. Porting the bloom effect today 🚀

@Rezmason
Copy link
Owner

Rezmason commented Nov 5, 2024

Can you confirm that the webgpu implementation produces different results with the default parameters?

The parameters passed into them are the same, but the webGPU bloom and the regl bloom were implemented separately.

bloomBlur.wgsl and bloomPass.blur.frag.glsl have the same responsibilities but I don't think their kernels are even the same size.

bloomCombine.wgsl and bloomPass.combine.frag.glsl are also quite different. I might even have different size image pyramids in here.

Either of those large differences would be reason enough for the blur to look different between my two renderers. One other theory, though, is that the WebGPU bloom pass may be setting a different base resolution than the regl pass.

From the perspective of a Unity port, I would suggest that you go with your gut when implementing the bloom. My regl code supports WebGL 1.0, and whatever version of Unity you're working in is way past that, so it might as well play outside the confines of an API designed in, what, 2008? Better bloom awaits us all.

As for the symbol brightness shader code you mention, that's almost verbatim MSDF rendering stuff.

void main() {
	// Bilinear sampling of the distance field
	vec3 s = texture2D(sdf, P).rgb;
	// Acquiring the signed distance
	float d = median(s.r, s.g, s.b) - 0.5;
	// The anti-aliased measure of how "inside" the fragment lies
	float w = clamp(d/fwidth(d) + 0.5, 0.0, 1.0);
	// Combining the two colors
	gl_FragColor = mix(outsideColor, insideColor, w);
}

—that's from Viktor Chlumsky's master's thesis. It's a fun one to skim. A-Frame's got it in theirs, too, so if your wife is using her laptop for something important, this particular tree probably isn't worth barking up just yet. 😉

@augustoicaro
Copy link
Author

Can you confirm that the webgpu implementation produces different results with the default parameters?

The parameters passed into them are the same, but the webGPU bloom and the regl bloom were implemented separately.

bloomBlur.wgsl and bloomPass.blur.frag.glsl have the same responsibilities but I don't think their kernels are even the same size.

bloomCombine.wgsl and bloomPass.combine.frag.glsl are also quite different. I might even have different size image pyramids in here.

Yeah, I noticed that too. I also adjusted the WebGL code to have a similar behavior to the regl implementation, but I didn't get the desired results 🥲

Either of those large differences would be reason enough for the blur to look different between my two renderers. One other theory, though, is that the WebGPU bloom pass may be setting a different base resolution than the regl pass.

If this is the case, reducing the bloomStrength solved the problem for me.

From the perspective of a Unity port, I would suggest that you go with your gut when implementing the bloom. My regl code supports WebGL 1.0, and whatever version of Unity you're working in is way past that, so it might as well play outside the confines of an API designed in, what, 2008? Better bloom awaits us all.

🚀

As for the symbol brightness shader code you mention, that's almost verbatim MSDF rendering stuff.

void main() {
	// Bilinear sampling of the distance field
	vec3 s = texture2D(sdf, P).rgb;
	// Acquiring the signed distance
	float d = median(s.r, s.g, s.b) - 0.5;
	// The anti-aliased measure of how "inside" the fragment lies
	float w = clamp(d/fwidth(d) + 0.5, 0.0, 1.0);
	// Combining the two colors
	gl_FragColor = mix(outsideColor, insideColor, w);
}

—that's from Viktor Chlumsky's master's thesis. It's a fun one to skim. A-Frame's got it in theirs, too, so if your wife is using her laptop for something important, this particular tree probably isn't worth barking up just yet. 😉

I was reading his master's thesis yesterday to try to understand my problem with Unity. I'm sure it's related to float precision since I'm not able to control it that well on HLSL, like define a global precision as you did on GLSL. I'm not familiar with Unity, and most of the big problems that I had I solved by changing a Unity option 🤦‍♂️
The latest one was the MSDF rendering part generating a square in the border of the texture. I was almost one day trying to discover the problem. In the end Unity was reading the MSDF glyph texture with the wrong format. After changing to RGBA Float and doing the rounding, it fixed the problem for me 🥲

@augustoicaro
Copy link
Author

Circling back to the problem, I tried the solution that I used on Unity, but it didn't help. It just reduced the antialias, but I still have a blur in the font using webgpu renderer. When I have more time, I will return to find the root of this problem and submit a PR.

I finished the Unity port for the 2D version of the shader and a simple tri-planar mapping strategy for the same texture, but using the same 2D texture strategy for 3D doesn't generate a seamless effect. Now, I'm adapting the code for something more in this line: https://github.com/IRCSS/MatrixVFX/tree/master?tab=readme-ov-file

I'm happy with the results so far. Thank you again for your work and for sharing valuable tips and resources 🙏

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants