What's going on with WebGL2? WebGPU?

Webgl2 seems like it’s been coming for a long time with issues in three.js about WebGL2Renderer dating back years but there haven’t been a lot of features added around it. The MRT PR, which is something I’m particularly interested in for deferred renderering, has been ready to go and on the upcoming milestone for the better part of a year but the PR hasn’t been merged yet.

It doesn’t seem to be three.js specifically either – I saw this twitter thread which mentions that Safari doesn’t support webgl2 and apparently progress hasn’t been made for years.

I was originally excited for whatever WebGL2 might enable but if Apple won’t support it then it doesn’t really seem usable. So I guess I’m curious as to what the plans are and what the future landscape seems to look like. Will three.js not really support any WebGL2 specific features? Will we have to wait for the WebGPU API maybe years out to have some more modern features like MRT? How are people handling their own applications?

If anyone has any more information on upcoming news or movement in this space I’d be excited to hear more! So much seems to happen behind the scenes.

Also, what happened to https://webglstats.com/ ? It used to be a very useful site to track WebGL2 support accross devices and browsers, but it seems to be down.

Progress is being made — see https://twitter.com/modeless/status/1227112617795149825.

If safari is not supported, it means that a tiny minority of people will not be able to view your content and will have to install Chrome.

here are some stats:


https://netmarketshare.com/browser-market-share.aspx

For comparison, Internet Explorer has 200% market share of Safari. So… I would say it’s mostly irrelevant. I like apple products as much as the next guy, but I don’t use Safari, personally.

1 Like

On desktop, maybe, but iOS is ~50% of U.S. mobile users, and Safari is the only browser engine on that platform — Chrome and Firefox on iOS must still use Safari internally.

5 Likes

I have iOS 12.1 and it looks like there are some Webgl2 & WebGPU experimental features that the Safari team is working on. It’s not full support yet, but I’m optimistic that there’s some progress being made in that direction.

@donmccurdy

Progress is being made — see https://twitter.com/modeless/status/1227112617795149825 .

That’s great to hear. I guess there is hope! Half of me is wondering if the reason the MRT hasn’t been merged is because WebGL2 doesn’t seem to be universally supported yet? Maybe @Mugen87 or @mrdoob can shed some light on that?

 

@marquizzo

I have iOS 12.1 and it looks like there are some Webgl2 & WebGPU experimental features that the Safari team is working on. It’s not full support yet, but I’m optimistic that there’s some progress being made in that direction.

The footnote on caniuse says “Has an option to enable via the “Experimental Features” developer menu but fails 77% of the WebGL2 conformance tests make it nearly unusable and has not seen any development activity in over 3 years”, so that flag wasn’t really promising…

1 Like

I heard that Apple is adopting ANGLE for their WebGL 2 implementation and there’s hope for it to be enabled in the next version of iOS.

As per the MRT PR, it sure is influenced by Safari not supporting it yet.

I’m not a big fan of multiple code paths, but even less of a fan when these paths do not work on some phones and people ask us for help.

Is a bit of a scalability issue.

4 Likes

One feature I use all the time is WebGLMultisampleRenderTarget.

Detect if WebGL2 is available, if so use a WebGLMultisampleRenderTarget for AA, if no WebGL2 then fall back to a SMAA pass. That at least gives a nice performance and quality boost for ~75% of users.

Nice!

2 Likes

@looeee

One feature I use all the time is WebGLMultisampleRenderTarget. … That at least gives a nice performance and quality boost for ~75% of users.

I saw that that was available but I haven’t used it myself! Can you elaborate on how you’re using it? How does it offer a performance boost? Is it because you’re using render targets that are twice as large otherwise? I may just not have much of a use for that specific feature. Post processing is really the only place I’m using render buffers right now but I don’t think a lot of them can work with MSAA buffers?

@mrdoob

As per the MRT PR, it sure is influenced by Safari not supporting it yet.

I’m not a big fan of multiple code paths, but even less of a fan when these paths do not work on some phones and people ask us for help.

Thanks for the update! I always appreciate having insight into why something that’s seemingly ready hasn’t been merged. Hopefully in the next year! :crossed_fingers: If it looks like it’s going to be supported it might be nice to have it (undocumented?) a bit earlier to start building other features around it.

How does it offer a performance boost?

MSAA is implemented in hardware, as far as I know, so you should get a performance boost compared to a manual AA pass. I have test MSAA vs FXAA/SMAA and there is a huge difference (up to 15fps) on some hardware, especially mobile hardware. I expect WebGLMultisampleRenderTarget to be similar to MSAA in terms of performance, but I don’t have tests to back that up.

However the real benefit is quality. MSAA looks much better than FXAA/SMAA, especially on the architectural models I’ve been working with lately which have loads of straight horizontal and vertical lines.

Can you elaborate on how you’re using it?

Create the renderer

import {
  WebGLRenderer,
} from 'three/build/three.module.js';

import { WEBGL } from '/node_modules/three/examples/jsm/WebGL.js';

const canvas = document.createElementNS(
  "http://www.w3.org/1999/xhtml",
  "canvas"
);

const contextAttributes = {
  antialias: false
  // ... other settings
};

let context;

if (WEBGL.isWebGL2Available()) {
  console.log("Using WebGL2");
  context = canvas.getContext("webgl2", contextAttributes);
} else {
  console.log("Using WebGL");
  context =
    canvas.getContext("webgl", contextAttributes) ||
    canvas.getContext("experimental-webgl", contextAttributes);
}

const renderer = new WebGLRenderer({
  canvas,
  context
});

Set up Composer

import {
  RGBFormat,
  Vector2,
  WebGLMultisampleRenderTarget,
} from 'three/build/three.module.js';

import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer.js';

const usingWebGL2 = renderer.capabilities.isWebGL2;
const size = this.renderer.getDrawingBufferSize(new Vector2());

let composer;

if (!usingWebGL2) {
  composer = new EffectComposer(renderer);
} else {
  const parameters = {
    format: RGBFormat,
    stencilBuffer: false
  };

  renderTarget = new WebGLMultisampleRenderTarget(
    size.width,
    size.height,
    parameters
  );

   // tune AA quality
  renderTarget.samples = 8;

  composer = new EffectComposer(renderer, renderTarget);
}

Set up post processing passes

import { RenderPass } from 'three/examples/jsm/postprocessing/RenderPass.js';
import { ShaderPass } from 'three/examples/jsm/postprocessing/ShaderPass.js';
import { GammaCorrectionShader } from 'three/examples/jsm/shaders/GammaCorrectionShader.js';
import { SMAAPass } from '/node_modules/three/examples/jsm/postprocessing/SMAAPass.js';

const renderPass = new RenderPass(scene, camera);
renderPass.name = "Initial Render Pass";
composer.addPass(renderPass);

// ... other linear space passes

const colorPass = new ShaderPass(GammaCorrectionShader);
colorPass.name = "Linear to sRGB Pass";
composer.addPass(colorPass);

// ... other sRGB space passes

// if not using WebGL2 add a manual AA pass such as FXAA or SMAA
if (!usingWebGL2) {
  const aaPass = new SMAAPass(size.x, size.y);
  aaPass.name = "SMAA Pass";
  composer.addPass(aaPass);
}

// ... any final passes (brightness/contrast/vignette etc)
4 Likes

I actually didn’t expect that – good to know.

And thanks for the extremely thorough example! I appreciate it. Somehow I didn’t realize you could pass render targets like that into the EffectComposer constructor. I expected the effect passes to look a bit odd in some cases because they’ve not be implemented with AA buffers in mind but I’ll have to give it a try!

1 Like

I haven’t noticed any difference so far, but I haven’t tested with that many different passes.

2 Likes

can i use WebGLMultisampleRenderTarget without EffectComposer? on webgl2

Yes, the official example shows how to setup EffectComposer with a multisampled rendertarget.

https://threejs.org/examples/webgl2_multisampled_renderbuffers

the Idea is using it without EffectComposer and post processing passes. so three renders direct to this target?

As far as I know you can use a WebGLMultisampleRenderTarget anywhere that you can use a WebGLRenderTarget.

thx, i think i misunderstand something here :> @looeee in your sample i need to set antialias: false ?
is it not better to use antialias: true and do not use the WebGLMultisampleRenderTarget?

antialias: true enables built-in antialiasing hardware AA, which is usually (maybe always?) MultiSampleAntialiasing (MSAA).

However when you render to a standard render target (e.g. when you use the EffectComposer) that doesn’t work, meaning that the setting has no effect. As a result you need to add a manual AA pass such as SMAA. In my experience these don’t look as good as MSAA and are less performant since the are running in software rather than hardware.

WebGLMultisampleRenderTarget allows you to use built-in hardware AA when rendering to a target.

I’m not sure if there’s any need to actually set antialias: false when rendering to a target, but I always do in case there’s a performance penalty to enabling it even when not using it.

1 Like

ok thx for the informations. if i do not need any other effect, like the GammaCorrection Effect, it makes no sense to use the WebGLMultisampleRenderTarget ? ( simple enable the antialias: true )