shaku
Version:
A simple and effective JavaScript game development framework that knows its place!
121 lines (103 loc) • 4.17 kB
JavaScript
/**
* Implement a basic effect to draw sprites with outline.
*
* |-- copyright and license --|
* @module Shaku
* @file shaku\src\gfx\effects\sprites_with_outline.js
* @author Ronen Ness (ronenness@gmail.com | http://ronenness.com)
* @copyright (c) 2021 Ronen Ness
* @license MIT
* |-- end copyright and license --|
*
*/
'use strict';
const Effect = require("./effect");
// vertex shader code
const vertexShader = `
attribute vec3 position;
attribute vec2 uv;
attribute vec4 color;
uniform vec4 outlineColor;
uniform mat4 projection;
uniform mat4 world;
varying vec2 v_texCoord;
varying vec4 v_color;
void main(void) {
gl_Position = projection * world * vec4(position, 1.0);
gl_PointSize = 1.0;
v_texCoord = uv;
v_color = color;
}
`;
// fragment shader code
const fragmentShader = `
precision highp float;
uniform sampler2D mainTexture;
uniform float textureWidth;
uniform float textureHeight;
uniform vec4 outlineColor;
uniform float outlineWeight;
varying vec2 v_texCoord;
varying vec4 v_color;
void main(void) {
float total = 0.0;
float grabPixel;
float facX = (1.0 / textureWidth) * 2.0;
float facY = (1.0 / textureHeight) * 2.0;
total += texture2D(mainTexture, v_texCoord + vec2(-facX, -facY)).a;
total += texture2D(mainTexture, v_texCoord + vec2(facX, -facY)).a;
total += texture2D(mainTexture, v_texCoord + vec2(facX, facY)).a;
total += texture2D(mainTexture, v_texCoord + vec2(-facX, facY)).a;
total += texture2D(mainTexture, v_texCoord + vec2(0.0, -facY)).a * 2.0;
total += texture2D(mainTexture, v_texCoord + vec2(0.0, facY)).a * 2.0;
total += texture2D(mainTexture, v_texCoord + vec2(-facX, 0.0)).a * 2.0;
total += texture2D(mainTexture, v_texCoord + vec2(facX, 0.0)).a * 2.0;
total *= outlineWeight;
vec4 currColor = texture2D(mainTexture, v_texCoord);
gl_FragColor = (currColor.a >= 0.9) ? currColor : (outlineColor * vec4(1,1,1,total));
gl_FragColor.rgb *= gl_FragColor.a;
}
`;
/**
* Default basic effect to draw 2d sprites with outline.
*/
class SpritesWithOutlineEffect extends Effect
{
/** @inheritdoc */
get vertexCode()
{
return vertexShader;
}
/** @inheritdoc */
get fragmentCode()
{
return fragmentShader;
}
/** @inheritdoc */
get uniformTypes()
{
return {
[]: { type: Effect.UniformTypes.Texture, bind: Effect.UniformBinds.MainTexture },
[]: { type: Effect.UniformTypes.Matrix, bind: Effect.UniformBinds.Projection },
[]: { type: Effect.UniformTypes.Matrix, bind: Effect.UniformBinds.World },
[]: { type: Effect.UniformTypes.Matrix, bind: Effect.UniformBinds.View },
[]: { type: Effect.UniformTypes.Color, bind: Effect.UniformBinds.OutlineColor },
[]: { type: Effect.UniformTypes.Float, bind: Effect.UniformBinds.TextureWidth },
[]: { type: Effect.UniformTypes.Float, bind: Effect.UniformBinds.TextureHeight },
[]: { type: Effect.UniformTypes.Float, bind: Effect.UniformBinds.OutlineWeight },
};
}
/** @inheritdoc */
get attributeTypes()
{
return {
[]: { size: 3, type: Effect.AttributeTypes.Float, normalize: false, bind: Effect.AttributeBinds.Position },
[]: { size: 2, type: Effect.AttributeTypes.Float, normalize: false, bind: Effect.AttributeBinds.TextureCoords },
[]: { size: 4, type: Effect.AttributeTypes.Float, normalize: false, bind: Effect.AttributeBinds.Colors },
};
}
}
// export the basic shader
module.exports = SpritesWithOutlineEffect;