Fragment Shader(dFdx,dFdy)的标准衍生产品在Android 4.4中无法正常运行

时间:2013-11-28 17:56:44

标签: android opengl-es-2.0 fragment-shader android-4.4-kitkat opengl-es-3.0

我正在使用片段着色器,它使用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中实现这些功能的错误? 我们做错了什么?

3 个答案:

答案 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_derivativesGL_FRAGMENT_PRECISION_HIGH

为此,您可以考虑衍生品的准确性提示:

  • GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES(GLES2,如果支持扩展名)
  • GL_FRAGMENT_SHADER_DERIVATIVE_HINT(GLES3)

答案 2 :(得分:0)

我在某些AMD桌面设置上看到了类似的内容。

如果dFdy(.xyz)在NVIDIA / intel上工作正常,我必须为每个组件执行派生,以便为某些AMD卡正确使用它。