You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SparkAR中SparkSL浮雕卷积滤镜输出图像垂直翻转问题求助

问题:SparkAR中SparkSL浮雕滤镜输出垂直翻转

我在SparkAR中使用Meta的SparkSL着色语言实现浮雕滤镜,代码基于ShaderToy案例修改而来。滤镜可正常运行,但最终输出图像出现垂直翻转现象,尝试取反相关数值后仍未解决问题。

垂直翻转的浮雕滤镜效果

现有代码

// Source:
// http://coding-experiments.blogspot.com/2010/07/convolution.html

#define EMBOSS_WIDTH    0.0015
#define EMBOSS_HEIGHT 0.0050

// samples a pixel centerd at "uv" and with offset of dx|dy
const vec4 sample_pixel(std:: Texture2d myTex, in vec2 uv, in float dx, in float dy)
{
    return myTex.sample( uv + vec2(dx, dy));
}

// convolves a SINGLE channel of input color_matrix
const float convolve(in float[9] kernel, in vec4[9] color_matrix) 
{
   float res = 0.0;
   for (int i=0; i<9; i++)
   {
      res += kernel[i] * color_matrix[i].a;
   }
   return clamp(res + 0.5, 0.0 ,1.0);
}

// builds a 3x3 color matrix centerd at "uv"
const void build_color_matrix(std:: Texture2d myTex, in vec2 uv, out vec4[9] color_matrix)
{
    float dxtex = EMBOSS_WIDTH;
    float dytex = EMBOSS_HEIGHT;
 
    color_matrix[0].rgb = sample_pixel(myTex, uv, -dxtex, -dytex)   .rgb;
    color_matrix[1].rgb = sample_pixel(myTex, uv, -dxtex,   0.0)    .rgb;
    color_matrix[2].rgb = sample_pixel(myTex, uv, -dxtex,   dytex)  .rgb;
    color_matrix[3].rgb = sample_pixel(myTex, uv, 0.0,  -dytex) .rgb;
    color_matrix[4].rgb = sample_pixel(myTex, uv, 0.0,  0.0)    .rgb;
    color_matrix[5].rgb = sample_pixel(myTex, uv, 0.0,  dytex)  .rgb;
    color_matrix[6].rgb = sample_pixel(myTex, uv, dxtex,    -dytex) .rgb;
    color_matrix[7].rgb = sample_pixel(myTex, uv, dxtex,    0.0)    .rgb;
    color_matrix[8].rgb = sample_pixel(myTex, uv, dxtex,    dytex)  .rgb;
}

// builds a mean color matrix (off of .rgb of input).
// NOTE: stores the output in alpha channel
 void build_mean_matrix(inout vec4[9] color_matrix)
{
   for (int i=0; i<9; i++)
   {
      color_matrix[i].a = (color_matrix[i].r + color_matrix[i].g + color_matrix[i].b) / 3.;
   }
}
 
vec4 mainImage( in std:: Texture2d myTex, out vec4 )
{
    /*2.    0.  0.
        0.  -1  0.
        0.  0.  -1  */
    
    float kerEmboss[9];
    kerEmboss[0] = 2.;
    kerEmboss[1] = 0.0;
    kerEmboss[2] = 0.0;
    kerEmboss[3] = 0.0;
    kerEmboss[4] = -1.;
    kerEmboss[5] = 0.0;
    kerEmboss[6] = 0.0;
    kerEmboss[7] = 0.0;
    kerEmboss[8] = -1.;
    
    vec4 pixel_matrix[9];
    vec2 iResolution = std::getRenderTargetSize();
    vec4 fragCoord = std:: getFragmentCoord();
    vec2 uv = fragCoord.xy / iResolution.xy;
    
    build_color_matrix(myTex, uv, pixel_matrix);
    build_mean_matrix(pixel_matrix);
    
    float convolved = convolve(kerEmboss, pixel_matrix);
    vec4 fragColor = vec4(vec3(convolved), 1.0);
    return fragColor;
}

解决方案

问题根源在于SparkAR的纹理UV坐标系与ShaderToy存在差异:ShaderToy中纹理原点在左下角,Y轴向上;而SparkAR中纹理原点在左上角,Y轴向下。这导致采样时Y方向的偏移逻辑完全相反,最终图像翻转。

有两种简单的修复方式:

方式1:翻转UV的Y轴坐标

在mainImage函数中计算UV时,直接翻转Y分量:

vec2 uv = vec2(fragCoord.x / iResolution.x, 1.0 - fragCoord.y / iResolution.y);

方式2:修改采样函数的Y偏移

在sample_pixel函数中,对Y方向的偏移取反:

const vec4 sample_pixel(std:: Texture2d myTex, in vec2 uv, in float dx, in float dy)
{
    return myTex.sample( uv + vec2(dx, -dy));
}

两种方式都能统一坐标系方向,解决图像垂直翻转的问题。

内容的提问来源于stack exchange,提问作者bee_bug

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 10:20:43