add Sprite.pattern_blend_type

This commit is contained in:
Struma 2021-11-29 21:58:18 -05:00
parent 3dc2128b25
commit 725d593db3
7 changed files with 93 additions and 11 deletions

View file

@ -65,6 +65,7 @@ DEF_GFX_PROP_I(Sprite, BushDepth)
DEF_GFX_PROP_I(Sprite, BushOpacity)
DEF_GFX_PROP_I(Sprite, Opacity)
DEF_GFX_PROP_I(Sprite, BlendType)
DEF_GFX_PROP_I(Sprite, PatternBlendType)
DEF_GFX_PROP_I(Sprite, PatternOpacity)
DEF_GFX_PROP_I(Sprite, PatternScrollX)
DEF_GFX_PROP_I(Sprite, PatternScrollY)
@ -141,6 +142,7 @@ void spriteBindingInit() {
INIT_PROP_BIND(Sprite, BushOpacity, "bush_opacity");
INIT_PROP_BIND(Sprite, Pattern, "pattern");
INIT_PROP_BIND(Sprite, PatternBlendType, "pattern_blend_type");
INIT_PROP_BIND(Sprite, PatternTile, "pattern_tile");
INIT_PROP_BIND(Sprite, PatternOpacity, "pattern_opacity");
INIT_PROP_BIND(Sprite, PatternScrollX, "pattern_scroll_x");

View file

@ -10,6 +10,7 @@ uniform float bushDepth;
uniform lowp float bushOpacity;
uniform sampler2D pattern;
uniform int patternBlendType;
uniform lowp float patternOpacity;
uniform bool renderPattern;
@ -21,6 +22,47 @@ varying vec2 v_patCoord;
const vec3 lumaF = vec3(.299, .587, .114);
const vec2 repeat = vec2(1, 1);
// = = = = = = = = = = =
// mixing functions, from https://github.com/jamieowen/glsl-blend
// = = = = = = = = = = =
// Normal
vec3 blendNormal(vec3 base, vec3 blend) {
return blend;
}
vec3 blendNormal(vec3 base, vec3 blend, float opacity) {
return (blendNormal(base, blend) * opacity + base * (1.0 - opacity));
}
// Add
float blendAdd(float base, float blend) {
return min(base+blend,1.0);
}
vec3 blendAdd(vec3 base, vec3 blend) {
return min(base+blend,vec3(1.0));
}
vec3 blendAdd(vec3 base, vec3 blend, float opacity) {
return (blendAdd(base, blend) * opacity + base * (1.0 - opacity));
}
// Substract
float blendSubstract(float base, float blend) {
return max(base+blend-1.0,0.0);
}
vec3 blendSubstract(vec3 base, vec3 blend) {
return max(base+blend-vec3(1.0),vec3(0.0));
}
vec3 blendSubstract(vec3 base, vec3 blend, float opacity) {
return (blendSubstract(base, blend) * opacity + blend * (1.0 - opacity));
}
// = = = = = = = = = = =
void main()
{
/* Sample source color */
@ -29,12 +71,15 @@ void main()
/* Apply pattern */
if (renderPattern) {
vec4 pattfrag = texture2D(pattern, mod(v_patCoord, repeat));
frag.rgb = mix(frag.rgb, pattfrag.rgb, pattfrag.a * patternOpacity);
}
/* Apply color inversion */
if (invert) {
frag.rgb = vec3(1.0 - frag.r, 1.0 - frag.g, 1.0 - frag.b);
if (patternBlendType == 1) {
frag.rgb = frag.rgb = blendAdd(frag.rgb, pattfrag.rgb, pattfrag.a * patternOpacity);
}
else if (patternBlendType == 2) {
frag.rgb = blendSubstract(frag.rgb, pattfrag.rgb, pattfrag.a * patternOpacity);
}
else {
frag.rgb = blendNormal(frag.rgb, pattfrag.rgb, pattfrag.a * patternOpacity);
}
}
/* Apply gray */
@ -50,6 +95,11 @@ void main()
/* Apply color */
frag.rgb = mix(frag.rgb, color.rgb, color.a);
/* Apply color inversion */
if (invert) {
frag.rgb = vec3(1.0 - frag.r, 1.0 - frag.g, 1.0 - frag.b);
}
/* Apply bush alpha by mathematical if */
lowp float underBush = float(v_texCoord.y < bushDepth);
frag.a *= clamp(bushOpacity + underBush, 0.0, 1.0);

View file

@ -24,12 +24,12 @@ void main()
if (renderPattern) {
if (patternTile) {
vec2 scroll = patternScroll * patternZoom;
v_patCoord = (texCoord * patternSizeInv) - (scroll * patternSizeInv);
vec2 scroll = patternScroll * (patternSizeInv / texSizeInv);
v_patCoord = (texCoord * (patternSizeInv / patternZoom)) - (scroll * patternSizeInv);
}
else {
vec2 scroll = patternScroll * (patternSizeInv / texSizeInv) * patternZoom;
v_patCoord = (texCoord * texSizeInv) - (scroll * texSizeInv);
vec2 scroll = patternScroll * (patternSizeInv / texSizeInv);
v_patCoord = (texCoord * (texSizeInv / patternZoom)) - (scroll * texSizeInv);
}
}
}

View file

@ -469,6 +469,7 @@ SpriteShader::SpriteShader()
GET_U(bushDepth);
GET_U(bushOpacity);
GET_U(pattern);
GET_U(patternBlendType);
GET_U(patternTile);
GET_U(renderPattern);
GET_U(patternSizeInv);
@ -514,6 +515,11 @@ void SpriteShader::setPattern(const TEX::ID pattern, const Vec2 &dimensions)
gl.Uniform2f(u_patternSizeInv, 1.f / dimensions.x, 1.f / dimensions.y);
}
void SpriteShader::setPatternBlendType(int blendType)
{
gl.Uniform1i(u_patternBlendType, blendType);
}
void SpriteShader::setPatternTile(bool value)
{
gl.Uniform1i(u_patternTile, value);

View file

@ -192,6 +192,7 @@ public:
void setBushDepth(float value);
void setBushOpacity(float value);
void setPattern(const TEX::ID pattern, const Vec2 &dimensions);
void setPatternBlendType(int blendType);
void setPatternTile(bool value);
void setShouldRenderPattern(bool value);
void setPatternOpacity(float value);
@ -201,7 +202,7 @@ public:
private:
GLint u_spriteMat, u_tone, u_opacity, u_color, u_bushDepth, u_bushOpacity, u_pattern, u_renderPattern,
u_patternSizeInv, u_patternTile, u_patternOpacity, u_patternScroll, u_patternZoom, u_invert;
u_patternBlendType, u_patternSizeInv, u_patternTile, u_patternOpacity, u_patternScroll, u_patternZoom, u_invert;
};
class PlaneShader : public ShaderBase

View file

@ -61,6 +61,7 @@ struct SpritePrivate
BlendType blendType;
Bitmap *pattern;
BlendType patternBlendType;
bool patternTile;
NormValue patternOpacity;
Vec2 patternScroll;
@ -337,6 +338,7 @@ DEF_ATTR_RD_SIMPLE(Sprite, Mirror, bool, p->mirrored)
DEF_ATTR_RD_SIMPLE(Sprite, BushDepth, int, p->bushDepth)
DEF_ATTR_RD_SIMPLE(Sprite, BlendType, int, p->blendType)
DEF_ATTR_RD_SIMPLE(Sprite, Pattern, Bitmap*, p->pattern)
DEF_ATTR_RD_SIMPLE(Sprite, PatternBlendType, int, p->patternBlendType)
DEF_ATTR_RD_SIMPLE(Sprite, Width, int, p->srcRect->width)
DEF_ATTR_RD_SIMPLE(Sprite, Height, int, p->srcRect->height)
DEF_ATTR_RD_SIMPLE(Sprite, WaveAmp, int, p->wave.amp)
@ -512,6 +514,25 @@ void Sprite::setPattern(Bitmap *value)
value->ensureNonMega();
}
void Sprite::setPatternBlendType(int type)
{
guardDisposed();
switch (type)
{
default :
case BlendNormal :
p->patternBlendType = BlendNormal;
return;
case BlendAddition :
p->patternBlendType = BlendAddition;
return;
case BlendSubstraction :
p->patternBlendType = BlendSubstraction;
return;
}
}
#define DEF_WAVE_SETTER(Name, name, type) \
void Sprite::setWave##Name(type value) \
{ \
@ -582,6 +603,7 @@ void Sprite::draw()
if (p->pattern && p->patternOpacity > 0) {
shader.setPattern(p->pattern->getGLTypes().tex, Vec2(p->pattern->width(), p->pattern->height()));
shader.setPatternBlendType(p->patternBlendType);
shader.setPatternTile(p->patternTile);
shader.setPatternZoom(p->patternZoom);
shader.setPatternOpacity(p->patternOpacity.norm);

View file

@ -63,6 +63,7 @@ public:
DECL_ATTR( Color, Color& )
DECL_ATTR( Tone, Tone& )
DECL_ATTR( Pattern, Bitmap* )
DECL_ATTR( PatternBlendType, int)
DECL_ATTR( PatternTile, bool )
DECL_ATTR( PatternOpacity, int )
DECL_ATTR( PatternScrollX, int )