mirror of
https://github.com/photonstorm/phaser
synced 2024-12-23 19:43:28 +00:00
465 lines
12 KiB
JavaScript
465 lines
12 KiB
JavaScript
|
/**
|
||
|
* @author Richard Davey <rich@photonstorm.com>
|
||
|
* @copyright 2020 Photon Storm Ltd.
|
||
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
||
|
*/
|
||
|
|
||
|
var Class = require('../utils/Class');
|
||
|
|
||
|
/**
|
||
|
* @classdesc
|
||
|
* The ColorMatrix class creates a 5x5 matrix that can be used in shaders and graphics
|
||
|
* operations. It provides methods required to modify the color values, such as adjusting
|
||
|
* the brightness, setting a sepia tone, hue rotation and more.
|
||
|
*
|
||
|
* Use the method `getData` to return a Float32Array containing the current color values.
|
||
|
*
|
||
|
* @class ColorMatrix
|
||
|
* @memberof Phaser.Display
|
||
|
* @constructor
|
||
|
* @since 3.50.0
|
||
|
*/
|
||
|
var ColorMatrix = new Class({
|
||
|
|
||
|
initialize:
|
||
|
|
||
|
function ColorMatrix ()
|
||
|
{
|
||
|
/**
|
||
|
* Internal ColorMatrix array.
|
||
|
*
|
||
|
* @name Phaser.Display.ColorMatrix#_matrix
|
||
|
* @type {number[]}
|
||
|
* @private
|
||
|
* @since 3.50.0
|
||
|
*/
|
||
|
this._matrix;
|
||
|
|
||
|
/**
|
||
|
* Is the ColorMatrix array dirty?
|
||
|
*
|
||
|
* @name Phaser.Display.ColorMatrix#_dirty
|
||
|
* @type {boolean}
|
||
|
* @private
|
||
|
* @since 3.50.0
|
||
|
*/
|
||
|
this._dirty = true;
|
||
|
|
||
|
/**
|
||
|
* The matrix data as a Float32Array.
|
||
|
*
|
||
|
* Returned by the `getData` method.
|
||
|
*
|
||
|
* @name Phaser.Display.ColorMatrix#data
|
||
|
* @type {Float32Array}
|
||
|
* @private
|
||
|
* @since 3.50.0
|
||
|
*/
|
||
|
this._data;
|
||
|
|
||
|
this.reset();
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Sets this ColorMatrix from the given array of color values.
|
||
|
*
|
||
|
* @method Phaser.Display.ColorMatrix#set
|
||
|
* @since 3.50.0
|
||
|
*
|
||
|
* @param {number[]} value - The ColorMatrix values to set.
|
||
|
*
|
||
|
* @return {this} This ColorMatrix instance.
|
||
|
*/
|
||
|
set: function (value)
|
||
|
{
|
||
|
this._matrix = value;
|
||
|
|
||
|
this._dirty = true;
|
||
|
|
||
|
return this;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Resets the ColorMatrix.
|
||
|
*
|
||
|
* @method Phaser.Display.ColorMatrix#reset
|
||
|
* @since 3.50.0
|
||
|
*
|
||
|
* @return {this} This ColorMatrix instance.
|
||
|
*/
|
||
|
reset: function ()
|
||
|
{
|
||
|
this._matrix = [
|
||
|
1, 0, 0, 0, 0,
|
||
|
0, 1, 0, 0, 0,
|
||
|
0, 0, 1, 0, 0,
|
||
|
0, 0, 0, 1, 0,
|
||
|
0, 0, 0, 0, 1
|
||
|
];
|
||
|
|
||
|
this._dirty = true;
|
||
|
|
||
|
return this;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Gets the ColorMatrix as a Float32Array.
|
||
|
*
|
||
|
* Can be used directly as a 1fv shader uniform value.
|
||
|
*
|
||
|
* @method Phaser.Display.ColorMatrix#getData
|
||
|
* @since 3.50.0
|
||
|
*
|
||
|
* @return {Float32Array} The ColorMatrix as a Float32Array.
|
||
|
*/
|
||
|
getData: function ()
|
||
|
{
|
||
|
if (this._dirty)
|
||
|
{
|
||
|
var f32 = new Float32Array(this._matrix);
|
||
|
|
||
|
f32[4] /= 255;
|
||
|
f32[9] /= 255;
|
||
|
f32[14] /= 255;
|
||
|
f32[19] /= 255;
|
||
|
|
||
|
this._data = f32;
|
||
|
|
||
|
this._dirty = false;
|
||
|
}
|
||
|
|
||
|
return this._data;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Changes the brightness of this ColorMatrix by the given amount.
|
||
|
*
|
||
|
* @method Phaser.Display.ColorMatrix#brightness
|
||
|
* @since 3.50.0
|
||
|
*
|
||
|
* @param {number} [value=0] - The amount of brightness to apply to this ColorMatrix.
|
||
|
*
|
||
|
* @return {this} This ColorMatrix instance.
|
||
|
*/
|
||
|
brightness: function (value)
|
||
|
{
|
||
|
if (value === undefined) { value = 0; }
|
||
|
|
||
|
var b = value + 1;
|
||
|
|
||
|
return this.multiply(this._matrix, [
|
||
|
b, 0, 0, 0, 0,
|
||
|
0, b, 0, 0, 0,
|
||
|
0, 0, b, 0, 0,
|
||
|
0, 0, 0, 1, 0,
|
||
|
0, 0, 0, 0, 1
|
||
|
]);
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Changes the saturation of this ColorMatrix by the given amount.
|
||
|
*
|
||
|
* @method Phaser.Display.ColorMatrix#saturation
|
||
|
* @since 3.50.0
|
||
|
*
|
||
|
* @param {number} [value=0] - The amount of saturation to apply to this ColorMatrix.
|
||
|
*
|
||
|
* @return {this} This ColorMatrix instance.
|
||
|
*/
|
||
|
saturation: function (value)
|
||
|
{
|
||
|
if (value === undefined) { value = 0; }
|
||
|
|
||
|
var x = value * 2 / 3 + 1;
|
||
|
var y = ((x - 1) * -0.5);
|
||
|
|
||
|
return this.multiply(this._matrix, [
|
||
|
x, y, y, 0, 0,
|
||
|
y, x, y, 0, 0,
|
||
|
y, y, x, 0, 0,
|
||
|
0, 0, 0, 1, 0,
|
||
|
0, 0, 0, 0, 1
|
||
|
]);
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Rotates the hues of this ColorMatrix by the value given.
|
||
|
*
|
||
|
* @method Phaser.Display.ColorMatrix#hue
|
||
|
* @since 3.50.0
|
||
|
*
|
||
|
* @param {number} [rotation=0] - The amount of hue rotation to apply to this ColorMatrix, in degrees.
|
||
|
*
|
||
|
* @return {this} This ColorMatrix instance.
|
||
|
*/
|
||
|
hue: function (rotation)
|
||
|
{
|
||
|
if (rotation === undefined) { rotation = 0; }
|
||
|
|
||
|
rotation = rotation / 180 * Math.PI;
|
||
|
|
||
|
var cos = Math.cos(rotation);
|
||
|
var sin = Math.sin(rotation);
|
||
|
var lumR = 0.213;
|
||
|
var lumG = 0.715;
|
||
|
var lumB = 0.072;
|
||
|
|
||
|
return this.multiply(this._matrix, [
|
||
|
lumR + cos * (1 - lumR) + sin * (-lumR),lumG + cos * (-lumG) + sin * (-lumG),lumB + cos * (-lumB) + sin * (1 - lumB), 0, 0,
|
||
|
lumR + cos * (-lumR) + sin * (0.143),lumG + cos * (1 - lumG) + sin * (0.140),lumB + cos * (-lumB) + sin * (-0.283), 0, 0,
|
||
|
lumR + cos * (-lumR) + sin * (-(1 - lumR)),lumG + cos * (-lumG) + sin * (lumG),lumB + cos * (1 - lumB) + sin * (lumB), 0, 0,
|
||
|
0, 0, 0, 1, 0,
|
||
|
0, 0, 0, 0, 1
|
||
|
]);
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Sets this ColorMatrix to be grayscale.
|
||
|
*
|
||
|
* @method Phaser.Display.ColorMatrix#grayscale
|
||
|
* @since 3.50.0
|
||
|
*
|
||
|
* @return {this} This ColorMatrix instance.
|
||
|
*/
|
||
|
grayscale: function ()
|
||
|
{
|
||
|
return this.saturation(-1);
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Change the contrast of this ColorMatrix by the amount given.
|
||
|
*
|
||
|
* @method Phaser.Display.ColorMatrix#contrast
|
||
|
* @since 3.50.0
|
||
|
*
|
||
|
* @param {number} [value=0] - The amount of contrast to apply to this ColorMatrix.
|
||
|
*
|
||
|
* @return {this} This ColorMatrix instance.
|
||
|
*/
|
||
|
contrast: function (value)
|
||
|
{
|
||
|
if (value === undefined) { value = 0; }
|
||
|
|
||
|
var v = value + 1;
|
||
|
var o = -128 * (v - 1);
|
||
|
|
||
|
return this.multiply(this._matrix, [
|
||
|
v, 0, 0, 0, o,
|
||
|
0, v, 0, 0, o,
|
||
|
0, 0, v, 0, o,
|
||
|
0, 0, 0, 1, 0,
|
||
|
0, 0, 0, 0, 1
|
||
|
]);
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Converts this ColorMatrix to have negative values.
|
||
|
*
|
||
|
* @method Phaser.Display.ColorMatrix#negative
|
||
|
* @since 3.50.0
|
||
|
*
|
||
|
* @return {this} This ColorMatrix instance.
|
||
|
*/
|
||
|
negative: function ()
|
||
|
{
|
||
|
return this.contrast(-2);
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Apply a desaturated luminance to this ColorMatrix.
|
||
|
*
|
||
|
* @method Phaser.Display.ColorMatrix#desaturateLuminance
|
||
|
* @since 3.50.0
|
||
|
*
|
||
|
* @return {this} This ColorMatrix instance.
|
||
|
*/
|
||
|
desaturateLuminance: function ()
|
||
|
{
|
||
|
return this.multiply(this._matrix, [
|
||
|
0.2764723, 0.9297080, 0.0938197, 0, -37.1,
|
||
|
0.2764723, 0.9297080, 0.0938197, 0, -37.1,
|
||
|
0.2764723, 0.9297080, 0.0938197, 0, -37.1,
|
||
|
0, 0, 0, 1, 0,
|
||
|
0, 0, 0, 0, 1
|
||
|
]);
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Applies a sepia tone to this ColorMatrix.
|
||
|
*
|
||
|
* @method Phaser.Display.ColorMatrix#sepia
|
||
|
* @since 3.50.0
|
||
|
*
|
||
|
* @return {this} This ColorMatrix instance.
|
||
|
*/
|
||
|
sepia: function ()
|
||
|
{
|
||
|
return this.multiply(this._matrix, [
|
||
|
0.393, 0.7689999, 0.18899999, 0, 0,
|
||
|
0.349, 0.6859999, 0.16799999, 0, 0,
|
||
|
0.272, 0.5339999, 0.13099999, 0, 0,
|
||
|
0, 0, 0, 1, 0,
|
||
|
0, 0, 0, 0, 1
|
||
|
]);
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Applies a brown tone to this ColorMatrix.
|
||
|
*
|
||
|
* @method Phaser.Display.ColorMatrix#brown
|
||
|
* @since 3.50.0
|
||
|
*
|
||
|
* @return {this} This ColorMatrix instance.
|
||
|
*/
|
||
|
brown: function ()
|
||
|
{
|
||
|
return this.multiply(this._matrix, [
|
||
|
0.5997023498159715, 0.34553243048391263, -0.2708298674538042, 0, 47.43192855600873,
|
||
|
-0.037703249837783157, 0.8609577587992641, 0.15059552388459913, 0, -36.96841498319127,
|
||
|
0.24113635128153335, -0.07441037908422492, 0.44972182064877153, 0, -7.562075277591283,
|
||
|
0, 0, 0, 1, 0,
|
||
|
0, 0, 0, 0, 1
|
||
|
]);
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Applies a vintage pinhole color effect to this ColorMatrix.
|
||
|
*
|
||
|
* @method Phaser.Display.ColorMatrix#vintagePinhole
|
||
|
* @since 3.50.0
|
||
|
*
|
||
|
* @return {this} This ColorMatrix instance.
|
||
|
*/
|
||
|
vintagePinhole: function ()
|
||
|
{
|
||
|
return this.multiply(this._matrix, [
|
||
|
0.6279345635605994, 0.3202183420819367, -0.03965408211312453, 0, 9.651285835294123,
|
||
|
0.02578397704808868, 0.6441188644374771, 0.03259127616149294, 0, 7.462829176470591,
|
||
|
0.0466055556782719, -0.0851232987247891, 0.5241648018700465, 0, 5.159190588235296,
|
||
|
0, 0, 0, 1, 0,
|
||
|
0, 0, 0, 0, 1
|
||
|
]);
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Applies a kodachrome color effect to this ColorMatrix.
|
||
|
*
|
||
|
* @method Phaser.Display.ColorMatrix#kodachrome
|
||
|
* @since 3.50.0
|
||
|
*
|
||
|
* @return {this} This ColorMatrix instance.
|
||
|
*/
|
||
|
kodachrome: function ()
|
||
|
{
|
||
|
return this.multiply(this._matrix, [
|
||
|
1.1285582396593525, -0.3967382283601348, -0.03992559172921793, 0, 63.72958762196502,
|
||
|
-0.16404339962244616, 1.0835251566291304, -0.05498805115633132, 0, 24.732407896706203,
|
||
|
-0.16786010706155763, -0.5603416277695248, 1.6014850761964943, 0, 35.62982807460946,
|
||
|
0, 0, 0, 1, 0,
|
||
|
0, 0, 0, 0, 1
|
||
|
]);
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Applies a technicolor color effect to this ColorMatrix.
|
||
|
*
|
||
|
* @method Phaser.Display.ColorMatrix#technicolor
|
||
|
* @since 3.50.0
|
||
|
*
|
||
|
* @return {this} This ColorMatrix instance.
|
||
|
*/
|
||
|
technicolor: function ()
|
||
|
{
|
||
|
return this.multiply(this._matrix, [
|
||
|
1.9125277891456083, -0.8545344976951645, -0.09155508482755585, 0, 11.793603434377337,
|
||
|
-0.3087833385928097, 1.7658908555458428, -0.10601743074722245, 0, -70.35205161461398,
|
||
|
-0.231103377548616, -0.7501899197440212, 1.847597816108189, 0, 30.950940869491138,
|
||
|
0, 0, 0, 1, 0,
|
||
|
0, 0, 0, 0, 1
|
||
|
]);
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Applies a polaroid color effect to this ColorMatrix.
|
||
|
*
|
||
|
* @method Phaser.Display.ColorMatrix#polaroid
|
||
|
* @since 3.50.0
|
||
|
*
|
||
|
* @return {this} This ColorMatrix instance.
|
||
|
*/
|
||
|
polaroid: function ()
|
||
|
{
|
||
|
return this.multiply(this._matrix, [
|
||
|
1.438, -0.062, -0.062, 0, 0,
|
||
|
-0.122, 1.378, -0.122, 0, 0,
|
||
|
-0.016, -0.016, 1.483, 0, 0,
|
||
|
0, 0, 0, 1, 0,
|
||
|
0, 0, 0, 0, 1
|
||
|
]);
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Shifts the values of this ColorMatrix into BGR order.
|
||
|
*
|
||
|
* @method Phaser.Display.ColorMatrix#shiftToBGR
|
||
|
* @since 3.50.0
|
||
|
*
|
||
|
* @return {this} This ColorMatrix instance.
|
||
|
*/
|
||
|
shiftToBGR: function ()
|
||
|
{
|
||
|
return this.multiply(this._matrix, [
|
||
|
0, 0, 1, 0, 0,
|
||
|
0, 1, 0, 0, 0,
|
||
|
1, 0, 0, 0, 0,
|
||
|
0, 0, 0, 1, 0,
|
||
|
0, 0, 0, 0, 1
|
||
|
]);
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Multiplies the two given matrices.
|
||
|
*
|
||
|
* @method Phaser.Display.ColorMatrix#multiply
|
||
|
* @since 3.50.0
|
||
|
*
|
||
|
* @param {number[]} a - The first ColorMatrix array to multiply.
|
||
|
* @param {number[]} b - The second ColorMatrix array to multiply.
|
||
|
*
|
||
|
* @return {this} This ColorMatrix instance.
|
||
|
*/
|
||
|
multiply: function (a, b)
|
||
|
{
|
||
|
var j;
|
||
|
var k;
|
||
|
var col = [];
|
||
|
|
||
|
for (var i = 0; i < 5; i++)
|
||
|
{
|
||
|
for (j = 0; j < 5; j++)
|
||
|
{
|
||
|
col[j] = a[j + i * 5];
|
||
|
}
|
||
|
|
||
|
for (j = 0; j < 5; j++)
|
||
|
{
|
||
|
var val = 0;
|
||
|
|
||
|
for (k = 0; k < 5; k++)
|
||
|
{
|
||
|
val += b[j + k * 5] * col[k];
|
||
|
}
|
||
|
|
||
|
a[j + i * 5] = val;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
this._dirty = true;
|
||
|
|
||
|
return this;
|
||
|
}
|
||
|
|
||
|
});
|
||
|
|
||
|
module.exports = ColorMatrix;
|