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=表示領域)
引数 | 型 | 初期値 | 説明 |
autoStart | boolean | true | 構築後の自動的レンダリングの有無 |
width | number | 800 | viewの横サイズ |
height | number | 600 | viewの縦サイズ |
view | HTMLCanvasElement | view(引数で受ける場合に利用) | |
transparent | boolean | false | viewの透過性 |
autoDensity | boolean | false | CSSピクセルによるviewサイズの変更可否 |
antialias | boolean | false | アンチエイリアスの設定可否 |
preserveDrawingBuffer | boolean | false | 描画バッファの保存可否 |
resolution | number | 1 | CSSピクセル/物理ピクセルの比(通常は1、retinaは2) |
forceCanvas | boolean | false | 強制的Canvasモード(WebGLを利用しない)の利用有無 |
backgroundColor | number | 0x000000 | viewの背景色(16進数カラーコード) |
clearBeforeRender | boolean | true | CanvasRendererによるCanvasクリアの設定有無 |
forceFXAA | boolean | false | FXAAアンチエイリアスの強制的利用有無 |
powerPreference | string | WebGLコンテキストに渡す値(high-performance・low-power) | |
sharedTicker | boolean | false | PIXI.Ticker.sharedの利用有無(falseならticker新規作成) |
sharedLoader | boolean | false | PIXI.Loaders.sharedの利用有無(falseならLoader新規作成) |
resizeTo | Window |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クラスのメンバー変数は、以下。
変数名 | クラス名 |
loader | PIXI.Loader |
renderer | PIXI.Renderer | PIXI.CanvasRenderer |
resizeTo | Window | HTMLElement |
screen | PIXI.Rectangle |
stage | PIXI.Container |
ticker | PIXI.Ticker |
view | HTMLCanvasElement |
この中でも、すでに以下の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の一部を映しているだけです。