着色器在 Instagram 上看起来与在 SparkAR Studio 中完全不同
Shader looks completely different on Instagram than in SparkAR Studio
我正在尝试使用 SparkAR 中的着色器创建水下滤镜。
我的过滤器在 SparkAR 中看起来符合预期,但在 Instagram 中测试时完全不同。
下面是对比,左边是SparkAR,右边是Instagram:
我认为它与分辨率有关,所以我已经尝试了一切:升级、使用 getModelViewProjectionMatrix() 代替 getRenderTargetSize() 计算 UV 等
没有任何效果,所以我希望这里有类似经历的人可以帮助我!
这里是使用的着色器代码:
#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 的基础。但事实并非如此。
您需要阅读文章: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);
我正在尝试使用 SparkAR 中的着色器创建水下滤镜。
我的过滤器在 SparkAR 中看起来符合预期,但在 Instagram 中测试时完全不同。
下面是对比,左边是SparkAR,右边是Instagram:
我认为它与分辨率有关,所以我已经尝试了一切:升级、使用 getModelViewProjectionMatrix() 代替 getRenderTargetSize() 计算 UV 等
没有任何效果,所以我希望这里有类似经历的人可以帮助我!
这里是使用的着色器代码:
#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 的基础。但事实并非如此。
您需要阅读文章: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);