M -
M -

Reputation: 28502

Threejs: mesh standard material reflection issues

I've stumbled upon the problem that some browsers and devices render the MeshStandardMaterial reflection poorly.

Consider the example below:

enter image description here

and this example below: enter image description here

Both comparisons are running simultaneously on the same computer, same graphics card, identical attributes, but different browsers. As you can see, the reflections on the right are almost unidentifiable.

Additionally, I'm getting some triangulation issues at sharp angles that make it seem as if the reflection is being calculated in the vertex shader: enter image description here

I understand that different browsers have different WebGL capabilities, as the results on http://webglreport.com/ illustrate: enter image description here

Does anybody know what WebGL extension or feature the IE/Edge browsers are missing that I can look for? I want to put a sniffer that uses a different material if it doesn't meet the necessary requirements. Or if anybody has a full solution, that would be even better. I've already tried playing with the EnvMap's minFilter attribute, but the reflections are still calculated differently.

Upvotes: 1

Views: 1655

Answers (1)

user128511
user128511

Reputation:

I don't know which extensions are needed but you can easily test. Before you init THREE.js put some code like this

const extensionsToDisable = [
  "OES_texture_float", 
  "OES_texture_float_linear",
];

WebGLRenderingContext.prototype.getExtension = function(oldFn) {
  return function(extensionName) {
    if (extensionsToDisable.indexOf(extensionName) >= 0) {
      return null;
    }
    return oldFn.call(this, name);
  };
}(WebGLRenderingContext.prototype.getExtension);

WebGLRenderingContext.prototype.getSupportedExtensions = function(oldFn) {
  return function() {
    const extensions = oldFn.call(this);
    return extensions.filter(e => extensionsToDisable.indexOf(e) < 0);
  };
}(WebGLRenderingContext.prototype.getSupportedExtensions);

Then just selectively disable extensions until Firefox/Chrome look the same as IE/Edge.

The first thing I'd test is disabling every extension that's in Chrome/Firefox that's not in IE/Edge just to verify that turning them all off reproduces the IE/Edge behavior.

If it does reproduce the issue then I'd do a binary search (turn on half the disabled extensions), and repeat until I found the required ones.

const extensionsToDisable = [
  "EXT_blend_minmax",
  "EXT_disjoint_timer_query",
  "EXT_shader_texture_lod",
  "EXT_sRGB",
  "OES_vertex_array_object",
  "WEBGL_compressed_texture_s3tc_srgb",
  "WEBGL_debug_shaders",
  "WEBKIT_WEBGL_depth_texture",
  "WEBGL_draw_buffers",
  "WEBGL_lose_context",
  "WEBKIT_WEBGL_lose_context", 
];

WebGLRenderingContext.prototype.getExtension = function(oldFn) {
  return function(extensionName) {
    if (extensionsToDisable.indexOf(extensionName) >= 0) {
      return null;
    }
    return oldFn.call(this, name);
  };
}(WebGLRenderingContext.prototype.getExtension);

WebGLRenderingContext.prototype.getSupportedExtensions = function(oldFn) {
  return function() {
    const extensions = oldFn.call(this);
    return extensions.filter(e => extensionsToDisable.indexOf(e) < 0);
  };
}(WebGLRenderingContext.prototype.getSupportedExtensions);

const gl = document.createElement("canvas").getContext("webgl");
console.log(gl.getSupportedExtensions().join('\n'));
console.log("WEBGL_draw_buffers:", gl.getExtension("WEBGL_draw_buffers"));

Upvotes: 3

Related Questions