我使用的片段着色器使用dFdy dFdx函数来计算以平面外观面对面查看。该着色器在gles 2.0和3.0中运行良好。令人费解的是,着色器在Android 4.4(KitKat-gles3.0)中不起作用。
(已解决!!..每个组件的单独导数,解决问题)。
为了检查错误,我准备了以下着色器:
//Vertex Shader
#version 300 es
precision highp float;
precision highp int;
uniform mat4 PMatrix; //Projection Matrix (varies according to camera)
uniform mat4 MVMatrix; //Model View Matrix (no change)
in vec3 vPosition;
out vec3 vPos;
main()
{
gl_Position=PMatrix * MVMatrix * vec4(vPosition.xyz,1.0);
vPos = (MVMatrix * vec4(vPosition.xyz,1.0)).xyz;
}
// Fragment shader
#version 300 es
#extension GL_OES_standard_derivatives : enable
precision highp float;
precision highp int;
in vec3 vPos;
main()
{
// don't run correctly
// vec3 fdx = dFdx(vPos);
// vec3 fdy = dFdy(vPos);
// ***Solved!*** this run correctly in KitKat
vec3 fdx = vec3(dFdx(vPos.x),dFdx(vPos.y),dFdx(vPos.z));
vec3 fdy = vec3(dFdy(vPos.x),dFdy(vPos.y),dFdy(vPos.z));
vec3 N = normalize(cross(fdx,fdy));
fragColor = vec4(N,1.0);
}
绘制立方体,在Android中<4.4每侧的颜色保持固定,与相机位置无关(正确,颜色标识每个正常人脸)。在Android 4.4中,如果移动相机,颜色会有所不同。
分别分析每个衍生产品:
1.-fragColor=vec4(normalize( fdx ), 1.0);
颜色不断变化(错误)
2.-fragColor=vec4(normalize( fdy ), 1.0);
颜色保持准稳定(准ok)
安卓4.4中这些功能的实现中存在错误?我们做错了什么?
您说过这最初是一个GLES2着色器,而您正在片段着色器中无条件地使用highp
?这是一场等待发生的灾难,因为GLES2实现不需要在片段着色器中支持highp
。同样,对dFdx (...)
、dFdy (...)
和fwidth (...)
的支持也是可选的。
您需要在该片段着色器的GLES2实现中检查GL_OES_standard_derivatives
和GL_FRAGMENT_PRECISION_HIGH
。
为此,您可以考虑衍生品的准确性提示:
GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES
(GLES2,如果支持扩展)GL_FRAGMENT_SHADER_DERIVATIVE_HINT
nbsp nbsp nbsp nbsp (gle3)
每个组件中的单个导数解决KitKat:中的问题
// Replace vec3 fdx = dFdx(vPos) by:
vec3 fdx = vec3(dFdx(vPos.x),dFdx(vPos.y),dFdx(vPos.z));
// Replace vec3 fdy = dFdy(vPos) by:
vec3 fdy = vec3(dFdy(vPos.x),dFdy(vPos.y),dFdy(vPos.z));
我在一些AMD桌面设置上看到过类似的东西。
在dFdy(.xyz)在NVIDIA/intel上运行良好的地方,我必须对每个组件进行推导,以使其正确适用于一些AMD卡。