【问题标题】:Transition shader过渡着色器
【发布时间】:2014-01-23 11:56:10
【问题描述】:

我已经创建了一个过渡着色器。

这是做什么的:

On each update the color that should be alpha changes.
Then preform a check for each pixel.
    If the color of the pixel is more that the 'alpha' value
      Set this pixel to transparent.
    Else If the color of the pixel is more that the 'alpha' value - 50
      Set this pixel to partly transparent.
    Else
      Set the color to black.

编辑(删除旧部分):

我尝试将我的 GLSL 转换为 AGAL(使用 http://cmodule.org/glsl2agal):

片段着色器:

const float alpha = 0.8;
varying vec2 TexCoord; //not used but required for converting
uniform sampler2D transition;//not used but required for converting

void main()
{
    vec4 color = texture2D(transition, TexCoord.st);//not used but required for converting

    color.a = float(color.r < alpha);

    if(color.r >= (alpha - 0.1)){
        color.a = 0.2 * (color.r - alpha - 0.1);
    }

    gl_FragColor = vec4(0, 0, 0, color.a);
}

我已经自定义了输出并将其添加到(自定义)Starling 过滤器:

var fragmentShader:String =
    "tex ft0, v0, fs0 <2d, clamp, linear, mipnone>                  \n" + // copy color to ft0
    "slt ft0.w, ft0.x, fc0.x                                        \n" + // alpha = red < inputAlpha
    "mov ft0.xyz, fc1.xyzz                                          \n" + // set color to black
    "mov oc, ft0";

mShaderProgram = target.registerProgramFromSource(PROGRAM_NAME, vertexShader, fragmentShader);

它可以工作,当我设置过滤器 alpha 时,它会更新内容。唯一剩下的是部分透明的东西,但我不知道该怎么做。

【问题讨论】:

  • 我对八哥的了解几乎为零,但我建议您使用help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/… 来处理颜色过渡。我很确定,如果你正确构建矩阵,你可以在循环方法的 1000 倍的速度下获得相同的效果。
  • 是的,starling 也有滤镜,所以基本相同,虽然我不知道如何使用彩色矩阵滤镜实现这种行为。

标签: image actionscript-3 shader transition


【解决方案1】:

在 Y 和 X 坐标上交换循环。通过在内部循环中使用 X,您可以优化 L1 缓存和 CPU 的预取器。

一些小提示:
删除零以获得更清晰的代码:

const c:uint = a << 24

验证 255/50 是否被编译器折叠成单个常量。

【讨论】:

  • 您能否提供任何细节或链接表明这部分代码存储在 L1 缓存中?还有关于交换循环如何强制在 L1 缓存中使用的详细信息。
  • 交换循环确实有帮助,它现在是 23 FPS 而不是 20。(我已经在我的帖子中编辑了代码)虽然它仍然没有我想要的那么快。这种功能是否可以通过另一种方式实现?我在使用 GLSL 之前已经这样做了,但我对 AGAL 一无所知。
  • 可能大部分时间都花在了 getPixel 和 setPixel 中,您是否测量了最大理论速度: tempBitmapData.setPixel32(x, y, bitmapData.getPixel(x, y)) ?附言通过编辑代码,我的答案现在可能被认为是“错误的”(!)
【解决方案2】:

一旦你使用 Starling,就不要因为 BitmapData 而发疯。

我不知道您是否自己对其进行灰度化。如果不是,只需为灰度创建一个Starling filter(下面的像素着色器就可以了)

tex ft0, v0, fs0 <2d,linear,clamp>
add ft1.x, ft0.x, ft0.y
add ft1.x, ft1.x, ft0.z
div ft1.x, ft1.x, fc0.x
mov ft0.xyz, ft1.xxx
mov oc ft0

对于 alpha 转换,只需扩展 Image 类,实现 IAnimatable 将其添加到 Juggler。在advanceTime只需做一个this.alpha -= VALUE;

就这么简单:)

【讨论】:

  • 它没有那么简单 ;P 让我们以这张图片为例:Battle.png 在每次更新时,应该是 alpha 的颜色都会发生变化。然后对每个像素进行检查。如果像素的颜色大于 'alpha' 值。将此像素设置为透明。别的。将颜色设置为黑色。
  • 您只需要检查像素并在着色器中杀死该像素。稍后我可以发布 AGAL 着色器……现在我没有时间。 Ps.:你说你是用 GLSL 做的,把它转换成 agal 并使用它;这是一个 glsl2agal 转换器cmodule.org/glsl2agal Cheers
  • :O GLSL 到 AGAL :O 谢谢:D
【解决方案3】:

只是想详细说明@Paxel 的答案。我与另一位开发人员 Jackson Dunstan 讨论了 L1 缓存,速度改进的来源,以及可以对这样的代码进行哪些其他改进以查看性能提升。

之后,Jackson 发布了一篇博文,可以在此处阅读:Take Advantage of CPU caching

我会发布一些相关的项目。首先,位图数据按行存储在内存中。行内存地址可能如下所示:

   row 1: 0 1 2 3 4 5
   row 2: 6 7 8 9 10 11
   row 3: 12 13 14 15 16 17

现在通过行运行内部循环将允许您利用 L1 缓存优势,因为您可以按顺序读取内存。所以内部循环 X 首先你会读到第一行:

0 1 2 3 4 5

但如果你先这样做,你会读作:

0 6 12 1 7 13

如您所见,您在内存地址附近跳跃,这使其过程变慢。

至于可以进行的优化,建议是缓存您的宽度和高度 getter,将属性存储到局部变量中。使用Math.round() 也很慢,替换它会看到速度增加。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-09-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-28
    • 1970-01-01
    • 2021-04-01
    • 2011-03-27
    相关资源
    最近更新 更多