Three.js: WebGLRenderer: WebGL fallback from WebGL2 does not honor context attributes

Created on 5 Apr 2020  路  10Comments  路  Source: mrdoob/three.js

Consequently, the attributes must be repeated to take effect.

var canvas = document.createElement( 'canvas' );

var context = canvas.getContext( 'webgl2', { alpha: true } );

renderer = new THREE.WebGLRenderer( { canvas: canvas, context: context, alpha: true } );
  • [ x ] Dev
  • [ x ] r115

Most helpful comment

This is messy... Maybe it's time to start supporting WebGL2 by default?

All 10 comments

This is messy... Maybe it's time to start supporting WebGL2 by default?

Agree that a change needs to be made (default webgl2 sounds great) but, until then, it is possible to use ES6 syntax to work around the issue:

const canvas = document.createElement( 'canvas' );
const params = {alpha: true, antialias: true, stencil: true};
const context = canvas.getContext('webgl2', params);
const renderer = new THREE.WebGLRenderer({canvas, context, ...params});

/ping @Mugen87
/ping @mrdoob

What is your recommendation?

In #13717, it was discussed how the WebGL 2 rendering context should be created. It was decided to shift the logic to app level since it was not clear what the renderer should do when the context creation fails. Regarding this decision it's the task of the user to implement a correct fallback like demonstrated with your code.

I guess this is a good opportunity to rethink the design and let the engine handle the context creation. One way to implement this is the introduction of new parameters to control the creation workflow like described here or here.

I think I vote for this type of change since enabling WebGL 2 rendering by default will break a lot of apps with custom shader code.

Either our examples need to do something intelligent, or the renderer needs to do something intelligent.

I would be inclined to leave it up to the apps (i.e., the examples), but let's pick one or the other. We need proper examples for the users to follow.

How about introducing a new parameter webgl2?

const renderer = new THREE.WebGLRenderer( { webgl2: true } );

If set to true, the renderer tries to create a WebGL 2 rendering context. If it fails, it uses WebGL 1. The context parameter handling is then encapsulated.

WebGL 2 will be the standard, so I think this would make more sense if you want to go that route:

const renderer = new THREE.WebGLRenderer( { webgl1: true } ); // force webGL 1

Otherwise, it tries WebGL 2, with WebGL 1 as the fallback. The app can then decide how it wants to proceed.

The device support for WebGL 2 is still limited on mobile devices. However, if @mrdoob thinks the time is right for this change I'm okay with it. It's just important to mark this change very clear in the migration guide since all users who have written custom shader programs have to set webgl1 to true. Otherwise their code won't work anymore.

Maybe doing a THREE.WebGL2Renderer that extends THREE.WebGLRenderer?

Should be solved now.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

donmccurdy picture donmccurdy  路  3Comments

jlaquinte picture jlaquinte  路  3Comments

fuzihaofzh picture fuzihaofzh  路  3Comments

Horray picture Horray  路  3Comments

zsitro picture zsitro  路  3Comments