processing / p5.js

p5.js is a client-side JS platform that empowers artists, designers, students, and anyone to learn to code and express themselves creatively on the web. It is based on the core principles of Processing. http://twitter.com/p5xjs —
http://p5js.org/
GNU Lesser General Public License v2.1
21.72k stars 3.34k forks source link

webgl2 #2536

Closed diwi closed 1 year ago

diwi commented 6 years ago

Hi, Are there any plans in switching from webgl1 to webgl2? I did some tests on master; creating a webgl2 context in the p5.RendererGL and all examples I've tested seemed to work just fine.

Spongman commented 6 years ago

fwiw, https://caniuse.com/#feat=webgl2 shows pretty spotty support

stalgiag commented 6 years ago

Yeah I think for now WebGL 2 might not work with p5's investment in being usable across as many browsers as possible. WebGL 2 has significantly less support than ES6 and we are just now considering beginning to use ES6 standards.

Spongman commented 6 years ago

you could add a flag for setAttributes to enable it, but i doubt it'll get used much. i believe Three.js has webgl2 support if you're looking for bleeding-edge stuff.

diwi commented 6 years ago

wow, I wasn't aware of such bad support. Just tested edge, which I definitely expected it to support it, and it failed indeed. thx for the link.

diwi commented 6 years ago

here is another one: https://webglstats.com/

stalgiag commented 6 years ago

I'm going to close this for organization but this could definitely be readdressed down the line if support for 2 grows.

diwi commented 6 years ago

It could still be part of context creation since there are always 2 other fall-back options to pick from.

    this.drawingContext = this.canvas.getContext('webgl2', this.attributes)
                       || this.canvas.getContext('webgl', this.attributes)
                       || this.canvas.getContext('experimental-webgl', this.attributes)
                        ;
stalgiag commented 6 years ago

Hm yeah that would be simple enough. I guess the question is do you think there are any advantages to creating the context in gl2 if our code doesn't use any of the features of gl2?

diwi commented 6 years ago

Nah I agree, It's certainly not a pressing issue.

diwi commented 6 years ago

I've done some little experiments with the current p5-release and some raw webgl2. Besides that little mod from above to get the webgl2 context, it works well to combine both, p5 rendercalls and my webgl2-wrapper. Due to the mentioned support limitations it works only in firefox and chrome, ... plus in chrome I get a whole lot more fps.

https://diwi.github.io/p5.EasyCam/examples/ReactionDiffusion_Webgl2/

Lomacar commented 5 years ago

It could still be part of context creation since there are always 2 other fall-back options to pick from.

    this.drawingContext = this.canvas.getContext('webgl2', this.attributes)
                       || this.canvas.getContext('webgl', this.attributes)
                       || this.canvas.getContext('experimental-webgl', this.attributes)
                        ;

EDIT: Sorry, I'm an idiot. I forgot about the vertex shader.

Could somebody explain to me how this is supposed to work? I am trying to convert an old sketch from Processing (Java), in 2009 to P5. I don't know how my old shader ever worked because P5/Chrome complained that it was using features only supported in "GLSL ES 3.00 and above only", so I added the directive "#version 300 es" and THEN I got errors about all sorts of things in my shader that were from GLSL 1.0, so I updated all of those things. And once all of those were fixed I finally got the wonderful message that I was using an unsupported shader version! OK, so I found this discussion and added in the line about 'webgl2', and now I get an error saying "Snap! Error linking shader program: Versions of linked shaders have to match." But I have no idea what it is talking about, and this error is not explained anywhere on the internet.

torinmb commented 2 years ago

Just wanted to revisit this thread since WebGL 2 has support on all major browsers now. The only exception is IE, but there's support for Edge. https://caniuse.com/webgl2

Three.js opted to change their default WebGL renderer to WebGL2 and provide a helper function for WebGL1 if needed for backward compatibility.

aferriss commented 2 years ago

I'd be open to the change but i think we need to clearly define what the benefits to p5 would be both in terms of features and accessibility.

From glancing through the changes in webgl2, outside of some performance improvements, I'm not sure that I see big benefits for us, especially since our renderer is fairly limited in what it can do. I'd be happy to be wrong though!

Is there something specific you'd like to do that isn't possible with webGL1? I'm also not sure who would do this work, it's a pretty big project and fairly advanced to implement.

rennis250 commented 2 years ago

Is it possible though that WebGL 1 will be deprecated and then no longer supported in browsers at some point, or is the idea similar to HTML/CSS, where even the oldest versions of WebGL need to be supported in all browsers for as long as possible?

aferriss commented 2 years ago

I suppose anything is possible, but at this point I haven't heard anything about webGL1 being deprecated. I think it would be unlikely that that would happen, but I'm not privy to the plans of whoever is defining the webGL standards.

stalgiag commented 2 years ago

I would be surprised if webgl1 was deprecated but who knows.

Perhaps an argument could be made that webgl2 is the most common basis for current and future shader examples so by updating we make these examples/tutorials/educational resources relevant to people working with p5?

limzykenneth commented 2 years ago

It is hard to speculate about what the standards will do, eg. I've also heard WebGPU will supercede WebGL entirely but obviously it isn't really ready for prime time yet.

For me the consideration is the current recommendation of the standards, if the standards says nothing about the deprecation of WebGL 1, I don't think it is something we need to take into consideration. Even if at some point it is deprecated, support for it won't be removed for quite some time (took us long enough to fully get rid of Flash for example).

That said I'm not opposed to switching to WebGL 2 but the point made by @aferriss about it potentially being a big project and will require good amount of time and effort from someone still stands, and I think will be the larger point of consideration on balancing cost/benefit for now.

stalgiag commented 2 years ago

It is hard to speculate about what the standards will do, eg. I've also heard WebGPU will supercede WebGL entirely but obviously it isn't really ready for prime time yet.

For me the consideration is the current recommendation of the standards, if the standards says nothing about the deprecation of WebGL 1, I don't think it is something we need to take into consideration. Even if at some point it is deprecated, support for it won't be removed for quite some time (took us long enough to fully get rid of Flash for example).

That said I'm not opposed to switching to WebGL 2 but the point made by @aferriss about it potentially being a big project and will require good amount of time and effort from someone still stands, and I think will be the larger point of consideration on balancing cost/benefit for now.

I think this would be rather simple since webgl2 is backwards-compatible for webgl1. I haven't tested this but I would be surprised if it takes more effort than just switching the string passed to getContext(). This would of course not use any of the features. Making the renderer use the features would be a big job. But I think we could use diwi's code above and give people the option to use more up-to-date shader features without changing more than one line in our codebase.

rennis250 commented 2 years ago

It is hard to speculate about what the standards will do, eg. I've also heard WebGPU will supercede WebGL entirely but obviously it isn't really ready for prime time yet. For me the consideration is the current recommendation of the standards, if the standards says nothing about the deprecation of WebGL 1, I don't think it is something we need to take into consideration. Even if at some point it is deprecated, support for it won't be removed for quite some time (took us long enough to fully get rid of Flash for example). That said I'm not opposed to switching to WebGL 2 but the point made by @aferriss about it potentially being a big project and will require good amount of time and effort from someone still stands, and I think will be the larger point of consideration on balancing cost/benefit for now.

I think this would be rather simple since webgl2 is backwards-compatible for webgl1. I haven't tested this but I would be surprised if it takes more effort than just switching the string passed to getContext(). This would of course not use any of the features. Making the renderer use the features would be a big job. But I think we could use diwi's code above and give people the option to use more up-to-date shader features without changing more than one line in our codebase.

The basic switch is indeed only 2 steps and quite easy:

https://webgl2fundamentals.org/webgl/lessons/webgl1-to-webgl2.html

Taking advantage of the advanced features is another ordeal.

nakednous commented 2 years ago

I'd be open to the change but i think we need to clearly define what the benefits to p5 would be both in terms of features and accessibility.

From glancing through the changes in webgl2, outside of some performance improvements, I'm not sure that I see big benefits for us, especially since our renderer is fairly limited in what it can do. I'd be happy to be wrong though!

Is there something specific you'd like to do that isn't possible with webGL1? I'm also not sure who would do this work, it's a pretty big project and fairly advanced to implement.

I'm currently implementing shadow mapping (without success) and I think the ability to output custom variables in the fragment shader presented in WEBGL2 would make it much more easier.

DaveHoskins commented 2 years ago

I recently couldn’t use a random hash generator, because it used a uvec2, and was very surprised p5 was not accepting WebGL2 as a canvas. Especially this year, as now all Apple products are using Angle to support WebGL 2. So now all OSs can use it.

stalgiag commented 2 years ago

Re-opening this since webgl2 is broadly supported in browsers. Should p5 continue with no support, refactor for default support, or add optional support ? Optional support would change little for the library while offering more flexibility for those writing custom shaders.

If optional, does anyone have thoughts on the best way for someone to indicate that they want a 'webgl2' drawing context? Is it too much to have createCanvas(WEBGL) and createCanvas(WEBGL2)?

davepagurek commented 2 years ago

Do we want to make it easy for users to fall back to WebGL 1 on older browsers? Off the top of my head, I think we would need to change what setAttributes({ antialias: true }) does for WebGL2, but if that's the only change to internals that would need to be done, we could maybe even try to first create a WebGL2 context and then fall back to WebGL 1 if the browser doesn't support it. We might need to add an isWebGL2 method so sketches can tell if a fallback has been picked or not.

Some downsides would be that it might break things that use drawingContext to access WebGL internals, and that we would have to make any other new features backwards-compatible instead of just adding them to WebGL2 mode.

DaveHoskins commented 2 years ago

Yes, it should be easy to make it backward compatible, so it would be invisible for old P5 WebGL scripts.

torinmb commented 2 years ago

Any updates on the status of this?

davepagurek commented 2 years ago

@torinmb No progress just yet, mostly because I've been prioritizing other WebGL mode improvements for now, since WebGL2 doesn't affect core p5 features much. It's still on my to do list though!

Also I think features like this https://github.com/processing/p5.js/issues/5571 will likely require WebGL2 support, or at least benefit from it, in order to get antialiased renderbuffers, so whenever I get to that, this might come with it.

Vamoss commented 1 year ago

Hack to enable p5js WEBGL2:

p5.RendererGL.prototype._initContext = function() {
    try {
        this.drawingContext =
            this.canvas.getContext('webgl2', this._pInst._glAttributes) ||
            this.canvas.getContext('experimental-webgl', this._pInst._glAttributes);
        if (this.drawingContext === null) {
            throw new Error('Error creating webgl2 context');
        } else {
            const gl = this.drawingContext;
            gl.enable(gl.DEPTH_TEST);
            gl.depthFunc(gl.LEQUAL);
            gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);
            this._viewport = this.drawingContext.getParameter(
                this.drawingContext.VIEWPORT
            );
        }
    } catch (er) {
        throw er;
    }
};
nakednous commented 1 year ago

What's the current status of webgl2? Can we help implementing it? If so, what would be the main tasks?

davepagurek commented 1 year ago

The maintainers are going to discuss this soon, I'll update you sometime this week!

davepagurek commented 1 year ago

(apologies, hit the wrong button!)

davepagurek commented 1 year ago

Thanks for your patience everyone! We've decided to move forward with a plan for WebGL2. Here are our current thoughts about a specification for this feature:

Let me know if you have any comments or suggestions!

rennis250 commented 1 year ago

Sounds great! I think this is a nice start and it should be easy to re-orient the plan if any strange corner cases pop up.

Looking forward to it 😄

DaveHoskins commented 1 year ago

It's fantastic this is happening. I would love the ability to grab floating point pixels from frame buffers. Not just 8 bits. That would be very useful.

davepagurek commented 1 year ago

Oh one more task to make this happen: Updating the font shader to also support WebGL2. It currently relies on the standard_derivatives extension of WebGL1: https://github.com/processing/p5.js/blob/main/src/webgl/shaders/font.frag#L1

To use fwidth in WebGL2, one has to use a newer GLSL version. I have some code for another shader that handles both versions (messily) here: https://github.com/davepagurek/p5.Framebuffer/blob/main/ContactShadowRenderer.js#L169 We'd have to do something similar for the font shader.

sterlingcrispin commented 1 year ago

just leaving my vote here on WebGL2 🫡 would be great

davepagurek commented 1 year ago

I've started working on this now, I'll put up a PR once I've updated the text shader as well!

Vamoss commented 7 months ago

Hi @davepagurek, I am trying to use a shader function with WEBGL2 (P5 version 1.9.2), and I am getting this error:

shader() is only supported in WEBGL mode

Thank you in advance!

Vamoss commented 7 months ago

I just noticed that WEBGL2 is initialized by default, the error were caused when using WEBGL2 parameter on createCanvas 🙏

Thank you again and congratulations for the amazing work!