【PlayCanvas】シェーダーの基礎!!塗りつぶし編!!

【PlayCanvas】シェーダーの基礎!!塗りつぶし編!!

福田です!!
今日はPlayCanvasでのシェーダーの実装について紹介していこうと思います!!

PlayCanvasでのシェーダーの実装についての初心者向けリファレンスはかなり少ないというのが個人的な感想です。
なので、初心者に向けて復習を兼ねて(福田も初心者です)解説していこうと思います!


今回取り扱うのはシェーダーでのオブジェクトの塗りつぶしです!
ただ塗りつぶすだけならほかにもやり方あるじゃん!と思いましたか?
その考えは正解です!
ただし、「塗りつぶすだけなら」という枕詞がつきます。

複雑な画像や解像度の問題、色が変わるものや動くもの。
いろいろな表現をしたい時にどうしますか?

やり方はたくさんあってシェーダーもそのうちの一つです。
とっつきにくいけどその分カスタム性が高く、解像度も自由自在、さらにサイズも少なく抑えられるシェーダーはきっとあなたの手助けになることでしょう!
まあ候補として出せる案が多いと問題解決も早くなるよね!という話です!



早速ですがこちらはPlayCanvas上に配置したオブジェクトにシェーダーで色を付けたものです!

きれいに塗りつぶせています!

ではこのプロジェクトをもとに解説していきますね。

まずPlayCanvasのシェーダーは基本的に3つに分かれています。(認識違ったらごめんなさい!!)
・シェーダーを管理するスクリプト
・頂点情報を管理するVertex(頂点)シェーダー
・画面出力を管理するFragmentシェーダー

この3つを使うことでオブジェクトやマテリアルに変化を与えることができるわけですね。

ではそれぞれどんな風に使っていくのか、コードと一緒に見ていきましょう。

まずはスクリプトです!

var Shader = pc.createScript('shader');

//各シェーダの窓口を作ります。
Shader.attributes.add('frag', { type: 'asset', assetType: "shader" });
Shader.attributes.add('vert', { type: 'asset', assetType: "shader" });

// 最初の一回に呼び出す処理です。
Shader.prototype.initialize = function() {

    var app = this.app;
    var gd = app.graphicsDevice;

    //頂点シェーダの取得
    var vertexShader = this.vert.resource;
    //フラグメントシェーダの取得
    var fragmentShader = "precision " + gd.precision + " float;\n";
    fragmentShader = fragmentShader + this.frag.resource;

    //頂点シェーダに値を渡します
    var shaderDefinition = {
        attributes: {
            aPosition: pc.SEMANTIC_POSITION,
            aUv0: pc.SEMANTIC_TEXCOORD0
        },
        vshader: vertexShader,
        fshader: fragmentShader
    };

    //頂点シェーダとフラグメントシェーダを渡します
    this.shader = new pc.Shader(gd, shaderDefinition);

    //マテリアルの作成をします
    this.material = new pc.Material();
    //作成したマテリアルのシェーダに今のシェーダを渡します
    this.material.shader = this.shader;

    var renders = this.entity.findComponents('render');

    var meshInstances = renders[0].meshInstances;
    meshInstances[0].material = this.material;

};

ある程度コード内に解説を書いてあるのでご一読ください!

次は頂点シェーダーです!(といっても今回いじることはほぼないようなものですが)

attribute vec3 aPosition;
attribute vec2 aUv0;

//(説明は以降の記事で紹介します。今はおまじないと思ってください)
uniform mat4 matrix_model;
uniform mat4 matrix_viewProjection;

varying vec2 vUv0;

void main(void)
{
    vUv0 = aUv0;
    gl_Position = matrix_viewProjection * matrix_model * vec4(aPosition, 1.0);
}

頂点シェーダのお仕事は簡単に言えば3D空間上に存在する頂点の位置をユーザーが使っているデバイスのピクセル座標に変換することです!!
変換した情報をフラグメントシェーダに送ることで塗りつぶすためのキャンバスを作るんですね~!

最後はFragmentシェーダーです。
今回の肝といってもいいでしょう!

void main(void)
{
    gl_FragColor = vec4(1.0, 0.0, 0.0, 0.0);
}

え?肝小さくない?という感じですがこれでオッケーです!
gl_FlagColorは色を指定することで塗りつぶしをすることができます!
頂点シェーダーがくれた範囲を全部塗りつぶしましょう!!
ただし注意です!
この塗りつぶしは最後の最後に行われます。
ライティングや影の調整などをしても最後の画面出力時に塗りつぶしちゃうので注意をしてください!



いかがだったでしょうか?
なんとな~くシェーダーについてわかってもらえたのではないでしょうか?

これからも続報を出せるように精進していくので、ぜひお待ちいただけたら嬉しいです!
福田でした!


現在シェルパグループでは、一緒に働く仲間を募集中!
建築パース、3DCG、UnrealEngine、Unity、プログラミングに興味のある方は
是非リクルートサイトをご覧ください!

■シェルパグループ リクルートサイト
https://sherpa-recruit.jp/