カスタムポストエフェクト
このチュートリアルでは、GLSLのカスタムポストエフェクトを使用してエフェクトを作成します。
概要
PlayCanvasでは、JavaScriptとGLSLを使用して独自のポストエフェクトを作成できます。ポストエフェクトは、カメラからの2Dレンダリングされたイメージに対して作用するシェーダーです。イメージに複数のポストエフェクトを適用でき、それぞれのエフェクトは前のエフェクトの出力を入力として使用します。
以下の段落では、独自のポストエフェクトを作成する方法を説明します。既存のポストエフェクトの例は、ここにあります。
スクリプト
最初に新しいスクリプトを作成する必要があります。このスクリプトには、ポストエフェクトのシェーダー定義と、ポストエフェクトをカメラに追加するコードが含まれます。このスクリプトは、Cameraコンポーネントを持つエンティティにアタッチする必要があります。スクリプト名は「posteffect_example.js」とします。
エフェクト
次に、ポストエフェクト用の新しいクラスを作成する必要があります。このクラスは pc.posteffect.PostEffect から派生します。このクラスの定義は、スクリプトの定義の直前に posteffect_example.js スクリプト内に記述します。
pc.extend(pc, function () {
// Constructor - Creates an instance of our post effect
var ExamplePostEffect = function (graphicsDevice, vs, fs) {
// this is the shader definition for our effect
this.shader = new pc.Shader(graphicsDevice, {
attributes: {
aPosition: pc.SEMANTIC_POSITION
},
vshader: vs,
fshader: fs
});
};
// Our effect must derive from pc.PostEffect
ExamplePostEffect = pc.inherits(ExamplePostEffect, pc.PostEffect);
ExamplePostEffect.prototype = pc.extend(ExamplePostEffect.prototype, {
// Every post effect must implement the render method which
// sets any parameters that the shader might require and
// also renders the effect on the screen
render: function (inputTarget, outputTarget, rect) {
var device = this.device;
var scope = device.scope;
// Set the input render target to the shader. This is the image rendered from our camera
scope.resolve("uColorBuffer").setValue(inputTarget.colorBuffer);
// Draw a full screen quad on the output target. In this case the output target is the screen.
// Drawing a full screen quad will run the shader that we defined above
pc.drawFullscreenQuad(device, outputTarget, this.vertexBuffer, this.shader, rect);
}
});
return {
ExamplePostEffect: ExamplePostEffect
};
}());
終了
これで、ポストエフェクトに必要なすべてのコンポーネントが揃いました。定義したExamplePostEffectのインスタンスを、カメラのpost effect queueに追加するだけです。以下が完全なリストです。
//--------------- POST EFFECT DEFINITION------------------------//
pc.extend(pc, function () {
// Constructor - Creates an instance of our post effect
var ExamplePostEffect = function (graphicsDevice, vs, fs) {
// this is the shader definition for our effect
this.shader = new pc.Shader(graphicsDevice, {
attributes: {
aPosition: pc.SEMANTIC_POSITION
},
vshader: vs,
fshader: fs
});
};
// Our effect must derive from pc.PostEffect
ExamplePostEffect = pc.inherits(ExamplePostEffect, pc.PostEffect);
ExamplePostEffect.prototype = pc.extend(ExamplePostEffect.prototype, {
// Every post effect must implement the render method which
// sets any parameters that the shader might require and
// also renders the effect on the screen
render: function (inputTarget, outputTarget, rect) {
var device = this.device;
var scope = device.scope;
// Set the input render target to the shader. This is the image rendered from our camera
scope.resolve("uColorBuffer").setValue(inputTarget.colorBuffer);
// Draw a full screen quad on the output target. In this case the output target is the screen.
// Drawing a full screen quad will run the shader that we defined above
pc.drawFullscreenQuad(device, outputTarget, this.vertexBuffer, this.shader, rect);
}
});
return {
ExamplePostEffect: ExamplePostEffect
};
}());
//--------------- SCRIPT DEFINITION------------------------//
var PosteffectExample = pc.createScript('posteffectExample');
PosteffectExample.attributes.add('vs', {
type: 'asset',
assetType: 'shader',
title: 'Vertex Shader'
});
PosteffectExample.attributes.add('fs', {
type: 'asset',
assetType: 'shader',
title: 'Fragment Shader'
});
// initialize code called once per entity
PosteffectExample.prototype.initialize = function() {
var effect = new pc.ExamplePostEffect(this.app.graphicsDevice, this.vs.resource, this.fs.resource);
// add the effect to the camera's postEffects queue
var queue = this.entity.camera.postEffects;
queue.addEffect(effect);
// when the script is enabled add our effect to the camera's postEffects queue
this.on('enable', function () {
queue.addEffect(effect, false);
});
// when the script is disabled remove our effect from the camera's postEffects queue
this.on('disable', function () {
queue.removeEffect(effect);
});
};
カスタムシェーダーの詳細についてはこちらを参照してください。