WebGLで画像を表示する【PixiJS】

WebGLで画像を表示する【PixiJS】 プログラミング

WebGLは、難しいモノと言う印象がありませんか?
「画像編集」、「画像生成」、「レンダリング」などのキーワードが並ぶとそうなりますよね。

もちろん、WebGLの画像処理には「画像表示」も含みます。
この画像表示は、一般的にはimgタグ(canvasでも可能)でやることが多いでしょう。

これだとCPUのみの利用です。
折角GPUを利用できるなら、GPUで画像を表示させませんか?

それができれば、画像表示の高速化を目指すことができます。
と言うより、WebGLによる画像表示を知らないとマイナス評価すら受けかねません。

また、画像表示はWebGLの基本中の基本です。
そこから、もっと高度な画像処理を行うための前提にもなります。

本記事の内容

  • WebGLによる画像処理を行うための準備
  • PixiJSを用いたWebGLによる画像表示
  • PIXI.Applicationクラス
  • PIXI.Applicationクラスのメンバー変数

それでは、上記に沿って解説していきましょう。

WebGLによる画像処理を行うための準備

PixiJSを利用します。
PixiJSに関しては、次の記事で説明しています。

上記記事では、PixiJSの導入方法まで説明しています。
PixiJSを導入する際には、そちらを参考にしてください。

あとは、もちろんGPU搭載のデバイスを用意することです。
ゲーミングPCなら、確実にGPUを搭載しています。

でも、古いPC・格安PCなどはGPUを搭載していないことが多いです。
その場合は、スマホで確認してください。
スマホなら、格安スマホでもGPUを搭載している可能性があります。

また、PixiJSはGPU未対応(搭載していない、無効にしている)の場合、canvasで画像処理を行います。
このような切り分けを自動でやってくれるので、ライブラリを使うべきなのです。

準備が整ったら、実際にコードを見ていきましょう。

PixiJSを用いたWebGLによる画像表示

PixiJSを用いたWebGLによる画像表示のサンプルコードは、以下。

<html>
<head>
  <meta charset="utf-8">
  <title>画像表示</title>
</head>
  <script src="./js/pixi.min.js"></script>
<body>
  <script type="text/javascript">
    // application生成
    const app = new PIXI.Application();

    // DOMにview(applicationの表示)を追加
    document.body.appendChild(app.view);

    // applicationにオブジェクトを追加(今回は、画像)
    app.stage.addChild(PIXI.Sprite.from('./img/dog.png'));
  </script>
</body>
</html>

短いので、htmlも含めています。
本来なら、jsavascriptの部分だけを表示すべきでしょうね。

pixi.min.jsやdog.pngのパスは各自の環境に合わせてください

dog.png

上記htmlにアクセスします。
問題なければ、この項の冒頭にある画像が表示されます。

もし、黒い背景だけで犬が表示されないなら、コンソールを確認します。

Access to image at 'file:各自の環境により異なる/img/dog.png' from origin 'null' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, chrome-untrusted, https.

上記のようなエラーが、出ているかもしれません。
これは、直接ファイルにアクセスしているから発生しているエラーです。
ブラウザのセキュリティが厳しいために、このエラーが発生しています。

その場合は、素直にWebサーバーを用意してください。
Webサーバーにファイルを設置して、ブラウザでアクセスするようにします。
そうすれば、エラーが出ません。

さて、コードでは以下の2点がポイントになります。

  • PIXI.Applicationクラス
  • PIXI.Spriteクラス

ただ、今回はPIXI.Spriteクラスの説明はしません。
PIXI.Applicationクラスの説明だけも、それなりのボリュームになります。
今回は、PIXI.Spriteクラスが画像の読み込みに必要だということだけを覚えましょう。

以下では、PIXI.Applicationクラスを説明していきます。

PIXI.Applicationクラス

const app = new PIXI.Application();

PixiJSで何かしらの処理を行う場合には、最初に記述します。
この記述により、PixiJSのアプリケーションを作成しています。

あくまで、 アプリケーションを作成しただけになります。

これだけでは、画面に何も表示されません。
そこで、次のコードでこの アプリケーションを見えるようにします。

document.body.appendChild(app.view);

ここまでは、おまじないみたいなモノなので理屈抜きに覚えましょう。
ただ、このままではあまりにも素っ気ないです。

大きさや色も自分で変更したくなります。
そういったモノをカスタマイズするために、オプションが用意されています。

new PIXI.Application ()
(※view=表示領域)

引数初期値説明
autoStartbooleantrue構築後の自動的レンダリングの有無
widthnumber800viewの横サイズ
heightnumber600viewの縦サイズ
viewHTMLCanvasElement
view(引数で受ける場合に利用)
transparentbooleanfalseviewの透過性
autoDensitybooleanfalseCSSピクセルによるviewサイズの変更可否
antialiasbooleanfalseアンチエイリアスの設定可否
preserveDrawingBufferbooleanfalse描画バッファの保存可否
resolutionnumber1CSSピクセル/物理ピクセルの比(通常は1、retinaは2)
forceCanvasbooleanfalse強制的Canvasモード(WebGLを利用しない)の利用有無
backgroundColornumber0x000000viewの背景色(16進数カラーコード)
clearBeforeRenderbooleantrueCanvasRendererによるCanvasクリアの設定有無
forceFXAAbooleanfalseFXAAアンチエイリアスの強制的利用有無
powerPreferencestring
WebGLコンテキストに渡す値(high-performance・low-power)
sharedTickerbooleanfalsePIXI.Ticker.sharedの利用有無(falseならticker新規作成)
sharedLoaderbooleanfalsePIXI.Loaders.sharedの利用有無(falseならLoader新規作成)
resizeToWindow |HTMLElement
自動的にstageのサイズを変更する要素

現時点は、不要なモノが多いです。
でも、こういう機会に頭の片隅に置いおくだけでも価値はあります。

とりあえず、よく使いそうな引数は以下あたりでしょうか。

  • width
  • height
  • transparent
  • backgroundColor

上記を用いて、以下の二つのケースを表示します。
それぞれ表示領域のサイズは、横400px、縦300pxとします。

  • 背景色を指定する
  • 背景を透明(透過)にする

背景色を指定する

    const app = new PIXI.Application({
                                      width:400,
                                      height:300,
                                      backgroundColor : "0x006400"
                                    });

(※「0x」は「#」と同義)

背景を透明(透過)にする

    const app = new PIXI.Application({
                                      width:400,
                                      height:300,
                                      transparent : true
                                    });

まとめ

PIXI.Applicationクラスでは、PixiJSのアプリケーションを作成します。
そして、その アプリケーションの見た目を次のように表現しています。

app.view

これをDOMに追加することにより、表示領域(view)を表示します。
このviewもそうなのですが、以下でも同じようにstageというモノが存在しています。

app.stage.addChild(PIXI.Sprite.from('./img/dog.png'));

このviewやstageのことをメンバー変数と言います。
これは、もうオブジェクト指向の話になってしまっていますね。
実際、PixiJSはオブジェクト指向で設計されているようです。

とにかく、PIXI.Applicationクラスで生成したオブジェクト(アプリケーション)には最初から変数が存在するということです。
じゃあ、どんなメンバー変数が存在するのか?

以下では、PIXI.Applicationクラスのメンバー変数を確認しましょう。

PIXI.Applicationクラスのメンバー変数

PIXI.Applicationクラスのメンバー変数は、以下。

変数名クラス名
loaderPIXI.Loader
rendererPIXI.Renderer | PIXI.CanvasRenderer
resizeToWindow | HTMLElement
screenPIXI.Rectangle
stagePIXI.Container
tickerPIXI.Ticker
viewHTMLCanvasElement

この中でも、すでに以下の2つは出てきました。

  • view
  • stage

この2つに関する説明は、以下。

view

オブジェクトの見た目だと表現しました。
正確には、レンダラーのcanvas要素です。

実際にhtmlソースを確認すると、確かにcanvasタグが表示されています。

stage

stageは、レンダリングされるルート表示コンテナのことです。
難しく聞こえますが、舞台のようなモノと覚えましょう。

舞台では、演者が必要です。
その演者を舞台に立たせましょう。

それを実現するのが、以下のコードになります。

app.stage.addChild(PIXI.Sprite.from('./img/dog.png'));

このコードにより、画像という演者を舞台に立たせているのです。

まとめ

ここまでの説明でなんとなくは、理解できたと思います。
ただ、viewとstageの関係がイマイチわかりませんよね。

なぜ、viewの上にstageがないのでしょうか?
それは、それぞれが独立しているからです。

viewは、表示領域に過ぎません。
例えると、渋谷スクランブル交差点に設置してあるライブカメラです。

あれは、渋谷スクランブル交差点というstageを映しているに過ぎません。
そして、そのstage上を人や車などのspriteが移動しているのです。

カメラと渋谷スクランブル交差点には、何も依存関係はありません。
それぞれ独立して存在しています。

カメラがなくても渋谷スクランブル交差点は存在します。
もちろん、そこを行き来する人や車も。

同様に、渋谷スクランブル交差点がなくてもカメラは存在します。
ただし、そこには何も映らないか、もしくは全然知らない交差点が映っているだけです。

以上より、viewとstageには依存関係がないと言えます。
単純に、viewはstageの一部を映しているだけです。

タイトルとURLをコピーしました