Шейдер в Instagram выглядит совершенно иначе, чем в студии SparkAR

#glsl #shader #spark-ar-studio

Вопрос:

Я пытаюсь создать подводный фильтр, используя шейдеры в SparkAR. Мой фильтр выглядит так, как задумано в SparkAR, но совсем не так, когда тестируется в Instagram. Вот сравнение: SparkAR слева, Instagram справа: SparkAR по сравнению с Instagram

Я думал, что это как-то связано с разрешением, поэтому я уже все там перепробовал: масштабирование, вычисление UVS с помощью getModelViewProjectionMatrix() вместо getRenderTargetSize () и т. Д.

Ничего не сработало, поэтому я надеюсь, что кто-то здесь испытал нечто подобное и может мне помочь!

Вот используемый код шейдера:

 #ifdef GL_ES
precision mediump float;
#endif

float length2(vec2 p) { return dot(p, p); }

float noise(vec2 p){
  return fract(sin(fract(sin(p.x) * (4231.13311))   p.y) * 3131.0011);
}

float worley(vec2 p) {
  float d = 1e30;
  for (int xo = -1; xo <= 1;   xo) {
    for (int yo = -1; yo <= 1;   yo) {
      vec2 tp = floor(p)   vec2(xo, yo);
      d = min(d, length2(p - tp - vec2(noise(tp))));
    }
  }
  return 3.0*exp(-4.0*abs(2.0*d - 1.0));
}

float fworley(vec2 p) {
  float time = fragment(std::getTime());
  return sqrt(sqrt(sqrt(
    1.6 * // light
    worley(p*32.   4.3   time*.125) *
    sqrt(worley(p * 64.   5.3   time * -0.0625)) *
    sqrt(sqrt(worley(p * -100.   9.3))))));
}

void main(out vec4 Position, out vec4 Color) {
  Position = std::getModelViewProjectionMatrix() * std::getVertexPosition();

  vec2 scaling = vec2(1., 1.);
  float time = fragment(std::getTime());
  vec2 vertCoord =  fragment(std::getVertexTexCoord());
  vec2 resolution = fragment(std::getRenderTargetSize());
  vec2 uv = floor(resolution * vertCoord) / resolution;
    
  vec2 xDifference = vec2(2.0 * (sin(time / 2.0) / 2.0)  - 1.5, 0.8);
  float t = fworley(uv * resolution / (900.0 * scaling)) / 2.;
  t *= exp(-length2(abs(1.0* (uv   xDifference) *  - 1.0)));

  t  = fworley(uv * resolution / (450.0 * scaling)) / 2.;
  xDifference = vec2(2.0 * (sin(time / 2.0) / 2.0)  - 0.75, 0.7);
  t *= exp(-length2(abs(1.0* (uv   xDifference) *  - 1.0))) * 0.5;

  t  = fworley(uv * resolution / (300.0 * scaling)) / 3.;
  xDifference = vec2(2.0 * (sin(time / 2.0) / 3.0)  - 0.5, 0.6);
  t *= exp(-length2(abs(1.0* (uv   xDifference) *  - 1.0)));
  
  Color = vec4((t 0.05) * vec3(0.3, 1.5*t, 0.3   pow(t, 1.0-t)), 1.3);
}
 

Я также уже проверил, использовал ли я что-то, что не поддерживается GLSL 1.x, поскольку это основа для SparkSL. Но это не тот случай.

Ответ №1:

Вам нужно прочитать статью : https://sparkar.facebook.com/ar-studio/learn/sparksl/cross-device-shader-sparksl#opengl

Короче говоря, проблема заключается в точности поплавков.

И никогда не используйте:

 fract(sin(fract(sin(p.x) * (4231.13311))   p.y) * 3131.0011);