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')
才支持。