这是我参与8月更文挑战的第17天,活动详情查看: 8月更文挑战
Spark AR 是 Facebook 免费创作 AR 作品的平台,使用户能够为 Facebook 和 Instagram 创建交互式增强现实体验,超过 40 万名创作者,190个国家/地区,使用 Spark AR 来创作自己的AR作品
由于该软件无需任何编码知识即可使用,因此任何人现在都可以在 AR 世界中几乎没有经验地制作下一个疯狂式传播的 Instagram AR 特效,引领世界潮流。
专门的 AR 滤镜设计师单价甚至可达到 1000 美元到 3 万美元不等。
着色器代码资产允许您使用 SparkSL 编程自己的着色器,Spark AR 自己的着色语言。
作为 GLSL 1.0 的超集,SparkSL 除了提供常见的数据类型和函数外,还提供了许多特性,如下所示。
Visual Studio Code 的 Spark AR 扩展支持 SparkSL 脚本的语法高亮和代码自动完成。
自动的类型推断
关键字 auto 支持变量和函数的自动类型推断。
auto c = a * b;
或者
auto fn() {
return vec4(1.0);
}
分量的混用(swizzle)
除了在混用时使用标准的 xyzw、rgba 和 stpq 语法外,SparkSL 还允许使用 0 和 1 作为值。
vec2 uv;
vec4 col1 = uv.xy01; // Equivalent to vec4(uv, 0.0, 1.0)
float v;
vec4 col2 = v.xxx1; // Equivalent to vec4(v, v, v, 1.0)
vec4 c;
vec4 col3 = c.rgb1; // Equivalent to vec4(c.rgb, 1.0)
Lambda 表达式函数
SparkSL 支持创建 lambda 函数,并将函数作为参数传递给这些函数。
不需要显式指定捕获;在下面的示例中,Tex 和 offset 都被隐式捕获。
// A function that both receives and returns a function
function<vec4(vec2)> blur1D(function<vec4(vec2)> tex, vec2 offset) {
// Creating and returning a lambda function
return [](vec2 uv) {
return 0.25 * tex(uv - offset) +
0.50 * tex(uv) +
0.25 * tex(uv + offset);
};
}
使用 lambda 可以简化纹理的转换和合成,并提供更大的灵活性。考虑两个纹理texA 和 texB ,每个都表示为函数 <vec4(vec2)> 。使用 lambda ,可以将它们相乘,如下面的示例所示。
vec4 myMaterial(function<vec4(vec2)> texA, function<vec4(vec2)> texB) {
// Further information on the getVertexTexCoord() function available in the API reference
vec2 uv = std::getVertexTexCoord();
return texA(uv) * texB(uv);
}
纹理也可以在 lambda 函数中操作。考虑下面的例子,texA 在乘以 texB 之前是模糊的。
vec4 myMaterial(function<vec4(vec2)> texA, function<vec4(vec2)> texB) {
// Further information on the getVertexTexCoord() function available in the API reference
vec2 uv = std::getVertexTexCoord();
auto blurredTexA = blur1D(texA, vec2(0.1));
return blurredTexA(uv) * texB(uv);
}
注意,blur1d 和 myMaterial 并不需要知道 texA 或 texB 的内部实现;事实上,只要提供 vec2 坐标作为参数,并且返回类型是 vec4 颜色,使用 lambda 就可以使用任何纹理实现。
命名空间的声明
支持使用命名空间来组织函数和全局变量,也支持嵌套命名空间和使用命名空间语法。
namespace fb {
vec4 foo(vec2 uv) {
return uv.xy01;
}
}
void main() {
// Further information on the getVertexTexCoord() function available in the API reference
vec2 uv = std::getVertexTexCoord();
gl_FragColor = fb::foo(uv);
}