Bump flixel-animate and add useRenderTexture to FunkinSprite as an option.
This commit is contained in:
+1
-1
Submodule assets updated: 572aa2becd...329427d5a7
@@ -59,7 +59,7 @@
|
||||
"name": "flixel-animate",
|
||||
"type": "git",
|
||||
"dir": null,
|
||||
"ref": "220463c8089444d6c9957b68919fe88e6cba495f",
|
||||
"ref": "84cd1915161eb49fba33b3f81a8c7ea3f05ae053",
|
||||
"url": "https://github.com/MaybeMaru/flixel-animate"
|
||||
},
|
||||
{
|
||||
|
||||
@@ -464,7 +464,8 @@ class CharacterDataParser
|
||||
swfMode: true,
|
||||
cacheOnLoad: false,
|
||||
filterQuality: 1,
|
||||
applyStageMatrix: false
|
||||
applyStageMatrix: false,
|
||||
useRenderTexture: false
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -274,6 +274,17 @@ typedef TextureAtlasData =
|
||||
*/
|
||||
@:optional
|
||||
var applyStageMatrix:Bool;
|
||||
|
||||
/**
|
||||
* If enabled, the sprite will render as one texture instead of rendering multiple limbs.
|
||||
* This is useful for stuff like changing alpha, and shaders that require the whole sprite.
|
||||
*
|
||||
* Only enable this if your sprite either:
|
||||
* - Changes alpha to something other than 1.0
|
||||
* - Has a shader or blend mode
|
||||
*/
|
||||
@:optional
|
||||
var useRenderTexture:Bool;
|
||||
};
|
||||
|
||||
typedef StageDataCharacter =
|
||||
|
||||
@@ -92,6 +92,17 @@ typedef AtlasSpriteSettings =
|
||||
*/
|
||||
@:optional
|
||||
var applyStageMatrix:Bool;
|
||||
|
||||
/**
|
||||
* If enabled, the sprite will render as one texture instead of rendering multiple limbs.
|
||||
* This is useful for stuff like changing alpha, and shaders that require the whole sprite.
|
||||
*
|
||||
* Only enable this if your sprite either:
|
||||
* - Changes alpha to something other than 1.0
|
||||
* - Has a shader or blend mode
|
||||
*/
|
||||
@:optional
|
||||
var useRenderTexture:Bool;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -329,7 +340,8 @@ class FunkinSprite extends FlxAnimate
|
||||
cacheKey: settings?.cacheKey ?? null,
|
||||
uniqueInCache: settings?.uniqueInCache ?? false,
|
||||
onSymbolCreate: settings?.onSymbolCreate ?? null,
|
||||
applyStageMatrix: settings?.applyStageMatrix ?? false
|
||||
applyStageMatrix: settings?.applyStageMatrix ?? false,
|
||||
useRenderTexture: settings?.useRenderTexture ?? false
|
||||
};
|
||||
|
||||
var assetLibrary:String = assetLibrary ?? "";
|
||||
@@ -351,6 +363,7 @@ class FunkinSprite extends FlxAnimate
|
||||
}
|
||||
|
||||
this.applyStageMatrix = validatedSettings.applyStageMatrix ?? false;
|
||||
this.useRenderTexture = validatedSettings.useRenderTexture ?? false;
|
||||
|
||||
frames = FlxAnimateFrames.fromAnimate(graphicKey, validatedSettings.spritemaps, validatedSettings.metadataJson, validatedSettings.cacheKey,
|
||||
validatedSettings.uniqueInCache, {
|
||||
|
||||
@@ -1,230 +0,0 @@
|
||||
package funkin.graphics.shaders;
|
||||
|
||||
import flixel.system.FlxAssets.FlxShader;
|
||||
import flixel.util.FlxColor;
|
||||
import flixel.FlxSprite;
|
||||
import flixel.math.FlxAngle;
|
||||
import flixel.graphics.frames.FlxFrame;
|
||||
import openfl.display.BitmapData;
|
||||
|
||||
/*
|
||||
A screenspace version of the DropShadowShader.. currently the only way to use this effect with
|
||||
FlxAnimate :(
|
||||
*/
|
||||
class DropShadowScreenspace extends DropShadowShader
|
||||
{
|
||||
/*
|
||||
The current zoom of the camera. Needed to figure out how much to multiply the drop shadow size.
|
||||
*/
|
||||
public var curZoom(default, set):Float;
|
||||
|
||||
function set_curZoom(val:Float):Float
|
||||
{
|
||||
curZoom = val;
|
||||
zoom.value = [val];
|
||||
return val;
|
||||
}
|
||||
|
||||
@:glFragmentSource('
|
||||
#pragma header
|
||||
|
||||
// This shader aims to mostly recreate how Adobe Animate/Flash handles drop shadows, but its main use here is for rim lighting.
|
||||
|
||||
// this shader also includes a recreation of the Animate/Flash "Adjust Color" filter,
|
||||
// which was kindly provided and written by Rozebud https://github.com/ThatRozebudDude ( thank u rozebud :) )
|
||||
// Adapted from Andrey-Postelzhuks shader found here: https://forum.unity.com/threads/hue-saturation-brightness-contrast-shader.260649/
|
||||
// Hue rotation stuff is from here: https://www.w3.org/TR/filter-effects/#feColorMatrixElement
|
||||
|
||||
// equals (frame.left, frame.top, frame.right, frame.bottom)
|
||||
uniform vec4 uFrameBounds;
|
||||
|
||||
uniform float ang;
|
||||
uniform float dist;
|
||||
uniform float str;
|
||||
uniform float thr;
|
||||
|
||||
// need to account for rotated frames... oops
|
||||
uniform float angOffset;
|
||||
|
||||
uniform sampler2D altMask;
|
||||
uniform bool useMask;
|
||||
uniform float thr2;
|
||||
|
||||
uniform vec3 dropColor;
|
||||
|
||||
uniform float hue;
|
||||
uniform float saturation;
|
||||
uniform float brightness;
|
||||
uniform float contrast;
|
||||
|
||||
uniform float zoom;
|
||||
|
||||
uniform float AA_STAGES;
|
||||
|
||||
const vec3 grayscaleValues = vec3(0.3098039215686275, 0.607843137254902, 0.0823529411764706);
|
||||
const float e = 2.718281828459045;
|
||||
|
||||
vec3 applyHueRotate(vec3 aColor, float aHue){
|
||||
float angle = radians(aHue);
|
||||
|
||||
mat3 m1 = mat3(0.213, 0.213, 0.213, 0.715, 0.715, 0.715, 0.072, 0.072, 0.072);
|
||||
mat3 m2 = mat3(0.787, -0.213, -0.213, -0.715, 0.285, -0.715, -0.072, -0.072, 0.928);
|
||||
mat3 m3 = mat3(-0.213, 0.143, -0.787, -0.715, 0.140, 0.715, 0.928, -0.283, 0.072);
|
||||
mat3 m = m1 + cos(angle) * m2 + sin(angle) * m3;
|
||||
|
||||
return m * aColor;
|
||||
}
|
||||
|
||||
vec3 applySaturation(vec3 aColor, float value){
|
||||
if(value > 0.0){ value = value * 3.0; }
|
||||
value = (1.0 + (value / 100.0));
|
||||
vec3 grayscale = vec3(dot(aColor, grayscaleValues));
|
||||
return clamp(mix(grayscale, aColor, value), 0.0, 1.0);
|
||||
}
|
||||
|
||||
vec3 applyContrast(vec3 aColor, float value){
|
||||
value = (1.0 + (value / 100.0));
|
||||
if(value > 1.0){
|
||||
value = (((0.00852259 * pow(e, 4.76454 * (value - 1.0))) * 1.01) - 0.0086078159) * 10.0; //Just roll with it...
|
||||
value += 1.0;
|
||||
}
|
||||
return clamp((aColor - 0.25) * value + 0.25, 0.0, 1.0);
|
||||
}
|
||||
|
||||
vec3 applyHSBCEffect(vec3 color){
|
||||
|
||||
//Brightness
|
||||
color = color + ((brightness) / 255.0);
|
||||
|
||||
//Hue
|
||||
color = applyHueRotate(color, hue);
|
||||
|
||||
//Contrast
|
||||
color = applyContrast(color, contrast);
|
||||
|
||||
//Saturation
|
||||
color = applySaturation(color, saturation);
|
||||
|
||||
return color;
|
||||
}
|
||||
|
||||
vec2 hash22(vec2 p) {
|
||||
vec3 p3 = fract(vec3(p.xyx) * vec3(.1031, .1030, .0973));
|
||||
p3 += dot(p3, p3.yzx + 33.33);
|
||||
return fract((p3.xx + p3.yz) * p3.zy);
|
||||
}
|
||||
|
||||
float intensityPass(vec2 fragCoord, float curThreshold, bool useMask) {
|
||||
vec4 col = texture2D(bitmap, fragCoord);
|
||||
|
||||
float maskIntensity = 0.0;
|
||||
if(useMask == true){
|
||||
maskIntensity = mix(0.0, 1.0, texture2D(altMask, fragCoord).b);
|
||||
}
|
||||
|
||||
if(col.a == 0.0){
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
float intensity = dot(col.rgb, vec3(0.3098, 0.6078, 0.0823));
|
||||
|
||||
intensity = maskIntensity > 0.0 ? float(intensity > thr2) : float(intensity > thr);
|
||||
|
||||
return intensity;
|
||||
}
|
||||
|
||||
// essentially just stole this from the AngleMask shader but repurposed it to smooth
|
||||
// the threshold because without any sort of smoothing it produces horrible edges
|
||||
float antialias(vec2 fragCoord, float curThreshold, bool useMask) {
|
||||
if (AA_STAGES == 0.0) {
|
||||
return intensityPass(fragCoord, curThreshold, useMask);
|
||||
}
|
||||
|
||||
// In GLSL 100, we need to use constant loop bounds
|
||||
// Well assume a reasonable maximum for AA_STAGES and use a fixed loop
|
||||
// The actual number of iterations will be controlled by a condition inside
|
||||
const int MAX_AA = 8; // This should be large enough for most uses
|
||||
|
||||
float AA_TOTAL_PASSES = AA_STAGES * AA_STAGES + 1.0;
|
||||
const float AA_JITTER = 0.5;
|
||||
|
||||
// Run the shader multiple times with a random subpixel offset each time and average the results
|
||||
float color = intensityPass(fragCoord, curThreshold, useMask);
|
||||
for (int i = 0; i < MAX_AA * MAX_AA; i++) {
|
||||
// Calculate x and y from i
|
||||
int x = i / MAX_AA;
|
||||
int y = i - (MAX_AA * int(i/MAX_AA)); // poor mans modulus
|
||||
|
||||
// Skip iterations beyond our desired AA_STAGES
|
||||
if (float(x) >= AA_STAGES || float(y) >= AA_STAGES) {
|
||||
continue;
|
||||
}
|
||||
|
||||
vec2 offset = AA_JITTER * (2.0 * hash22(vec2(float(x), float(y))) - 1.0) / openfl_TextureSize.xy;
|
||||
color += intensityPass(fragCoord + offset, curThreshold, useMask);
|
||||
}
|
||||
|
||||
return color / AA_TOTAL_PASSES;
|
||||
}
|
||||
|
||||
vec3 createDropShadow(vec3 col, float curThreshold, bool useMask) {
|
||||
|
||||
// essentially a mask so that areas under the threshold dont show the rimlight (mainly the outlines)
|
||||
float intensity = antialias(openfl_TextureCoordv, curThreshold, useMask);
|
||||
|
||||
// the distance the dropshadow moves needs to be correctly scaled based on the texture size
|
||||
vec2 imageRatio = vec2(1.0/openfl_TextureSize.x, 1.0/openfl_TextureSize.y);
|
||||
|
||||
// check the pixel in the direction and distance specified
|
||||
vec2 checkedPixel = vec2(openfl_TextureCoordv.x + ((dist*zoom) * cos(ang + angOffset) * imageRatio.x), openfl_TextureCoordv.y - ((dist*zoom) * sin(ang + angOffset) * imageRatio.y));
|
||||
|
||||
// multiplier for the intensity of the drop shadow
|
||||
float dropShadowAmount = 0.0;
|
||||
|
||||
dropShadowAmount = texture2D(bitmap, checkedPixel).a;
|
||||
|
||||
// add the dropshadow color based on the amount, strength, and intensity
|
||||
col.rgb += dropColor.rgb * ((1.0 - (dropShadowAmount * str))*intensity);
|
||||
|
||||
return col;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 col = texture2D(bitmap, openfl_TextureCoordv);
|
||||
|
||||
vec3 unpremultipliedColor = col.a > 0.0 ? col.rgb / col.a : col.rgb;
|
||||
|
||||
vec3 outColor = applyHSBCEffect(unpremultipliedColor);
|
||||
|
||||
outColor = createDropShadow(outColor, thr, useMask);
|
||||
|
||||
gl_FragColor = vec4(outColor.rgb * col.a, col.a);
|
||||
}
|
||||
|
||||
')
|
||||
override public function new()
|
||||
{
|
||||
super();
|
||||
|
||||
angle = 90;
|
||||
strength = 1;
|
||||
distance = 15;
|
||||
threshold = 0.1;
|
||||
|
||||
baseHue = 0;
|
||||
baseSaturation = 0;
|
||||
baseBrightness = 0;
|
||||
baseContrast = 0;
|
||||
|
||||
useAltMask = false;
|
||||
|
||||
color = 0xFFDFEF3C;
|
||||
|
||||
antialiasAmt = 2;
|
||||
|
||||
curZoom = 1;
|
||||
|
||||
angOffset.value = [0];
|
||||
}
|
||||
}
|
||||
@@ -232,6 +232,12 @@ class DropShadowShader extends FlxShader
|
||||
angOffset.value = [frame.angle * FlxAngle.TO_RAD];
|
||||
}
|
||||
|
||||
public function updateFrameInfoSimple(width:Float, height:Float, angle:Float):Void
|
||||
{
|
||||
uFrameBounds.value = [0, 0, width, height];
|
||||
angOffset.value = [angle * FlxAngle.TO_RAD];
|
||||
}
|
||||
|
||||
function set_altMaskImage(_bitmapData:BitmapData):BitmapData
|
||||
{
|
||||
altMask.input = _bitmapData;
|
||||
|
||||
@@ -536,6 +536,10 @@ class DebugBoundingState extends FlxState
|
||||
onionSkinChar.y = swagChar.y;
|
||||
onionSkinChar.debug = true;
|
||||
|
||||
// Enable `useRenderTexture` for texture atlas sprites so the alpha renders properly for them.
|
||||
// This doesn't do anything for sparrows, don't worry!
|
||||
onionSkinChar.useRenderTexture = true;
|
||||
|
||||
offsetView.add(onionSkinChar);
|
||||
offsetView.add(swagChar);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user