iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 18
1
Modern Web

寫給工程師的 WebGL 學習心得系列 第 18

[WebGL - Day18] PixiJS 濾鏡實作 - alpha filter

  • 分享至 

  • xImage
  •  

PixiJS 內建一些濾鏡:


PIXI.filters - Classes
AlphaFilter、BlurFilter、BlurFilterPass、
ColorMatrixFilter、DisplacementFilter、FXAAFilter、NoiseFilter
本篇介紹其中 AlphaFilter 的實作

AlphaFilter

  • 調整透明度的濾鏡

先照著 Basic - PixiJS Examples來畫隻兔子:
Pixi Example Basic

const bunny = PIXI.Sprite.from('examples/assets/bunny.png');
app.stage.addChild(bunny);

畫了隻兔子,然後放到場景上
(PIXI.Sprite.from 是 v5 的寫法,與 v4 不太相同)

如果要調整透明度,只需要:

bunny.alpha = 0.5;

設定物件的 alpha 屬性就可以了,不使用濾鏡
Pixi Example Basic

使用 AlphaFilter

使用濾鏡的話,也不會太麻煩

const alphaFilter = new PIXI.filters.AlphaFilter();
bunny.filters = [alphaFilter];

調整 alphaFilter 的值有兩個方法:

alphaFilter.alpha = 0.5;

alphaFilter.uniforms.uAlpha = 0.5;

意思是相同的

直接看原始碼 filter-alpha src

import { Filter, defaultVertex } from '@pixi/core';
import fragment from './alpha.frag';

export class AlphaFilter extends Filter
{
    /**
     * @param {number} [alpha=1] Amount of alpha from 0 to 1, where 0 is transparent
     */
    constructor(alpha = 1.0)
    {
        super(defaultVertex, fragment, { uAlpha: 1 });

        this.alpha = alpha;
    }

    /**
     * Coefficient for alpha multiplication
     *
     * @member {number}
     * @default 1
     */
    get alpha()
    {
        return this.uniforms.uAlpha;
    }

    set alpha(value) // eslint-disable-line require-jsdoc
    {
        this.uniforms.uAlpha = value;
    }
}

其中的 gettersetter 便是 fragment shaderuniform float uAlpha

再往上看一點:

import { Filter, defaultVertex } from '@pixi/core';
import fragment from './alpha.frag';
...
super(defaultVertex, fragment, { uAlpha: 1 });

這是 PixiJS 濾鏡的基本寫法:

new Filter(vertShader, fragShader, myUniforms);

這個 alphaFilter 裡:

  • vertShader 是 @pixi/core 的 defaultVertex,使用預設值
  • fragShader 是自己寫的 ./alpha.frag
  • myUniforms 則是上方提到的 {uAlpha},可透過 JavaScript 控制

半透明的 gl_FragColor

昨天提到 fragment shader 輸出 gl_FragColor

gl_FragColor // vec4

如果要輸出半透明黃色

gl_FragColor = vec4(1.0, 1.0, 0.0, 1.0) * 0.7; //yellow circle, alpha=0.7

雖然輸出顏色很像 vec4(RGBA),但實際上是vec4(vec3(RGB),1.0)*A;

vec4(1.0, 1.0, 0.0, 1.0) * 0.7; // 正確,alpha 值最後再乘
vec4(1.0, 1.0, 0.0, 0.7); // 錯的

alpha.frag

Fragment Shaderalpha.frag 原始碼:

varying vec2 vTextureCoord;

uniform sampler2D uSampler;
uniform float uAlpha;

void main(void)
{
   gl_FragColor = texture2D(uSampler, vTextureCoord) * uAlpha;
}

vTextureCoord 是 varying 的 Storage Qualifiers 變數,
表示這是從 Vertex Shader 傳過來的值

PIXI.Filter 說明文件

  • uSampler 也是 Built-in Uniforms 之一

最常使用的情形是,搭配 vTextureCoord,回傳濾鏡本身的原圖:

gl_FragColor = texture2D(uSampler, vTextureCoord);

最後乘上 uAlpha ,就是 alphaFilter 了!


補充:
昨天 Mouse Blending 範例 裡,實際上是把濾鏡加在一個空白容器裡,因此不需要輸出原圖
Pixi Example Mouse Blending


上一篇
[WebGL - Day17] 在 PixiJS 裡寫 Shader,並看懂範例裡的 Shader 寫法
下一篇
[WebGL - Day19] PixiJS 濾鏡實作 - glowFilter、PixiJS v4 v5 版濾鏡寫法差異
系列文
寫給工程師的 WebGL 學習心得30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言