滤镜特效节点开发

1. 概述

XImageEffect库是一个图像处理框架,允许定义前处理和后处理逻辑,前处理是对背景图像(如摄像头采集的图像)所做的处理,后处理是对背景图像与3D引擎渲染内容合成的结果所做的处理。XImageEffect作为滤镜框架,允许用户在该框架下创建自定义滤镜。

一个滤镜效果对应一个滤镜节点,多个滤镜节点构成一张图(这张图可以是一个滤镜链),每个滤镜节点有确定的输入和输出(可以有多个输入和输出),因此滤镜节点构成的图是一张有向图。滤镜处理器在执行滤镜效果的时候,即是对这张有向图进行遍历,依次执行每一个滤镜节点。

滤镜通过材质的方式来定义,创建一个滤镜即是创建一个材质。材质是渲染引擎的概念,一个材质描述一种表现效果,从技术细节上来讲,材质封装了一套渲染状态、shader代码及参数。更复杂的滤镜可以由lua脚本来控制逻辑(比如更新VertexBuffer),lua脚本以及前面提到的材质文件、shader代码都可以看做资源文件,支持热更新。

2. 示例

下面以一个示例(AR背景层特效)来讲解在XImageEffect框架下编写滤镜的方法。该示例实现如下效果。

滤镜编写流程整体分为三个步骤:

  1. 编写材质文件,以.mt为后缀。
  2. 编写shader文件,包括vertex shader和pixel shader文件,以.glsl为后缀。
  3. 创建XImageEffectNode,并构建XImageEffectGraph。

3. 编写材质文件

材质文件的后缀名为.mt,以文本形式编辑。以AR背景层特效为例,ar_background.mt的定义如下图所示。

  • MaterialProperties:材质属性,该部分定义渲染状态、shader文件名等。
    • AlphaType:混合模式,可取值为Opaque、Translucent。
    • pass:定义一个渲染通道,渲染顺序与pass定义顺序一致。
    • SrcColorBlend:源颜色混合系数。可取值为One、zero、SrcAlpha、InvSrcAlpha、SrcColor、InvSrcColor。
    • DestColorBlend:目的颜色混合系数。可取值同SrcColorBlend。
      • SrcColorBlend和DestColorBlend共同决定源颜色如何与目标颜色如何混合,假设SrcColor和DestColor分别表示源颜色和目标颜色,混合公式为:FinalColor = SrcColor * SrcColorBlend+DestColor * DestColorBlend。
      • 最常用的组合为:SrcColorBlend为One,DestColorBlend为Zero,表示源颜色直接覆盖目标颜色,等效于将混合模式设置为Opaque;SrcColorBlend为SrcAlpha,DestColorBlend为InvSrcAlpha,表示源颜色按照alpha值与目标颜色混合,即alpha半透明。
    • VertexShader:顶点着色器文件名。
    • PixelShader:片段着色器文件名。
    • VSEntry:顶点着色器函数入口,默认为main。
    • PSEntry:片段着色器函数入口,默认为main。
    • CullMode:裁剪模式,可取值为Back、Front或Off,分别表示背面剔除、正面剔除和关闭剔除。
    • ClearColor:清屏颜色。
    • Input:输入纹理名。
      • “InputTextureSampler”为系统内置输入,表示节点默认输入(背景纹理),即当前帧。
      • 当输入纹理名不为“InputTextureSampler”时,表示其他pass的临时输出。
      • @Point为纹理过滤模式。其他可取值为@Bilinear、@Trilinear、@Anisotropic。
      • @ClampU和@ClampV表示寻址模式。其他可取值为@WrapU、@WrapV、@MirrorU、@MirrorV、@BorderU、@BorderV。
        • 寻址模式对应OpenGL中纹理寻址的WrapMode。@WrapU和@WrapV对应GL_REPEAT,@MirrorU和@MirrorV对应GL_MIRRORED_REPEAT,@ClampU、@ClampV、@BorderU和@BorderV均对应GL_CLAMP_TO_EDGE。最常用的是@ClampU和@ClampV。具体细节可参考OpenGL纹理相关文档。
    • Output:输出渲染缓冲名。
      • “OutputRenderTarget”为系统内置输出,表示节点默认输出(图像处理结果)。
      • 当输出缓冲不为“OutputRenderTarget”时,可以设置其格式和大小。
      • @RGBA表示渲染缓冲的格式为R8G8B8A8。其他可取值为@RGB、@Luminance、@LuminanceAlpha。注:@Luminance和@LuminanceAlpha在安卓平台有问题,暂时别用。
      • @Relative_0.25_0.25表示渲染缓冲的大小是相对尺寸,宽和高都是输出纹理的0.25倍。Relative表示尺寸为相对模式,Absolute表示尺寸为绝对模式。例如,@Absolute_256_256表示渲染缓冲的尺寸为256x256。
  • MaterialUserParameters:用户材质参数,shader的参数定在在这。可选参数类型为float、float2、float3、float4、matrix4、texture2D、textureCube。
  • FrameCache模块说明(允许设置输入图像的像素缓存)
    • 添加XImageEffectNodeFrameCache类型,提供缓存帧的功能,可以在ImageEffectGraph内任意位置插入XImageEffectNodeFrameCache节点(一个Graph中可以插入多个FrameCache节点)。
    • 支持自动触发cache和手动触发cache,手动触发时可以通过CacheFrame接口传入帧的标签,在shader中可以通过该标签拿到缓存帧。
    • FrameCache_xxx_yyy是关键字,shader中可以通过该关键字拿到某个被cache的帧。xxx是FrameCache节点的名字,yyy是数字或者手动触发时的标签(如果是数字,表示倒数第几帧,通常用于延迟滤镜)。
    • XProject中的demo01有相关用法演示。
    • 之前,缓存帧的shader关键字是InputTextureSampler_n,现在需要相应的改为FrameCache_xxx_n,不兼容之前的关键字。
  • XImageEffectNodeUser节点支持多输入多输出,最多支持7个输入和7个输出。
    • InputTextureSampler_n是输入关键字,n取0-6。
    • OutputRenderTarget_n是输出关键字,n取0-6。
    • 之前的关键字InputTextureSampler和OutputRenderTarget可兼容,InputTextureSampler被解释为InputTextureSampler_0,OutputRenderTarget被解释为OutputRenderTarget_0。

4. 编写Shader文件

Shader文件有两项注意事项:

  • Shader文件需要进行转码加密。(XImageEffect库中g_pXImageEffectShaderCodec提供了转解码接口)。
  • Shader文件必须与其材质文件(.mt文件)在同一级目录下。如下图所示。

5. 创建特效节点

图像处理由一张图(XImageEffectGraph)表示,图中的每个节点(XImageEffectNode)表示一个具体的图像处理效果。

用户通过材质和shader编写的特效均是通过XImageEffectNodeUser类型的节点来实现的,该节点接受一个材质实例作为输入,由材质定义的滤镜效果最终通过该节点类型的对象来执行。

图的构建是由用户来完成的,用户定义一个XImageEffectGraphBuilder的子类,实现其BuildImageEffectGraph接口。以AR背景层特效实例为例,图的结构如下图所示。

编辑器工具

魔方编辑器提供了编写图像特效的工具,可以在编辑器中创建滤镜Actor、自定义滤镜链、编辑mt文件、编写shader等。 编辑器使用方式可参考

@Copyright © cosmos 2019 all right reserved,powered by Gitbook修订时间: 2021-08-04 18:26:53

results matching ""

    No results matching ""