Pārlūkot izejas kodu

[unity] Made all shaders (including URP and LWRP shaders) compatible with Linear Color Space. Closes #1301.

Harald Csaszar 4 gadi atpakaļ
vecāks
revīzija
aa46f411ab
43 mainītis faili ar 240 papildinājumiem un 100 dzēšanām
  1. 3 0
      CHANGELOG.md
  2. 7 2
      spine-unity/Assets/Spine/Editor/spine-unity/Editor/Shaders/SpineSpriteShaderGUI.cs
  3. 1 1
      spine-unity/Assets/Spine/Editor/spine-unity/Editor/Utility/AssetUtility.cs
  4. 2 1
      spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/BlendModes/Spine-Skeleton-PMA-Additive.shader
  5. 2 1
      spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/BlendModes/Spine-Skeleton-PMA-Multiply.shader
  6. 2 1
      spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/BlendModes/Spine-Skeleton-PMA-Screen.shader
  7. 42 0
      spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/CGIncludes/Spine-Common.cginc
  8. 10 0
      spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/CGIncludes/Spine-Common.cginc.meta
  9. 2 1
      spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/CGIncludes/Spine-Skeleton-Lit-Common.cginc
  10. 28 18
      spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/SkeletonGraphic/Spine-SkeletonGraphic-TintBlack.shader
  11. 13 6
      spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/SkeletonGraphic/Spine-SkeletonGraphic.shader
  12. 2 1
      spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Skeleton-Fill.shader
  13. 2 1
      spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Skeleton-Tint.shader
  14. 4 3
      spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Skeleton-TintBlack.shader
  15. 2 1
      spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Skeleton.shader
  16. 5 5
      spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Special-Skeleton-Grayscale.shader
  17. 31 10
      spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/CGIncludes/ShaderShared.cginc
  18. 2 2
      spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/SpritesPixelLit.shader
  19. 1 1
      spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/SpritesUnlit.shader
  20. 1 1
      spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/SpritesVertexLit.shader
  21. 20 10
      spine-unity/Assets/Spine/Runtime/spine-unity/Utility/MaterialChecks.cs
  22. 2 1
      spine-unity/Modules/com.esotericsoftware.spine.lwrp-shaders/Shaders/CGIncludes/Spine-Skeleton-ForwardPass-LW.hlsl
  23. 2 1
      spine-unity/Modules/com.esotericsoftware.spine.lwrp-shaders/Shaders/CGIncludes/Spine-SkeletonLit-ForwardPass-LW.hlsl
  24. 2 2
      spine-unity/Modules/com.esotericsoftware.spine.lwrp-shaders/Shaders/CGIncludes/Spine-Sprite-ForwardPass-LW.hlsl
  25. 2 0
      spine-unity/Modules/com.esotericsoftware.spine.lwrp-shaders/Shaders/CGIncludes/SpineCoreShaders/Spine-Common.cginc
  26. 1 1
      spine-unity/Modules/com.esotericsoftware.spine.lwrp-shaders/Shaders/Spine-Sprite-LW.shader
  27. 4 4
      spine-unity/Modules/com.esotericsoftware.spine.lwrp-shaders/package-2019.1.json
  28. 4 4
      spine-unity/Modules/com.esotericsoftware.spine.lwrp-shaders/package-2019.2.json
  29. 4 4
      spine-unity/Modules/com.esotericsoftware.spine.lwrp-shaders/package.json
  30. 3 2
      spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/Examples/2D/Spine Skeletons/StretchymanURP/stretchyman_Material.mat
  31. 2 2
      spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/Examples/2D/URP 2D Shaders.unity
  32. 3 2
      spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/Examples/3D/Spine Skeletons/StretchymanURP/stretchyman_Material.mat
  33. 1 1
      spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/Examples/Outline Shaders URP.unity
  34. 1 1
      spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/Shaders/2D/Include/Spine-Sprite-StandardPass-URP-2D.hlsl
  35. 4 1
      spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/Shaders/2D/Spine-SkeletonLit-URP-2D.shader
  36. 1 1
      spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/Shaders/2D/Spine-Sprite-URP-2D.shader
  37. 2 1
      spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/Shaders/Include/Spine-Skeleton-ForwardPass-URP.hlsl
  38. 2 1
      spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/Shaders/Include/Spine-SkeletonLit-ForwardPass-URP.hlsl
  39. 3 2
      spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/Shaders/Include/Spine-Sprite-ForwardPass-URP.hlsl
  40. 2 0
      spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/Shaders/Include/SpineCoreShaders/Spine-Common.cginc
  41. 10 0
      spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/Shaders/Include/SpineCoreShaders/Spine-Common.cginc.meta
  42. 1 1
      spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/Shaders/Spine-Sprite-URP.shader
  43. 2 2
      spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/package.json

+ 3 - 0
CHANGELOG.md

@@ -52,6 +52,7 @@
   * Reverted changes: `BoneFollower` property `followLocalScale` has intermediately been renamed to `followScale` but was renamed back to `followLocalScale`. Serialized values (scenes and prefabs) will automatically be upgraded, only code accessing `followScale` needs to be adapted.
   * Corrected blending behaviour of all `Sprite` shaders in `Premultiply Alpha` blend mode (including URP and LWRP packages). Previously vertex color alpha was premultiplied again, even though `Premultiply Alpha` blend mode assumes PMA texture and PMA vertex color input. Slot-alpha blending will thus be correctly lighter after upgrading to 4.0. If you have compensated this problem by disabling `Advanced - PMA Vertex Colors` you can now re-enable this parameter, also allowing for rendering Additive slots in a single pass.
   * Corrected all `Outline` shaders outline thickness when `Advanced - Sample 8 Neighbourhood` is disabled (thus using `4 Neighbourhood`). Previously weighting was incorrectly thick (4x as thick) compared to 8 neighbourhood, now it is more consistent. This might require adjustment of all your outline materials where `Sample 8 Neighbourhood` is disabled to restore the previous outline thickness, by adjusting the `Outline Threshold` parameter through adding a `/4` to make the threshold 4 times smaller.
+  * **Linear color space:** Previously Slot colors were not displayed the same in Unity as in the Spine Editor. This is now fixed at all shaders, including URP and LWRP shaders. See section *Additions* below for more details. If you have tweaked Slot colors to look correct in `Linear` color space in Unity but incorrect in Spine, you might want to adjust the tweaked colors. Slot colors displayed in Unity should now match colors displayed in the Spine Editor when configured to display as `Linear` color space in the Spine Editor Settings.
 
 * **Additions**
   * Additional **Fix Draw Order** parameter at SkeletonRenderer, defaults to `disabled` (previous behaviour).
@@ -89,6 +90,8 @@
   * `SkeletonGraphic` now fully supports [`SkeletonUtility`](http://esotericsoftware.com/spine-unity#SkeletonUtility) for generating a hierarchy of [`SkeletonUtilityBones`](http://esotericsoftware.com/spine-unity#SkeletonUtilityBone) in both modes `Follow` and `Override`. This also enables creating hinge chain physics rigs and using `SkeletonUtilityConstraints` such as `SkeletonUtilityGroundConstraint` and `SkeletonUtilityEyeConstraint` on `SkeletonGraphic`.
   * Added **native support for slot blend modes** `Additive`, `Multiply` and `Screen` with automatic assignment at newly imported skeleton assets. `BlendModeMaterialAssets` are now obsolete and replaced by the native properties at `SkeletonDataAsset`. The `SkeletonDataAsset` Inspector provides a new `Blend Modes - Upgrade` button to upgrade an obsolete `BlendModeMaterialAsset` to the native blend modes properties. This upgrade will be performed automatically on imported and re-imported assets.
   * `BoneFollower` and `BoneFollowerGraphic` components now provide better support for following bones when the skeleton's Transform is not the parent of the follower's Transform. Previously e.g. rotating a common parent Transform did not lead to the desired result, as well as negatively scaling a skeleton's Transform when it is not a parent of the follower's Transform.
+  * **Linear color space:** Previously Slot colors were not displayed the same in Unity as in the Spine Editor (when configured to display as `Linear` color space in Spine Editor Settings). This is now fixed at all shaders, including URP and LWRP shaders.
+  * All Spine shaders (also including URP and LWRP shaders) now support `PMA Vertex Colors` in combination with `Linear` color space. Thus when using Spine shaders, you should always enable `PMA Vertex Colors` at the `SkeletonRenderer` component. This allows using single pass `Additive` Slots rendering. Note that textures shall still be exported as `Straight alpha` when using `Linear` color space, so combine `PMA Vertex Colors` with `Straight Texture`. All `Sprite` shaders now provide an additional blend mode for this, named `PMA Vertex, Straight Texture` which shall be the preferred Sprite shader blend mode in `Linear` color space.
 
 * **Changes of default values**
 

+ 7 - 2
spine-unity/Assets/Spine/Editor/spine-unity/Editor/Shaders/SpineSpriteShaderGUI.cs

@@ -51,6 +51,7 @@ public class SpineSpriteShaderGUI : SpineShaderWithOutlineGUI {
 
 	private enum eBlendMode {
 		PreMultipliedAlpha,
+		PreMultipliedVertexAlpha,
 		StandardAlpha,
 		Opaque,
 		Additive,
@@ -159,7 +160,8 @@ public class SpineSpriteShaderGUI : SpineShaderWithOutlineGUI {
 	};
 	static GUIContent _blendModeText = new GUIContent("Blend Mode", "Blend Mode");
 	static GUIContent[] _blendModeOptions = {
-		new GUIContent("Pre-Multiplied Alpha"),
+		new GUIContent("PMA Vertex, PMA Texture"),
+		new GUIContent("PMA Vertex, Straight Texture"),
 		new GUIContent("Standard Alpha"),
 		new GUIContent("Opaque"),
 		new GUIContent("Additive"),
@@ -895,7 +897,7 @@ public class SpineSpriteShaderGUI : SpineShaderWithOutlineGUI {
 		//Disable emission by default (is set on by default in standard shader)
 		SetKeyword(material, "_EMISSION", false);
 		//Start with preMultiply alpha by default
-		SetBlendMode(material, eBlendMode.PreMultipliedAlpha);
+		SetBlendMode(material, eBlendMode.PreMultipliedVertexAlpha);
 		SetDiffuseRampMode(material, eDiffuseRampMode.DefaultRampMode);
 		//Start with mesh normals by default
 		SetNormalsMode(material, eNormalsMode.MeshNormals, false);
@@ -1052,6 +1054,8 @@ public class SpineSpriteShaderGUI : SpineShaderWithOutlineGUI {
 			return eBlendMode.StandardAlpha;
 		if (material.IsKeywordEnabled("_ALPHAPREMULTIPLY_ON"))
 			return eBlendMode.PreMultipliedAlpha;
+		if (material.IsKeywordEnabled("_ALPHAPREMULTIPLY_VERTEX_ONLY"))
+			return eBlendMode.PreMultipliedVertexAlpha;
 		if (material.IsKeywordEnabled("_MULTIPLYBLEND"))
 			return eBlendMode.Multiply;
 		if (material.IsKeywordEnabled("_MULTIPLYBLEND_X2"))
@@ -1067,6 +1071,7 @@ public class SpineSpriteShaderGUI : SpineShaderWithOutlineGUI {
 	static void SetBlendMode (Material material, eBlendMode blendMode) {
 		SetKeyword(material, "_ALPHABLEND_ON", blendMode == eBlendMode.StandardAlpha);
 		SetKeyword(material, "_ALPHAPREMULTIPLY_ON", blendMode == eBlendMode.PreMultipliedAlpha);
+		SetKeyword(material, "_ALPHAPREMULTIPLY_VERTEX_ONLY", blendMode == eBlendMode.PreMultipliedVertexAlpha);
 		SetKeyword(material, "_MULTIPLYBLEND", blendMode == eBlendMode.Multiply);
 		SetKeyword(material, "_MULTIPLYBLEND_X2", blendMode == eBlendMode.Multiplyx2);
 		SetKeyword(material, "_ADDITIVEBLEND", blendMode == eBlendMode.Additive);

+ 1 - 1
spine-unity/Assets/Spine/Editor/spine-unity/Editor/Utility/AssetUtility.cs

@@ -846,7 +846,7 @@ namespace Spine.Unity.Editor {
 			bool isUsingPMAWorkflow = string.IsNullOrEmpty(referenceTextureSettings) ||
 				(!referenceTextureSettings.ToLower().Contains("straight") && referenceTextureSettings.ToLower().Contains("pma"));
 
-			MaterialChecks.EnablePMAAtMaterial(material, isUsingPMAWorkflow);
+			MaterialChecks.EnablePMATextureAtMaterial(material, isUsingPMAWorkflow);
 		}
 #endregion
 

+ 2 - 1
spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/BlendModes/Spine-Skeleton-PMA-Additive.shader

@@ -48,6 +48,7 @@ Shader "Spine/Blend Modes/Skeleton PMA Additive" {
 			#pragma vertex vert
 			#pragma fragment frag
 			#include "UnityCG.cginc"
+			#include "../CGIncludes/Spine-Common.cginc"
 			uniform sampler2D _MainTex;
 			uniform float4 _Color;
 
@@ -67,7 +68,7 @@ Shader "Spine/Blend Modes/Skeleton PMA Additive" {
 				VertexOutput o;
 				o.pos = UnityObjectToClipPos(v.vertex);
 				o.uv = v.uv;
-				o.vertexColor = v.vertexColor * float4(_Color.rgb * _Color.a, _Color.a); // Combine a PMA version of _Color with vertexColor.
+				o.vertexColor = PMAGammaToTargetSpace(v.vertexColor) * float4(_Color.rgb * _Color.a, _Color.a); // Combine a PMA version of _Color with vertexColor.
 				return o;
 			}
 

+ 2 - 1
spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/BlendModes/Spine-Skeleton-PMA-Multiply.shader

@@ -48,6 +48,7 @@ Shader "Spine/Blend Modes/Skeleton PMA Multiply" {
 			#pragma vertex vert
 			#pragma fragment frag
 			#include "UnityCG.cginc"
+			#include "../CGIncludes/Spine-Common.cginc"
 			uniform sampler2D _MainTex;
 			uniform float4 _Color;
 
@@ -67,7 +68,7 @@ Shader "Spine/Blend Modes/Skeleton PMA Multiply" {
 				VertexOutput o;
 				o.pos = UnityObjectToClipPos(v.vertex);
 				o.uv = v.uv;
-				o.vertexColor = v.vertexColor * float4(_Color.rgb * _Color.a, _Color.a); // Combine a PMA version of _Color with vertexColor.
+				o.vertexColor = PMAGammaToTargetSpace(v.vertexColor) * float4(_Color.rgb * _Color.a, _Color.a); // Combine a PMA version of _Color with vertexColor.
 				return o;
 			}
 

+ 2 - 1
spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/BlendModes/Spine-Skeleton-PMA-Screen.shader

@@ -48,6 +48,7 @@ Shader "Spine/Blend Modes/Skeleton PMA Screen" {
 			#pragma vertex vert
 			#pragma fragment frag
 			#include "UnityCG.cginc"
+			#include "../CGIncludes/Spine-Common.cginc"
 			uniform sampler2D _MainTex;
 			uniform float4 _Color;
 
@@ -67,7 +68,7 @@ Shader "Spine/Blend Modes/Skeleton PMA Screen" {
 				VertexOutput o;
 				o.pos = UnityObjectToClipPos(v.vertex);
 				o.uv = v.uv;
-				o.vertexColor = v.vertexColor * float4(_Color.rgb * _Color.a, _Color.a); // Combine a PMA version of _Color with vertexColor.
+				o.vertexColor = PMAGammaToTargetSpace(v.vertexColor) * float4(_Color.rgb * _Color.a, _Color.a); // Combine a PMA version of _Color with vertexColor.
 				return o;
 			}
 

+ 42 - 0
spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/CGIncludes/Spine-Common.cginc

@@ -0,0 +1,42 @@
+#ifndef SPINE_COMMON_INCLUDED
+#define SPINE_COMMON_INCLUDED
+
+#if defined(USE_LWRP)
+#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl"
+#define GammaToLinearSpace SRGBToLinear
+#define LinearToGammaSpace LinearToSRGB
+#elif defined(USE_URP)
+#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl"
+#define GammaToLinearSpace SRGBToLinear
+#define LinearToGammaSpace LinearToSRGB
+#else
+#include "UnityCG.cginc"
+#endif
+
+inline half3 GammaToTargetSpace(half3 gammaColor) {
+#if UNITY_COLORSPACE_GAMMA
+	return gammaColor;
+#else
+	return GammaToLinearSpace(gammaColor);
+#endif
+}
+
+inline half3 TargetToGammaSpace(half3 targetColor) {
+#if UNITY_COLORSPACE_GAMMA
+	return targetColor;
+#else
+	return LinearToGammaSpace(targetColor);
+#endif
+}
+
+inline half4 PMAGammaToTargetSpace(half4 gammaPMAColor) {
+#if UNITY_COLORSPACE_GAMMA
+	return gammaPMAColor;
+#else
+	return gammaPMAColor.a == 0 ?
+		half4(GammaToLinearSpace(gammaPMAColor.rgb), gammaPMAColor.a) :
+		half4(GammaToLinearSpace(gammaPMAColor.rgb / gammaPMAColor.a) * gammaPMAColor.a, gammaPMAColor.a);
+#endif
+}
+
+#endif

+ 10 - 0
spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/CGIncludes/Spine-Common.cginc.meta

@@ -0,0 +1,10 @@
+fileFormatVersion: 2
+guid: f0c09e980440e7f4f8db4f9f146d320c
+ShaderImporter:
+  externalObjects: {}
+  defaultTextures: []
+  nonModifiableTextures: []
+  preprocessorOverride: 0
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 2 - 1
spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/CGIncludes/Spine-Skeleton-Lit-Common.cginc

@@ -2,6 +2,7 @@
 #define SKELETON_LIT_COMMON_INCLUDED
 
 #include "UnityCG.cginc"
+#include "CGIncludes/Spine-Common.cginc"
 
 // ES2.0/WebGL/3DS can not do loops with non-constant-expression iteration counts :(
 #if defined(SHADER_API_GLES)
@@ -79,7 +80,7 @@ VertexOutput vert (appdata v) {
 	UNITY_SETUP_INSTANCE_ID(v);
 	UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
 
-	half4 color = v.color;
+	half4 color = PMAGammaToTargetSpace(v.color);
 	float3 eyePos = UnityObjectToViewPos(float4(v.pos, 1)).xyz; //mul(UNITY_MATRIX_MV, float4(v.pos,1)).xyz;
 	half3 fixedNormal = half3(0,0,-1);
 	half3 eyeNormal = normalize(mul((float3x3)UNITY_MATRIX_IT_MV, fixedNormal));

+ 28 - 18
spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/SkeletonGraphic/Spine-SkeletonGraphic-TintBlack.shader

@@ -73,6 +73,7 @@ Shader "Spine/SkeletonGraphic Tint Black"
 
 			#include "UnityCG.cginc"
 			#include "UnityUI.cginc"
+			#include "../CGIncludes/Spine-Common.cginc"
 
 			#pragma multi_compile __ UNITY_UI_ALPHACLIP
 
@@ -87,16 +88,19 @@ Shader "Spine/SkeletonGraphic Tint Black"
 
 			struct VertexOutput {
 				float4 vertex   : SV_POSITION;
-				fixed4 color    : COLOR;
+				half4 color    : COLOR;
 				half2 texcoord  : TEXCOORD0;
 				float4 darkColor : TEXCOORD1;
 				float4 worldPosition : TEXCOORD2;
+			#ifdef _CANVAS_GROUP_COMPATIBLE
+				float canvasAlpha : TEXCOORD3;
+			#endif
 				UNITY_VERTEX_OUTPUT_STEREO
 			};
 
-			fixed4 _Color;
-			fixed4 _Black;
-			fixed4 _TextureSampleAdd;
+			half4 _Color;
+			half4 _Black;
+			half4 _TextureSampleAdd;
 			float4 _ClipRect;
 
 			VertexOutput vert (VertexInput IN) {
@@ -109,15 +113,31 @@ Shader "Spine/SkeletonGraphic Tint Black"
 				OUT.vertex = UnityObjectToClipPos(OUT.worldPosition);
 				OUT.texcoord = IN.texcoord;
 
-				OUT.color = IN.color;
 				OUT.darkColor = float4(IN.uv1.r, IN.uv1.g, IN.uv2.r, IN.uv2.g);
+				OUT.darkColor.rgb = GammaToTargetSpace(OUT.darkColor.rgb) + _Black.rgb;
+
+			#ifdef _CANVAS_GROUP_COMPATIBLE
+				// 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).
+				float originalAlpha = OUT.darkColor.a;
+				OUT.canvasAlpha = (originalAlpha == 0) ? IN.color.a : IN.color.a / originalAlpha;
+			#else
+				float originalAlpha = IN.color.a;
+			#endif
+				// Note: CanvasRenderer performs a GammaToTargetSpace conversion on vertex color already,
+				// however incorrectly assuming straight alpha color.
+				float4 vertexColor = PMAGammaToTargetSpace(half4(TargetToGammaSpace(IN.color.rgb), originalAlpha));
+
+				OUT.color = vertexColor * float4(_Color.rgb * _Color.a, _Color.a);
 				return OUT;
 			}
 
 			sampler2D _MainTex;
 			#include "../CGIncludes/Spine-Skeleton-Tint-Common.cginc"
 
-			fixed4 frag (VertexOutput IN) : SV_Target
+			half4 frag(VertexOutput IN) : SV_Target
 			{
 				half4 texColor = (tex2D(_MainTex, IN.texcoord) + _TextureSampleAdd);
 				texColor *= UnityGet2DClipping(IN.worldPosition.xy, _ClipRect);
@@ -125,19 +145,9 @@ Shader "Spine/SkeletonGraphic Tint Black"
 				clip(texColor.a - 0.001);
 				#endif
 
-				float4 vertexColor = IN.color * float4(_Color.rgb * _Color.a, _Color.a);
-			#ifdef _CANVAS_GROUP_COMPATIBLE
-				// 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).
-				float originalAlpha = IN.darkColor.a;
-				float canvasAlpha = (originalAlpha == 0) ? IN.color.a : IN.color.a / originalAlpha;
-				vertexColor.a = originalAlpha * _Color.a;
-			#endif
-				float4 fragColor = fragTintedColor(texColor, _Black.rgb + IN.darkColor, vertexColor, _Color.a, _Black.a);
+				float4 fragColor = fragTintedColor(texColor, IN.darkColor.rgb, IN.color, _Color.a, _Black.a);
 			#ifdef _CANVAS_GROUP_COMPATIBLE
-				fragColor.rgba *= canvasAlpha;
+				fragColor.rgba *= IN.canvasAlpha;
 			#endif
 				return fragColor;
 			}

+ 13 - 6
spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/SkeletonGraphic/Spine-SkeletonGraphic.shader

@@ -70,6 +70,7 @@ Shader "Spine/SkeletonGraphic"
 
 			#include "UnityCG.cginc"
 			#include "UnityUI.cginc"
+			#include "../CGIncludes/Spine-Common.cginc"
 
 			#pragma multi_compile __ UNITY_UI_ALPHACLIP
 
@@ -106,7 +107,18 @@ Shader "Spine/SkeletonGraphic"
 				OUT.vertex.xy += (_ScreenParams.zw-1.0) * float2(-1,1);
 				#endif
 
-				OUT.color = IN.color * float4(_Color.rgb * _Color.a, _Color.a); // Combine a PMA version of _Color with vertexColor.
+			#ifdef _CANVAS_GROUP_COMPATIBLE
+				half4 vertexColor = IN.color;
+				// CanvasGroup alpha sets vertex color alpha, but does not premultiply it to rgb components.
+				vertexColor.rgb *= vertexColor.a;
+				// Unfortunately we cannot perform the TargetToGamma and PMAGammaToTarget transformations,
+				// as these would be wrong with modified alpha.
+			#else
+				// Note: CanvasRenderer performs a GammaToTargetSpace conversion on vertex color already,
+				// however incorrectly assuming straight alpha color.
+				float4 vertexColor = PMAGammaToTargetSpace(half4(TargetToGammaSpace(IN.color.rgb), IN.color.a));
+			#endif
+				OUT.color = vertexColor * float4(_Color.rgb * _Color.a, _Color.a); // Combine a PMA version of _Color with vertexColor.
 				return OUT;
 			}
 
@@ -121,11 +133,6 @@ Shader "Spine/SkeletonGraphic"
 				#endif
 
 				half4 color = (texColor + _TextureSampleAdd) * IN.color;
-				#ifdef _CANVAS_GROUP_COMPATIBLE
-				// CanvasGroup alpha sets vertex color alpha, but does not premultiply it to rgb components.
-				color.rgb *= IN.color.a;
-				#endif
-
 				color *= UnityGet2DClipping(IN.worldPosition.xy, _ClipRect);
 
 				#ifdef UNITY_UI_ALPHACLIP

+ 2 - 1
spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Skeleton-Fill.shader

@@ -42,6 +42,7 @@ Shader "Spine/Skeleton Fill" {
 			#pragma vertex vert
 			#pragma fragment frag
 			#include "UnityCG.cginc"
+			#include "CGIncludes/Spine-Common.cginc"
 			sampler2D _MainTex;
 			float4 _FillColor;
 			float _FillPhase;
@@ -61,7 +62,7 @@ Shader "Spine/Skeleton Fill" {
 			VertexOutput vert (VertexInput v) {
 				VertexOutput o = (VertexOutput)0;
 				o.uv = v.uv;
-				o.vertexColor = v.vertexColor;
+				o.vertexColor = PMAGammaToTargetSpace(v.vertexColor);
 				o.pos = UnityObjectToClipPos(v.vertex);
 				return o;
 			}

+ 2 - 1
spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Skeleton-Tint.shader

@@ -49,6 +49,7 @@ Shader "Spine/Skeleton Tint" {
 			#pragma vertex vert
 			#pragma fragment frag
 			#include "UnityCG.cginc"
+			#include "CGIncludes/Spine-Common.cginc"
 			sampler2D _MainTex;
 			float4 _Color;
 			float4 _Black;
@@ -69,7 +70,7 @@ Shader "Spine/Skeleton Tint" {
 				VertexOutput o;
 				o.pos = UnityObjectToClipPos(v.vertex);
 				o.uv = v.uv;
-				o.vertexColor = v.vertexColor * float4(_Color.rgb * _Color.a, _Color.a); // Combine a PMA version of _Color with vertexColor.
+				o.vertexColor = PMAGammaToTargetSpace(v.vertexColor) * float4(_Color.rgb * _Color.a, _Color.a); // Combine a PMA version of _Color with vertexColor.
 				return o;
 			}
 

+ 4 - 3
spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Skeleton-TintBlack.shader

@@ -52,6 +52,7 @@ Shader "Spine/Skeleton Tint Black" {
 			#pragma vertex vert
 			#pragma fragment frag
 			#include "UnityCG.cginc"
+			#include "CGIncludes/Spine-Common.cginc"
 			sampler2D _MainTex;
 			float4 _Color;
 			float4 _Black;
@@ -75,8 +76,8 @@ Shader "Spine/Skeleton Tint Black" {
 				VertexOutput o;
 				o.pos = UnityObjectToClipPos(v.vertex); // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
 				o.uv = v.uv;
-				o.vertexColor = v.vertexColor * float4(_Color.rgb * _Color.a, _Color.a); // Combine a PMA version of _Color with vertexColor.
-				o.darkColor = float3(v.uv1.r, v.uv1.g, v.uv2.r);
+				o.vertexColor = PMAGammaToTargetSpace(v.vertexColor) * float4(_Color.rgb * _Color.a, _Color.a); // Combine a PMA version of _Color with vertexColor.
+				o.darkColor = GammaToTargetSpace(float3(v.uv1.r, v.uv1.g, v.uv2.r)) + _Black.rgb;
 				return o;
 			}
 
@@ -84,7 +85,7 @@ Shader "Spine/Skeleton Tint Black" {
 
 			float4 frag (VertexOutput i) : SV_Target {
 				float4 texColor = tex2D(_MainTex, i.uv);
-				return fragTintedColor(texColor, _Black.rgb + i.darkColor, i.vertexColor, _Color.a, _Black.a);
+				return fragTintedColor(texColor, i.darkColor, i.vertexColor, _Color.a, _Black.a);
 			}
 			ENDCG
 		}

+ 2 - 1
spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Skeleton.shader

@@ -39,6 +39,7 @@ Shader "Spine/Skeleton" {
 			#pragma vertex vert
 			#pragma fragment frag
 			#include "UnityCG.cginc"
+			#include "CGIncludes/Spine-Common.cginc"
 			sampler2D _MainTex;
 
 			struct VertexInput {
@@ -57,7 +58,7 @@ Shader "Spine/Skeleton" {
 				VertexOutput o;
 				o.pos = UnityObjectToClipPos(v.vertex);
 				o.uv = v.uv;
-				o.vertexColor = v.vertexColor;
+				o.vertexColor = PMAGammaToTargetSpace(v.vertexColor);
 				return o;
 			}
 

+ 5 - 5
spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Special-Skeleton-Grayscale.shader

@@ -42,6 +42,7 @@ Shader "Spine/Special/Skeleton Grayscale" {
 			#pragma vertex vert
 			#pragma fragment frag
 			#include "UnityCG.cginc"
+			#include "CGIncludes/Spine-Common.cginc"
 			sampler2D _MainTex;
 			float _GrayPhase;
 
@@ -60,18 +61,17 @@ Shader "Spine/Special/Skeleton Grayscale" {
 			VertexOutput vert (VertexInput v) {
 				VertexOutput o = (VertexOutput)0;
 				o.uv = v.uv;
-				o.vertexColor = v.vertexColor;
+				o.vertexColor = PMAGammaToTargetSpace(v.vertexColor);
 				o.pos = UnityObjectToClipPos(v.vertex);
 				return o;
 			}
 
 			float4 frag (VertexOutput i) : SV_Target {
 				float4 rawColor = tex2D(_MainTex,i.uv);
-				float finalAlpha = (rawColor.a * i.vertexColor.a);
-
-				#if defined(_STRAIGHT_ALPHA_INPUT)
+			#if defined(_STRAIGHT_ALPHA_INPUT)
 				rawColor.rgb *= rawColor.a;
-				#endif
+			#endif
+				float finalAlpha = (rawColor.a * i.vertexColor.a);
 
 				rawColor.rgb *= i.vertexColor.rgb;
 

+ 31 - 10
spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/CGIncludes/ShaderShared.cginc

@@ -5,10 +5,13 @@
 
 #if defined(USE_LWRP)
 #include "Packages/com.unity.render-pipelines.lightweight/ShaderLibrary/Core.hlsl"
+#include "Packages/com.esotericsoftware.spine.lwrp-shaders/Shaders/CGIncludes/SpineCoreShaders/Spine-Common.cginc"
 #elif defined(USE_URP)
 #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
+#include "Packages/com.esotericsoftware.spine.urp-shaders/Shaders/Include/SpineCoreShaders/Spine-Common.cginc"
 #else
 #include "UnityCG.cginc"
+#include "../../CGIncludes/Spine-Common.cginc"
 #endif
 
 ////////////////////////////////////////
@@ -129,14 +132,16 @@ inline half3 calculateNormalFromBumpMap(float2 texUV, half3 tangentWorld, half3
 ////////////////////////////////////////
 // Blending functions
 //
-
-inline fixed4 prepareLitPixelForOutput(fixed4 finalPixel, fixed4 color) : SV_Target
+inline fixed4 prepareLitPixelForOutput(fixed4 finalPixel, fixed textureAlpha, fixed colorAlpha) : SV_Target
 {
 #if defined(_ALPHABLEND_ON)
 	//Normal Alpha
 	finalPixel.rgb *= finalPixel.a;
+#elif defined(_ALPHAPREMULTIPLY_VERTEX_ONLY)
+	//PMA vertex, straight texture
+	finalPixel.rgb *= textureAlpha;
 #elif defined(_ALPHAPREMULTIPLY_ON)
-	//Pre multiplied alpha
+	//Pre multiplied alpha, both vertex and texture
 	// texture and vertex colors are premultiplied already
 #elif defined(_MULTIPLYBLEND)
 	//Multiply
@@ -148,7 +153,7 @@ inline fixed4 prepareLitPixelForOutput(fixed4 finalPixel, fixed4 color) : SV_Tar
 #elif defined(_ADDITIVEBLEND)
 	//Additive
 	finalPixel *= 2.0f;
-	finalPixel.rgb *= color.a;
+	finalPixel.rgb *= colorAlpha;
 #elif defined(_ADDITIVEBLEND_SOFT)
 	//Additive soft
 	finalPixel.rgb *= finalPixel.a;
@@ -162,7 +167,7 @@ inline fixed4 prepareLitPixelForOutput(fixed4 finalPixel, fixed4 color) : SV_Tar
 inline fixed4 calculateLitPixel(fixed4 texureColor, fixed4 color, fixed3 lighting) : SV_Target
 {
 	fixed4 finalPixel = texureColor * color * fixed4(lighting, 1);
-	finalPixel = prepareLitPixelForOutput(finalPixel, color);
+	finalPixel = prepareLitPixelForOutput(finalPixel, texureColor.a, color.a);
 	return finalPixel;
 }
 
@@ -180,9 +185,13 @@ inline fixed4 calculateAdditiveLitPixel(fixed4 texureColor, fixed4 color, fixed3
 	//Normal Alpha, Additive and Multiply modes
 	finalPixel.rgb = (texureColor.rgb * lighting * color.rgb) * (texureColor.a * color.a);
 	finalPixel.a = 1.0;
+#elif defined(_ALPHAPREMULTIPLY_VERTEX_ONLY)
+	//PMA vertex, straight texture
+	finalPixel.rgb = texureColor.rgb * lighting * color.rgb * texureColor.a;
+	finalPixel.a = 1.0;
 #elif defined(_ALPHAPREMULTIPLY_ON)
-	//Pre multiplied alpha
-	finalPixel.rgb = texureColor.rgb * lighting * color.rgb * color.a;
+	//Pre multiplied alpha, both vertex and texture
+	finalPixel.rgb = texureColor.rgb * lighting * color.rgb;
 	finalPixel.a = 1.0;
 #else
 	//Opaque
@@ -197,7 +206,7 @@ inline fixed4 calculateAdditiveLitPixel(fixed4 texureColor, fixed3 lighting) : S
 {
 	fixed4 finalPixel;
 
-#if defined(_ALPHABLEND_ON)	|| defined(_MULTIPLYBLEND) || defined(_MULTIPLYBLEND_X2) || defined(_ADDITIVEBLEND) || defined(_ADDITIVEBLEND_SOFT)
+#if defined(_ALPHABLEND_ON)	|| defined(_ALPHAPREMULTIPLY_VERTEX_ONLY) || defined(_MULTIPLYBLEND) || defined(_MULTIPLYBLEND_X2) || defined(_ADDITIVEBLEND) || defined(_ADDITIVEBLEND_SOFT)
 	//Normal Alpha, Additive and Multiply modes
 	finalPixel.rgb = (texureColor.rgb * lighting) * texureColor.a;
 	finalPixel.a = 1.0;
@@ -248,7 +257,13 @@ uniform fixed _Cutoff;
 	#define RETURN_UNLIT_IF_ADDITIVE_SLOT(textureColor, vertexColor) \
 	if (vertexColor.a == 0 && (vertexColor.r || vertexColor.g || vertexColor.b)) {\
 		ALPHA_CLIP(texureColor, fixed4(1, 1, 1, 1))\
-			return texureColor * vertexColor;\
+		return texureColor * vertexColor;\
+	}
+#elif defined(_ALPHAPREMULTIPLY_VERTEX_ONLY)
+	#define RETURN_UNLIT_IF_ADDITIVE_SLOT(textureColor, vertexColor) \
+	if (vertexColor.a == 0 && (vertexColor.r || vertexColor.g || vertexColor.b)) {\
+		ALPHA_CLIP(texureColor, fixed4(1, 1, 1, 1))\
+		return texureColor * texureColor.a * vertexColor;\
 	}
 #else
 	#define RETURN_UNLIT_IF_ADDITIVE_SLOT(textureColor, vertexColor)
@@ -264,7 +279,13 @@ uniform fixed4 _Color;
 
 inline fixed4 calculateVertexColor(fixed4 color)
 {
+#if defined(_ALPHAPREMULTIPLY_ON) || _ALPHAPREMULTIPLY_VERTEX_ONLY
+	return PMAGammaToTargetSpace(color) * _Color;
+#elif !defined (UNITY_COLORSPACE_GAMMA)
+	return fixed4(GammaToLinearSpace(color.rgb), color.a) * _Color;
+#else
 	return color * _Color;
+#endif
 }
 
 #if defined(_COLOR_ADJUST)
@@ -338,7 +359,7 @@ inline fixed4 applyFog(fixed4 pixel, float fogCoordOrFactorAtLWRP)
 	//In multipliedx2 mode fade to grey based on inverse luminance
 	float luminance = pixel.r * 0.3 + pixel.g * 0.59 + pixel.b * 0.11;
 	fixed4 fogColor = lerp(fixed4(0.5f,0.5f,0.5f,0.5f), fixed4(0,0,0,0), luminance);
-#elif defined(_ALPHABLEND_ON) || defined(_ALPHAPREMULTIPLY_ON)
+#elif defined(_ALPHABLEND_ON) || defined(_ALPHAPREMULTIPLY_VERTEX_ONLY) || defined(_ALPHAPREMULTIPLY_ON)
 	//In alpha blended modes blend to fog color based on pixel alpha
 	fixed4 fogColor = lerp(fixed4(0,0,0,0), unity_FogColor, pixel.a);
 #else

+ 2 - 2
spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/SpritesPixelLit.shader

@@ -78,7 +78,7 @@ Shader "Spine/Sprite/Pixel Lit"
 			CGPROGRAM
 				#pragma target 3.0
 
-				#pragma shader_feature _ _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON _ADDITIVEBLEND _ADDITIVEBLEND_SOFT _MULTIPLYBLEND _MULTIPLYBLEND_X2
+				#pragma shader_feature _ _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON _ALPHAPREMULTIPLY_VERTEX_ONLY _ADDITIVEBLEND _ADDITIVEBLEND_SOFT _MULTIPLYBLEND _MULTIPLYBLEND_X2
 				#pragma shader_feature _ _FIXED_NORMALS_VIEWSPACE _FIXED_NORMALS_VIEWSPACE_BACKFACE _FIXED_NORMALS_MODELSPACE  _FIXED_NORMALS_MODELSPACE_BACKFACE _FIXED_NORMALS_WORLDSPACE
 				#pragma shader_feature _ _SPECULAR _SPECULAR_GLOSSMAP
 				#pragma shader_feature _NORMALMAP
@@ -116,7 +116,7 @@ Shader "Spine/Sprite/Pixel Lit"
 			CGPROGRAM
 				#pragma target 3.0
 
-				#pragma shader_feature _ _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON _ADDITIVEBLEND _ADDITIVEBLEND_SOFT _MULTIPLYBLEND _MULTIPLYBLEND_X2
+				#pragma shader_feature _ _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON _ALPHAPREMULTIPLY_VERTEX_ONLY _ADDITIVEBLEND _ADDITIVEBLEND_SOFT _MULTIPLYBLEND _MULTIPLYBLEND_X2
 				#pragma shader_feature _ _FIXED_NORMALS_VIEWSPACE _FIXED_NORMALS_VIEWSPACE_BACKFACE _FIXED_NORMALS_MODELSPACE  _FIXED_NORMALS_MODELSPACE_BACKFACE _FIXED_NORMALS_WORLDSPACE
 				#pragma shader_feature _ _SPECULAR _SPECULAR_GLOSSMAP
 				#pragma shader_feature _NORMALMAP

+ 1 - 1
spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/SpritesUnlit.shader

@@ -60,7 +60,7 @@ Shader "Spine/Sprite/Unlit"
 			Lighting Off
 
 			CGPROGRAM
-				#pragma shader_feature _ _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON _ADDITIVEBLEND _ADDITIVEBLEND_SOFT _MULTIPLYBLEND _MULTIPLYBLEND_X2
+				#pragma shader_feature _ _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON _ALPHAPREMULTIPLY_VERTEX_ONLY _ADDITIVEBLEND _ADDITIVEBLEND_SOFT _MULTIPLYBLEND _MULTIPLYBLEND_X2
 				#pragma shader_feature _ALPHA_CLIP
 				#pragma shader_feature _TEXTURE_BLEND
 				#pragma shader_feature _COLOR_ADJUST

+ 1 - 1
spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/SpritesVertexLit.shader

@@ -79,7 +79,7 @@ Shader "Spine/Sprite/Vertex Lit"
 			CGPROGRAM
 				#pragma target 3.0
 
-				#pragma shader_feature _ _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON _ADDITIVEBLEND _ADDITIVEBLEND_SOFT _MULTIPLYBLEND _MULTIPLYBLEND_X2
+				#pragma shader_feature _ _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON _ALPHAPREMULTIPLY_VERTEX_ONLY _ADDITIVEBLEND _ADDITIVEBLEND_SOFT _MULTIPLYBLEND _MULTIPLYBLEND_X2
 				#pragma shader_feature _ _FIXED_NORMALS_VIEWSPACE _FIXED_NORMALS_VIEWSPACE_BACKFACE _FIXED_NORMALS_MODELSPACE  _FIXED_NORMALS_MODELSPACE_BACKFACE _FIXED_NORMALS_WORLDSPACE
 				#pragma shader_feature _ _SPECULAR _SPECULAR_GLOSSMAP
 				#pragma shader_feature _NORMALMAP

+ 20 - 10
spine-unity/Assets/Spine/Runtime/spine-unity/Utility/MaterialChecks.cs

@@ -38,6 +38,8 @@ namespace Spine.Unity {
 
 		static readonly int STRAIGHT_ALPHA_PARAM_ID = Shader.PropertyToID("_StraightAlphaInput");
 		static readonly string ALPHAPREMULTIPLY_ON_KEYWORD = "_ALPHAPREMULTIPLY_ON";
+		static readonly string ALPHAPREMULTIPLY_VERTEX_ONLY_ON_KEYWORD = "_ALPHAPREMULTIPLY_VERTEX_ONLY";
+		static readonly string ALPHABLEND_ON_KEYWORD = "_ALPHABLEND_ON";
 		static readonly string STRAIGHT_ALPHA_KEYWORD = "_STRAIGHT_ALPHA_INPUT";
 		static readonly string[] FIXED_NORMALS_KEYWORDS = {
 			"_FIXED_NORMALS_VIEWSPACE",
@@ -50,7 +52,9 @@ namespace Spine.Unity {
 		static readonly string CANVAS_GROUP_COMPATIBLE_KEYWORD = "_CANVAS_GROUP_COMPATIBLE";
 
 		public static readonly string kPMANotSupportedLinearMessage =
-			"\nWarning: Premultiply-alpha atlas textures not supported in Linear color space!\n\nPlease\n"
+			"\nWarning: Premultiply-alpha atlas textures not supported in Linear color space!"
+			+ "You can use a straight alpha texture with 'PMA Vertex Color' by choosing blend mode 'PMA Vertex, Straight Texture'.\n\n"
+			+ "If you have a PMA Texture, please\n"
 			+ "a) re-export atlas as straight alpha texture with 'premultiply alpha' unchecked\n"
 			+ "   (if you have already done this, please set the 'Straight Alpha Texture' Material parameter to 'true') or\n"
 			+ "b) switch to Gamma color space via\nProject Settings - Player - Other Settings - Color Space.\n";
@@ -173,7 +177,7 @@ namespace Spine.Unity {
 
 		public static bool IsColorSpaceSupported (Material material, ref string errorMessage) {
 			if (QualitySettings.activeColorSpace == ColorSpace.Linear) {
-				if (IsPMAMaterial(material)) {
+				if (IsPMATextureMaterial(material)) {
 					errorMessage += kPMANotSupportedLinearMessage;
 					return false;
 				}
@@ -196,7 +200,7 @@ namespace Spine.Unity {
 			}
 
 			bool isProblematic = false;
-			if (IsPMAMaterial(material)) {
+			if (IsPMATextureMaterial(material)) {
 				// 'sRGBTexture = true' generates incorrectly weighted mipmaps at PMA textures,
 				// causing white borders due to undesired custom weighting.
 				if (sRGBTexture && mipmapEnabled && colorSpace == ColorSpace.Gamma) {
@@ -234,23 +238,29 @@ namespace Spine.Unity {
 			return isProblematic;
 		}
 
-		public static void EnablePMAAtMaterial (Material material, bool enablePMA) {
+		public static void EnablePMATextureAtMaterial (Material material, bool enablePMATexture) {
 			if (material.HasProperty(STRAIGHT_ALPHA_PARAM_ID)) {
-				material.SetInt(STRAIGHT_ALPHA_PARAM_ID, enablePMA ? 0 : 1);
-				if (enablePMA)
+				material.SetInt(STRAIGHT_ALPHA_PARAM_ID, enablePMATexture ? 0 : 1);
+				if (enablePMATexture)
 					material.DisableKeyword(STRAIGHT_ALPHA_KEYWORD);
 				else
 					material.EnableKeyword(STRAIGHT_ALPHA_KEYWORD);
 			}
 			else {
-				if (enablePMA)
-					material.EnableKeyword(ALPHAPREMULTIPLY_ON_KEYWORD);
-				else
+				if (enablePMATexture) {
+					material.DisableKeyword(ALPHAPREMULTIPLY_ON_KEYWORD);
+					material.DisableKeyword(ALPHABLEND_ON_KEYWORD);
+					material.EnableKeyword(ALPHAPREMULTIPLY_VERTEX_ONLY_ON_KEYWORD);
+				}
+				else {
 					material.DisableKeyword(ALPHAPREMULTIPLY_ON_KEYWORD);
+					material.DisableKeyword(ALPHAPREMULTIPLY_VERTEX_ONLY_ON_KEYWORD);
+					material.EnableKeyword(ALPHABLEND_ON_KEYWORD);
+				}
 			}
 		}
 
-		static bool IsPMAMaterial (Material material) {
+		static bool IsPMATextureMaterial (Material material) {
 			bool usesAlphaPremultiplyKeyword = IsSpriteShader(material);
 			if (usesAlphaPremultiplyKeyword)
 				return material.IsKeywordEnabled(ALPHAPREMULTIPLY_ON_KEYWORD);

+ 2 - 1
spine-unity/Modules/com.esotericsoftware.spine.lwrp-shaders/Shaders/CGIncludes/Spine-Skeleton-ForwardPass-LW.hlsl

@@ -3,6 +3,7 @@
 
 #include "Packages/com.unity.render-pipelines.lightweight/ShaderLibrary/Core.hlsl"
 #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/CommonMaterial.hlsl"
+#include "SpineCoreShaders/Spine-Common.cginc"
 
 struct appdata {
 	float3 pos : POSITION;
@@ -27,7 +28,7 @@ VertexOutput vert(appdata v) {
 	float3 positionWS = TransformObjectToWorld(v.pos);
 	o.pos = TransformWorldToHClip(positionWS);
 	o.uv0 = v.uv0;
-	o.color = v.color;
+	o.color = PMAGammaToTargetSpace(v.color);
 	return o;
 }
 

+ 2 - 1
spine-unity/Modules/com.esotericsoftware.spine.lwrp-shaders/Shaders/CGIncludes/Spine-SkeletonLit-ForwardPass-LW.hlsl

@@ -4,6 +4,7 @@
 #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/CommonMaterial.hlsl"
 #include "Packages/com.unity.render-pipelines.lightweight/ShaderLibrary/Core.hlsl"
 #include "Packages/com.unity.render-pipelines.lightweight/ShaderLibrary/Lighting.hlsl"
+#include "SpineCoreShaders/Spine-Common.cginc"
 
 #if (defined(_MAIN_LIGHT_SHADOWS) || defined(MAIN_LIGHT_CALCULATE_SHADOWS)) && !defined(_RECEIVE_SHADOWS_OFF)
 #define SKELETONLIT_RECEIVE_SHADOWS
@@ -55,7 +56,7 @@ VertexOutput vert(appdata v) {
 	UNITY_SETUP_INSTANCE_ID(v);
 	UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
 
-	half4 color = v.color;
+	half4 color = PMAGammaToTargetSpace(v.color);
 	float3 positionWS = TransformObjectToWorld(v.pos);
 	half3 fixedNormal = half3(0, 0, -1);
 	half3 normalWS = normalize(mul((float3x3)unity_ObjectToWorld, fixedNormal));

+ 2 - 2
spine-unity/Modules/com.esotericsoftware.spine.lwrp-shaders/Shaders/CGIncludes/Spine-Sprite-ForwardPass-LW.hlsl

@@ -105,7 +105,7 @@ half4 LightweightFragmentPBRSimplified(InputData inputData, half4 texAlbedoAlpha
 	finalColor += inputData.vertexLighting * brdfData.diffuse;
 #endif
 	finalColor += emission;
-	return prepareLitPixelForOutput(half4(finalColor, albedo.a), vertexColor);
+	return prepareLitPixelForOutput(half4(finalColor, albedo.a), texAlbedoAlpha.a, vertexColor.a);
 }
 
 #else // !SPECULAR
@@ -148,7 +148,7 @@ half4 LightweightFragmentBlinnPhongSimplified(InputData inputData, half4 texDiff
 	diffuseLighting += emission;
 	//half3 finalColor = diffuseLighting * diffuse + emission;
 	half3 finalColor = diffuseLighting * diffuse.rgb;
-	return prepareLitPixelForOutput(half4(finalColor, diffuse.a), vertexColor);
+	return prepareLitPixelForOutput(half4(finalColor, diffuse.a), texDiffuseAlpha.a, vertexColor.a);
 }
 #endif // SPECULAR
 

+ 2 - 0
spine-unity/Modules/com.esotericsoftware.spine.lwrp-shaders/Shaders/CGIncludes/SpineCoreShaders/Spine-Common.cginc

@@ -0,0 +1,2 @@
+// Adapt this path accordingly if you have unpacked the Spine directory to another location.
+#include "Assets/Spine/Runtime/spine-unity/Shaders/CGIncludes/Spine-Common.cginc"

+ 1 - 1
spine-unity/Modules/com.esotericsoftware.spine.lwrp-shaders/Shaders/Spine-Sprite-LW.shader

@@ -80,7 +80,7 @@ Shader "Lightweight Render Pipeline/Spine/Sprite"
 
 			// -------------------------------------
 			// Material Keywords
-			#pragma shader_feature _ _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON _ADDITIVEBLEND _ADDITIVEBLEND_SOFT _MULTIPLYBLEND _MULTIPLYBLEND_X2
+			#pragma shader_feature _ _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON _ALPHAPREMULTIPLY_VERTEX_ONLY _ADDITIVEBLEND _ADDITIVEBLEND_SOFT _MULTIPLYBLEND _MULTIPLYBLEND_X2
 			#pragma shader_feature _ _FIXED_NORMALS_VIEWSPACE _FIXED_NORMALS_VIEWSPACE_BACKFACE _FIXED_NORMALS_MODELSPACE _FIXED_NORMALS_MODELSPACE_BACKFACE _FIXED_NORMALS_WORLDSPACE
 			#pragma shader_feature _ _SPECULAR _SPECULAR_GLOSSMAP
 			#pragma shader_feature _NORMALMAP

+ 4 - 4
spine-unity/Modules/com.esotericsoftware.spine.lwrp-shaders/package-2019.1.json

@@ -1,8 +1,8 @@
 {
-	"name": "com.esotericsoftware.spine.lwrp-shaders", 
+	"name": "com.esotericsoftware.spine.lwrp-shaders",
 	"displayName": "Spine Lightweight RP Shaders",
 	"description": "This plugin provides lightweight render pipeline (LWRP) shaders for the spine-unity runtime.\n\nPrerequisites:\nIt requires a working installation of the spine-unity runtime, version 4.0.\n(See http://esotericsoftware.com/git/spine-runtimes/spine-unity)",
-	"version": "4.0.2",
+	"version": "4.0.3",
 	"unity": "2019.1",
 	"author": {
 		"name": "Esoteric Software",
@@ -18,5 +18,5 @@
 		"lightweight",
 		"render pipeline",
 		"shaders"
-	] 
-}
+	]
+}

+ 4 - 4
spine-unity/Modules/com.esotericsoftware.spine.lwrp-shaders/package-2019.2.json

@@ -1,8 +1,8 @@
 {
-	"name": "com.esotericsoftware.spine.lwrp-shaders", 
+	"name": "com.esotericsoftware.spine.lwrp-shaders",
 	"displayName": "Spine Lightweight RP Shaders",
 	"description": "This plugin provides lightweight render pipeline (LWRP) shaders for the spine-unity runtime.\n\nPrerequisites:\nIt requires a working installation of the spine-unity runtime, version 4.0.\n(See http://esotericsoftware.com/git/spine-runtimes/spine-unity)",
-	"version": "4.0.2",
+	"version": "4.0.3",
 	"unity": "2019.2",
 	"author": {
 		"name": "Esoteric Software",
@@ -18,5 +18,5 @@
 		"lightweight",
 		"render pipeline",
 		"shaders"
-	] 
-}
+	]
+}

+ 4 - 4
spine-unity/Modules/com.esotericsoftware.spine.lwrp-shaders/package.json

@@ -1,8 +1,8 @@
 {
-	"name": "com.esotericsoftware.spine.lwrp-shaders", 
+	"name": "com.esotericsoftware.spine.lwrp-shaders",
 	"displayName": "Spine Lightweight RP Shaders",
 	"description": "This plugin provides lightweight render pipeline (LWRP) shaders for the spine-unity runtime.\n\nPrerequisites:\nIt requires a working installation of the spine-unity runtime, version 4.0.\n(See http://esotericsoftware.com/git/spine-runtimes/spine-unity)",
-	"version": "4.0.2",
+	"version": "4.0.3",
 	"unity": "2019.1",
 	"author": {
 		"name": "Esoteric Software",
@@ -18,5 +18,5 @@
 		"lightweight",
 		"render pipeline",
 		"shaders"
-	] 
-}
+	]
+}

+ 3 - 2
spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/Examples/2D/Spine Skeletons/StretchymanURP/stretchyman_Material.mat

@@ -9,8 +9,8 @@ Material:
   m_PrefabAsset: {fileID: 0}
   m_Name: stretchyman_Material
   m_Shader: {fileID: 4800000, guid: a79d0a36ad5ba0542946e3c3317e2aa4, type: 3}
-  m_ShaderKeywords: _ALPHABLEND_ON _EMISSION _FIXED_NORMALS_VIEWSPACE _NORMALMAP
-    _USE8NEIGHBOURHOOD_ON
+  m_ShaderKeywords: _ALPHAPREMULTIPLY_VERTEX_ONLY _EMISSION _FIXED_NORMALS_VIEWSPACE
+    _NORMALMAP _USE8NEIGHBOURHOOD_ON
   m_LightmapFlags: 4
   m_EnableInstancingVariants: 0
   m_DoubleSidedGI: 0
@@ -81,3 +81,4 @@ Material:
     - _OutlineColor: {r: 1, g: 1, b: 0, a: 1}
     - _OverlayColor: {r: 0, g: 0, b: 0, a: 0}
     - _RimColor: {r: 1, g: 1, b: 1, a: 1}
+  m_BuildTextureStacks: []

+ 2 - 2
spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/Examples/2D/URP 2D Shaders.unity

@@ -160,7 +160,7 @@ MonoBehaviour:
   zSpacing: 0
   useClipping: 1
   immutableTriangles: 0
-  pmaVertexColors: 0
+  pmaVertexColors: 1
   clearStateOnDisable: 0
   tintBlack: 0
   singleSubmesh: 0
@@ -1020,7 +1020,7 @@ MonoBehaviour:
   zSpacing: 0
   useClipping: 1
   immutableTriangles: 0
-  pmaVertexColors: 0
+  pmaVertexColors: 1
   clearStateOnDisable: 0
   tintBlack: 0
   singleSubmesh: 0

+ 3 - 2
spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/Examples/3D/Spine Skeletons/StretchymanURP/stretchyman_Material.mat

@@ -9,8 +9,8 @@ Material:
   m_PrefabAsset: {fileID: 0}
   m_Name: stretchyman_Material
   m_Shader: {fileID: 4800000, guid: 9f253724b2d29a3438eeea48277c25cb, type: 3}
-  m_ShaderKeywords: _ALPHABLEND_ON _EMISSION _FIXED_NORMALS_VIEWSPACE _NORMALMAP
-    _RECEIVE_SHADOWS_OFF
+  m_ShaderKeywords: _ALPHAPREMULTIPLY_VERTEX_ONLY _EMISSION _FIXED_NORMALS_VIEWSPACE
+    _NORMALMAP _RECEIVE_SHADOWS_OFF
   m_LightmapFlags: 4
   m_EnableInstancingVariants: 0
   m_DoubleSidedGI: 0
@@ -81,3 +81,4 @@ Material:
     - _FixedNormal: {r: 0, g: 0, b: 1, a: 1}
     - _OverlayColor: {r: 0.18118013, g: 1, b: 0.033018887, a: 0}
     - _RimColor: {r: 1, g: 1, b: 1, a: 1}
+  m_BuildTextureStacks: []

+ 1 - 1
spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/Examples/Outline Shaders URP.unity

@@ -1718,7 +1718,7 @@ MonoBehaviour:
   zSpacing: 0
   useClipping: 1
   immutableTriangles: 0
-  pmaVertexColors: 0
+  pmaVertexColors: 1
   clearStateOnDisable: 0
   tintBlack: 0
   singleSubmesh: 0

+ 1 - 1
spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/Shaders/2D/Include/Spine-Sprite-StandardPass-URP-2D.hlsl

@@ -106,7 +106,7 @@ half4 CombinedShapeLightFragment(VertexOutputSpriteURP2D input) : SV_Target
 #endif
 
 	APPLY_EMISSION(pixel.rgb, input.texcoord)
-	pixel = prepareLitPixelForOutput(pixel, input.vertexColor);
+	pixel = prepareLitPixelForOutput(pixel, texureColor.a, input.vertexColor.a);
 	COLORISE(pixel)
 	return pixel;
 }

+ 4 - 1
spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/Shaders/2D/Spine-SkeletonLit-URP-2D.shader

@@ -58,7 +58,10 @@
 			#pragma vertex CombinedShapeLightVertex
 			#pragma fragment CombinedShapeLightFragment
 
+
 			#include "Packages/com.unity.render-pipelines.universal/Shaders/2D/Include/LightingUtility.hlsl"
+			#define USE_URP
+			#include "../Include/SpineCoreShaders/Spine-Common.cginc"
 
 			TEXTURE2D(_MainTex);
 			SAMPLER(sampler_MainTex);
@@ -89,7 +92,7 @@
 				o.uv = v.uv;
 				float4 clipVertex = o.positionCS / o.positionCS.w;
 				o.lightingUV = ComputeScreenPos(clipVertex).xy;
-				o.color = v.color;
+				o.color = PMAGammaToTargetSpace(v.color);
 				return o;
 			}
 

+ 1 - 1
spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/Shaders/2D/Spine-Sprite-URP-2D.shader

@@ -74,7 +74,7 @@ Shader "Universal Render Pipeline/2D/Spine/Sprite"
 
 			// -------------------------------------
 			// Material Keywords
-			#pragma shader_feature _ _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON _ADDITIVEBLEND _ADDITIVEBLEND_SOFT _MULTIPLYBLEND _MULTIPLYBLEND_X2
+			#pragma shader_feature _ _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON _ALPHAPREMULTIPLY_VERTEX_ONLY _ADDITIVEBLEND _ADDITIVEBLEND_SOFT _MULTIPLYBLEND _MULTIPLYBLEND_X2
 			#pragma shader_feature _ _FIXED_NORMALS_VIEWSPACE _FIXED_NORMALS_VIEWSPACE_BACKFACE _FIXED_NORMALS_MODELSPACE  _FIXED_NORMALS_MODELSPACE_BACKFACE
 			#pragma shader_feature _NORMALMAP
 			#pragma shader_feature _ALPHA_CLIP

+ 2 - 1
spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/Shaders/Include/Spine-Skeleton-ForwardPass-URP.hlsl

@@ -3,6 +3,7 @@
 
 #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
 #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/CommonMaterial.hlsl"
+#include "SpineCoreShaders/Spine-Common.cginc"
 
 struct appdata {
 	float3 pos : POSITION;
@@ -27,7 +28,7 @@ VertexOutput vert(appdata v) {
 	float3 positionWS = TransformObjectToWorld(v.pos);
 	o.pos = TransformWorldToHClip(positionWS);
 	o.uv0 = v.uv0;
-	o.color = v.color;
+	o.color = PMAGammaToTargetSpace(v.color);
 	return o;
 }
 

+ 2 - 1
spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/Shaders/Include/Spine-SkeletonLit-ForwardPass-URP.hlsl

@@ -4,6 +4,7 @@
 #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/CommonMaterial.hlsl"
 #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
 #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
+#include "SpineCoreShaders/Spine-Common.cginc"
 
 #if (defined(_MAIN_LIGHT_SHADOWS) || defined(MAIN_LIGHT_CALCULATE_SHADOWS)) && !defined(_RECEIVE_SHADOWS_OFF)
 #define SKELETONLIT_RECEIVE_SHADOWS
@@ -55,7 +56,7 @@ VertexOutput vert(appdata v) {
 	UNITY_SETUP_INSTANCE_ID(v);
 	UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
 
-	half4 color = v.color;
+	half4 color = PMAGammaToTargetSpace(v.color);
 	float3 positionWS = TransformObjectToWorld(v.pos);
 	half3 fixedNormal = half3(0, 0, -1);
 	half3 normalWS = normalize(mul((float3x3)unity_ObjectToWorld, fixedNormal));

+ 3 - 2
spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/Shaders/Include/Spine-Sprite-ForwardPass-URP.hlsl

@@ -4,6 +4,7 @@
 #include "Include/Spine-Sprite-Common-URP.hlsl"
 #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
 #include "SpineCoreShaders/SpriteLighting.cginc"
+#include "SpineCoreShaders/Spine-Common.cginc"
 
 #if defined(_RIM_LIGHTING) || defined(_ADDITIONAL_LIGHTS) || defined(MAIN_LIGHT_CALCULATE_SHADOWS)
 	#define NEEDS_POSITION_WS
@@ -109,7 +110,7 @@ half4 LightweightFragmentPBRSimplified(InputData inputData, half4 texAlbedoAlpha
 	finalColor += inputData.vertexLighting * brdfData.diffuse;
 #endif
 	finalColor += emission;
-	return prepareLitPixelForOutput(half4(finalColor, albedo.a), vertexColor);
+	return prepareLitPixelForOutput(half4(finalColor, albedo.a), texAlbedoAlpha.a, vertexColor.a);
 }
 
 #else // !SPECULAR
@@ -157,7 +158,7 @@ half4 LightweightFragmentBlinnPhongSimplified(InputData inputData, half4 texDiff
 	diffuseLighting += emission;
 	//half3 finalColor = diffuseLighting * diffuse + emission;
 	half3 finalColor = diffuseLighting * diffuse.rgb;
-	return prepareLitPixelForOutput(half4(finalColor, diffuse.a), vertexColor);
+	return prepareLitPixelForOutput(half4(finalColor, diffuse.a), texDiffuseAlpha.a, vertexColor.a);
 }
 #endif // SPECULAR
 

+ 2 - 0
spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/Shaders/Include/SpineCoreShaders/Spine-Common.cginc

@@ -0,0 +1,2 @@
+// Adapt this path accordingly if you have unpacked the Spine directory to another location.
+#include "Assets/Spine/Runtime/spine-unity/Shaders/CGIncludes/Spine-Common.cginc"

+ 10 - 0
spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/Shaders/Include/SpineCoreShaders/Spine-Common.cginc.meta

@@ -0,0 +1,10 @@
+fileFormatVersion: 2
+guid: 4e0db06e1bfb2c544ba6d1b209ad1911
+ShaderImporter:
+  externalObjects: {}
+  defaultTextures: []
+  nonModifiableTextures: []
+  preprocessorOverride: 0
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 1 - 1
spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/Shaders/Spine-Sprite-URP.shader

@@ -79,7 +79,7 @@ Shader "Universal Render Pipeline/Spine/Sprite"
 
 			// -------------------------------------
 			// Material Keywords
-			#pragma shader_feature _ _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON _ADDITIVEBLEND _ADDITIVEBLEND_SOFT _MULTIPLYBLEND _MULTIPLYBLEND_X2
+			#pragma shader_feature _ _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON _ALPHAPREMULTIPLY_VERTEX_ONLY _ADDITIVEBLEND _ADDITIVEBLEND_SOFT _MULTIPLYBLEND _MULTIPLYBLEND_X2
 			#pragma shader_feature _ _FIXED_NORMALS_VIEWSPACE _FIXED_NORMALS_VIEWSPACE_BACKFACE _FIXED_NORMALS_MODELSPACE _FIXED_NORMALS_MODELSPACE_BACKFACE _FIXED_NORMALS_WORLDSPACE
 			#pragma shader_feature _ _SPECULAR _SPECULAR_GLOSSMAP
 			#pragma shader_feature _NORMALMAP

+ 2 - 2
spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/package.json

@@ -2,7 +2,7 @@
   "name": "com.esotericsoftware.spine.urp-shaders",
   "displayName": "Spine Universal RP Shaders",
   "description": "This plugin provides universal render pipeline (URP) shaders for the spine-unity runtime.\n\nPrerequisites:\nIt requires a working installation of the spine-unity runtime, version 4.0.\n(See http://esotericsoftware.com/git/spine-runtimes/spine-unity)",
-  "version": "4.0.2",
+  "version": "4.0.3",
   "unity": "2019.3",
   "author": {
     "name": "Esoteric Software",
@@ -20,4 +20,4 @@
     "shaders"
   ],
   "hideInEditor": false
-}
+}