Threejs:网格标准材质反射问题

时间:2017-08-17 19:53:47

标签: three.js webgl gpu

我偶然发现了一些浏览器和设备导致MeshStandardMaterial反射效果不佳的问题。

考虑下面的example

enter image description here

下面的

this exampleenter image description here

两种比较都在同一台计算机,相同的显卡,相同的属性和不同的浏览器上同时运行。如您所见,右侧的反射几乎无法辨认。

此外,我在锐角处获得了一些三角测量问题,使得看起来好像在顶点着色器中计算了反射: enter image description here

据我所知,不同的浏览器具有不同的WebGL功能,因为http://webglreport.com/上的结果说明了: enter image description here

有人知道IE / Edge浏览器丢失的WebGL扩展或功能是否可以查找?如果它不符合必要的要求,我想要使用不同材料的嗅探器。或者如果有人有完整的解决方案,那就更好了。我已经尝试过使用EnvMap的minFilter属性,但反射的计算方式仍然不同。

1 个答案:

答案 0 :(得分:3)

我不知道需要哪些扩展,但您可以轻松测试。在你初始化之前THREE.js放了一些像这样的代码

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);

然后选择性地禁用扩展,直到Firefox / Chrome看起来与IE / Edge相同。

我要测试的第一件事就是禁用Chrome / Firefox中不在IE / Edge中的每个扩展程序,只是为了验证关闭它们以重现IE / Edge行为。

如果它确实重现了这个问题,那么我会进行二分查找(打开一半禁用的扩展名),然后重复,直到找到所需的扩展名。

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"));