Стандартные производные от фрагментного шейдера (dFdx, dFdy), не работают корректно в Android 4.4



Я использую шейдер фрагментов, который использует функции dFdy dFdx для вычисления нормали
лицо для просмотра в плоском виде. Этот шейдер работает нормально в gles 2.0 и 3.0. Необъяснимо, шейдер не работает на Андроид 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


Анализ каждого производного отдельно:



1.- fragColor=vec4(normalize( fdx ), 1.0); цвета постоянно меняются (неправильно)



2.- fragColor=vec4(normalize( fdy ), 1.0); цвета остаются квазистабильными (квази-ОК)



Ошибка в реализации этих функций в Android 4.4?
Мы делаем что-то не так?

530   3  

3 ответов:

Отдельные производные в каждом компоненте решают задачу в 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));

Вы сказали, что изначально это был шейдер GLES2, и вы используете highp в шейдере фрагментов безоговорочно? Это катастрофа, ожидающая своего часа, потому что реализации GLES2 не требуются для поддержки highp в шейдерах фрагментов. Аналогичным образом, поддержка для 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)

Я видел подобные вещи на некоторых настольных компьютерах AMD.

Где dFdy( .xyz) отлично работал на NVIDIA / intel, мне пришлось сделать дериват для каждого компонента, чтобы получить его правильно для некоторых карт AMD.

Comments

    Ничего не найдено.