three.js 中 ‘dFdx’ : no matching overloaded function found 问题处理

three.js 中使用 shaderMaterial / rawShaderMaterial 时报 ‘dFdx’ : no matching overloaded function found 问题处理

最近在使用 three.js 移植一个 shader 效果时遇到一个问题,报错如下:

THREE.WebGLProgram: shader error: 0 35715 false gl.getProgramInfoLog No compiled fragment shader when at least one graphics shader is attached.
THREE.WebGLShader: gl.getShaderInfoLog() fragment
ERROR: 0:23: 'dFdx' : no matching overloaded function found
ERROR: 0:23: 'dFdy' : no matching overloaded function found
ERROR: 0:23: 'cross' : no matching overloaded function found
WARNING: 0:? : 'normalize' : operation result is undefined for the values passed in
ERROR: 0:23: '=' : dimension mismatch
ERROR: 0:23: '=' : cannot convert from 'const mediump float' to 'highp 3-component vector of float'

本次使用的 three.js 的版本如下:

"three": "^0.122.0",

百度了很多解决方案貌似都只是:
1、在 shader 顶部中添加 #extension GL_OES_standard_derivatives : enable
2、在 renderer 使用后,设置 renderer.getContext('OES_standard_derivatives')

折腾来折腾去,终于搞定了此问题,最终解决方式:
1、

renderer = new THREE.WebGL1Renderer({ antialias: false }) // 注意:要使用 WebGL1Renderer,而不是 WebGLRenderer

2、在 shader 顶部中添加 #extension GL_OES_standard_derivatives : enable,即可。

还没看 three.js 源码,但我猜其实应该就是类似于,canvas.getContext('webgl') 与 canvas.getContext('experimental-webgl') 的区别。WebGLRenderer 使用的是 canvas.getContext('webgl'),这种模式不支持 GL_OES_standard_derivatives;而 canvas.getContext('experimental-webgl') 才支持。