2

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

4

3 回答 3

4

你说这本来是GLES2 shader,你是highp无条件用在片段shader中?highp这是一场等待发生的灾难,因为片段着色器不需要支持 GLES2 实现。同样,支持dFdx (...),dFdy (...)fwidth (...)是可选的。

您需要检查GL_OES_standard_derivatives并检查GL_FRAGMENT_PRECISION_HIGH此片段着色器的 GLES2 实现。

为此,您可以考虑导数的准确性提示:

  • GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES  (GLES2,如果支持扩展)
  • GL_FRAGMENT_SHADER_DERIVATIVE_HINT          (GLES3)
于 2013-11-29T05:55:31.413 回答
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));
于 2014-01-10T08:21:04.013 回答
0

我在一些 AMD 桌面设置上看到过类似的事情。

在 dFdy( .xyz ) 在 NVIDIA/intel 上运行良好的地方,我必须对每个组件进行派生才能正确获取某些 AMD 卡。

于 2014-04-14T09:22:27.137 回答