我正在使用片段着色器,它使用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);
颜色保持准稳定(准确定)
在Android 4.4中实现这些功能的错误? 我们做错了什么?
答案 0 :(得分:4)
每个组件中的各个衍生物解决了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));
答案 1 :(得分:3)
您说这最初是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
(GLES3)答案 2 :(得分:0)
我在某些AMD桌面设置上看到了类似的内容。
如果dFdy(.xyz)在NVIDIA / intel上工作正常,我必须为每个组件执行派生,以便为某些AMD卡正确使用它。