playcanvas
Version:
PlayCanvas WebGL game engine
97 lines (82 loc) • 2.91 kB
JavaScript
// --------------- POST EFFECT DEFINITION --------------- //
/**
* @class
* @name VignetteEffect
* @classdesc Implements the VignetteEffect post processing effect.
* @description Creates new instance of the post effect.
* @augments PostEffect
* @param {GraphicsDevice} graphicsDevice - The graphics device of the application.
* @property {number} offset Controls the offset of the effect.
* @property {number} darkness Controls the darkness of the effect.
*/
function VignetteEffect(graphicsDevice) {
pc.PostEffect.call(this, graphicsDevice);
// Shaders
var luminosityFrag = [
'uniform sampler2D uColorBuffer;',
'uniform float uDarkness;',
'uniform float uOffset;',
'',
'varying vec2 vUv0;',
'',
'void main() {',
' vec4 texel = texture2D(uColorBuffer, vUv0);',
' vec2 uv = (vUv0 - vec2(0.5)) * vec2(uOffset);',
' gl_FragColor = vec4(mix(texel.rgb, vec3(1.0 - uDarkness), dot(uv, uv)), texel.a);',
'}'
].join('\n');
this.vignetteShader = pc.ShaderUtils.createShader(graphicsDevice, {
uniqueName: 'VignetteShader',
attributes: { aPosition: pc.SEMANTIC_POSITION },
vertexGLSL: pc.PostEffect.quadVertexShader,
fragmentGLSL: luminosityFrag
});
this.offset = 1;
this.darkness = 1;
}
VignetteEffect.prototype = Object.create(pc.PostEffect.prototype);
VignetteEffect.prototype.constructor = VignetteEffect;
Object.assign(VignetteEffect.prototype, {
render: function (inputTarget, outputTarget, rect) {
var device = this.device;
var scope = device.scope;
scope.resolve('uColorBuffer').setValue(inputTarget.colorBuffer);
scope.resolve('uOffset').setValue(this.offset);
scope.resolve('uDarkness').setValue(this.darkness);
this.drawQuad(outputTarget, this.vignetteShader, rect);
}
});
// ----------------- SCRIPT DEFINITION ------------------ //
var Vignette = pc.createScript('vignette');
Vignette.attributes.add('offset', {
type: 'number',
default: 1,
min: 0,
title: 'Offset'
});
Vignette.attributes.add('darkness', {
type: 'number',
default: 1,
title: 'Darkness'
});
// initialize code called once per entity
Vignette.prototype.initialize = function () {
this.effect = new VignetteEffect(this.app.graphicsDevice);
this.effect.offset = this.offset;
this.effect.darkness = this.darkness;
this.on('attr', function (name, value) {
this.effect[name] = value;
}, this);
var queue = this.entity.camera.postEffects;
queue.addEffect(this.effect);
this.on('state', function (enabled) {
if (enabled) {
queue.addEffect(this.effect);
} else {
queue.removeEffect(this.effect);
}
});
this.on('destroy', function () {
queue.removeEffect(this.effect);
});
};