[unity] Fixed enabling CanvasGroup Compatible at Spine-SkeletonGraphic-TintBlack shader causing Additive blend mode not to work but instead hide the attachment completely. Now providing a Canvas Group Tint Black parameter a SkeletonGraphic Inspector in the Advanced section. Closes #1756.

This commit is contained in:
Harald Csaszar 2020-09-11 20:38:14 +02:00
parent 4cf792f51d
commit d43b7b0a9f
3 changed files with 33 additions and 11 deletions

View File

@ -239,6 +239,7 @@
* Added a new `Spine/Outline/OutlineOnly-ZWrite` shader to provide correct outline-only rendering. Note: the shader requires two render passes and is therefore not compatible with URP. The `Spine Examples/Other Examples/Outline Shaders` example scene has been updated to demonstrate the new shader.
* Added `OnMeshAndMaterialsUpdated` callback event to `SkeletonRenderSeparator` and `SkeletonPartsRenderer`. It is issued at the end of `LateUpdate`, before rendering.
* Added `Root Motion Scale X/Y` parameters to `SkeletonRootMotionBase` subclasses (`SkeletonRootMotion` and `SkeletonMecanimRootMotion`). Also providing `AdjustRootMotionToDistance()` and other methods to allow for easy delta compensation. Delta compensation can be used to e.g. stretch a jump to a given distance. Root motion can be adjusted at the start of an animation or every frame via `skeletonRootMotion.AdjustRootMotionToDistance(targetPosition - transform.position, trackIndex);`.
* Now providing a `Canvas Group Tint Black` parameter a `SkeletonGraphic` Inspector in the `Advanced` section. Enable when using Additive blend mode at SkeletonGraphic under a CanvasGroup. Be sure to also have the parameter `CanvasGroup Compatible` enabled at the shader.
* **Changes of default values**
* `SkeletonMecanim`'s `Layer Mix Mode` now defaults to `MixMode.MixNext` instead of `MixMode.MixAlways`.

View File

@ -68,6 +68,9 @@ namespace Spine.Unity {
[Header("Vertex Data")]
public bool pmaVertexColors;
public bool tintBlack;
[Tooltip("Enable when using Additive blend mode at SkeletonGraphic under a CanvasGroup. " +
"When enabled, Additive alpha value is stored at uv2.g instead of color.a to capture CanvasGroup modifying color.a.")]
public bool canvasGroupTintBlack;
public bool calculateTangents;
public bool addNormals;
public bool immutableTriangles;
@ -493,6 +496,7 @@ namespace Spine.Unity {
#else
bool useClipping = settings.useClipping;
#endif
bool canvasGroupTintBlack = settings.tintBlack && settings.canvasGroupTintBlack;
if (useClipping) {
if (instruction.preActiveClippingSlotSource >= 0) {
@ -556,12 +560,18 @@ namespace Spine.Unity {
}
}
float tintBlackAlpha = 1.0f;
if (pmaVertexColors) {
color.a = (byte)(skeletonA * slot.a * c.a * 255);
color.r = (byte)(skeletonR * slot.r * c.r * color.a);
color.g = (byte)(skeletonG * slot.g * c.g * color.a);
color.b = (byte)(skeletonB * slot.b * c.b * color.a);
if (slot.data.blendMode == BlendMode.Additive) color.a = 0;
if (slot.data.blendMode == BlendMode.Additive) {
if (canvasGroupTintBlack)
tintBlackAlpha = 0;
else
color.a = 0;
}
} else {
color.a = (byte)(skeletonA * slot.a * c.a * 255);
color.r = (byte)(skeletonR * slot.r * c.r * 255);
@ -590,7 +600,7 @@ namespace Spine.Unity {
g2 *= alpha;
b2 *= alpha;
}
AddAttachmentTintBlack(r2, g2, b2, attachmentVertexCount);
AddAttachmentTintBlack(r2, g2, b2, tintBlackAlpha, attachmentVertexCount);
}
//AddAttachment(workingVerts, uvs, color, attachmentTriangleIndices, attachmentVertexCount, attachmentIndexCount, ref meshBoundsMin, ref meshBoundsMax, z);
@ -694,6 +704,7 @@ namespace Spine.Unity {
// Use this faster method when no clipping is involved.
public void BuildMeshWithArrays (SkeletonRendererInstruction instruction, bool updateTriangles) {
var settings = this.settings;
bool canvasGroupTintBlack = settings.tintBlack && settings.canvasGroupTintBlack;
int totalVertexCount = instruction.rawVertexCount;
// Add data to vertex buffers
@ -758,6 +769,7 @@ namespace Spine.Unity {
rg.x = slot.r2; //r
rg.y = slot.g2; //g
b2.x = slot.b2; //b
b2.y = 1.0f;
var regionAttachment = attachment as RegionAttachment;
if (regionAttachment != null) {
@ -766,6 +778,7 @@ namespace Spine.Unity {
rg.x *= alpha;
rg.y *= alpha;
b2.x *= alpha;
b2.y = slot.data.blendMode == BlendMode.Additive ? 0 : alpha;
}
uv2i[vi] = rg; uv2i[vi + 1] = rg; uv2i[vi + 2] = rg; uv2i[vi + 3] = rg;
uv3i[vi] = b2; uv3i[vi + 1] = b2; uv3i[vi + 2] = b2; uv3i[vi + 3] = b2;
@ -778,6 +791,7 @@ namespace Spine.Unity {
rg.x *= alpha;
rg.y *= alpha;
b2.x *= alpha;
b2.y = slot.data.blendMode == BlendMode.Additive ? 0 : alpha;
}
int meshVertexCount = meshAttachment.worldVerticesLength;
for (int iii = 0; iii < meshVertexCount; iii += 2) {
@ -814,7 +828,7 @@ namespace Spine.Unity {
color.r = (byte)(r * slot.r * regionAttachment.r * color.a);
color.g = (byte)(g * slot.g * regionAttachment.g * color.a);
color.b = (byte)(b * slot.b * regionAttachment.b * color.a);
if (slot.data.blendMode == BlendMode.Additive) color.a = 0;
if (slot.data.blendMode == BlendMode.Additive && !canvasGroupTintBlack) color.a = 0;
} else {
color.a = (byte)(a * slot.a * regionAttachment.a * 255);
color.r = (byte)(r * slot.r * regionAttachment.r * 255);
@ -861,7 +875,7 @@ namespace Spine.Unity {
color.r = (byte)(r * slot.r * meshAttachment.r * color.a);
color.g = (byte)(g * slot.g * meshAttachment.g * color.a);
color.b = (byte)(b * slot.b * meshAttachment.b * color.a);
if (slot.data.blendMode == BlendMode.Additive) color.a = 0;
if (slot.data.blendMode == BlendMode.Additive && !canvasGroupTintBlack) color.a = 0;
} else {
color.a = (byte)(a * slot.a * meshAttachment.a * 255);
color.r = (byte)(r * slot.r * meshAttachment.r * 255);
@ -985,9 +999,9 @@ namespace Spine.Unity {
meshBoundsThickness *= scale;
}
void AddAttachmentTintBlack (float r2, float g2, float b2, int vertexCount) {
void AddAttachmentTintBlack (float r2, float g2, float b2, float a, int vertexCount) {
var rg = new Vector2(r2, g2);
var bo = new Vector2(b2, 1f);
var bo = new Vector2(b2, a);
int ovc = vertexBuffer.Count;
int newVertexCount = ovc + vertexCount;

View File

@ -89,7 +89,7 @@ Shader "Spine/SkeletonGraphic Tint Black"
float4 vertex : SV_POSITION;
fixed4 color : COLOR;
half2 texcoord : TEXCOORD0;
float3 darkColor : TEXCOORD1;
float4 darkColor : TEXCOORD1;
float4 worldPosition : TEXCOORD2;
UNITY_VERTEX_OUTPUT_STEREO
};
@ -110,7 +110,7 @@ Shader "Spine/SkeletonGraphic Tint Black"
OUT.texcoord = IN.texcoord;
OUT.color = IN.color * _Color;
OUT.darkColor = float3(IN.uv1.r, IN.uv1.g, IN.uv2.r);
OUT.darkColor = float4(IN.uv1.r, IN.uv1.g, IN.uv2.r, IN.uv2.g);
return OUT;
}
@ -125,10 +125,17 @@ Shader "Spine/SkeletonGraphic Tint Black"
clip(texColor.a - 0.001);
#endif
float4 fragColor = fragTintedColor(texColor, _Black.rgb + IN.darkColor, IN.color, _Black.a);
float4 vertexColor = IN.color;
#ifdef _CANVAS_GROUP_COMPATIBLE
// CanvasGroup alpha sets vertex color alpha, but does not premultiply it to rgb components.
fragColor.rgb *= IN.color.a;
// CanvasGroup alpha multiplies existing vertex color alpha, but
// does not premultiply it to rgb components. This causes problems
// with additive blending (alpha = 0), which is why we store the
// alpha value in uv2.g (darkColor.a).
vertexColor.a = IN.darkColor.a;
#endif
float4 fragColor = fragTintedColor(texColor, _Black.rgb + IN.darkColor, vertexColor, _Black.a);
#ifdef _CANVAS_GROUP_COMPATIBLE
fragColor.rgba *= IN.color.a;
#endif
return fragColor;
}