From 2b28510acd8d0b65b681f9a58ca25922fd44b4bb Mon Sep 17 00:00:00 2001 From: Harald Csaszar Date: Wed, 27 Jul 2022 19:21:34 +0200 Subject: [PATCH 1/4] [unity] Fixed SkeletonGraphic shader flickering on low alpha vertex colors in Linear color space. Closes #2128. --- .../Shaders/CGIncludes/Spine-Common.cginc | 14 ++++++++++++++ .../Spine-SkeletonGraphic-NormalPass.cginc | 3 ++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/CGIncludes/Spine-Common.cginc b/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/CGIncludes/Spine-Common.cginc index 442bb3fea..5df8e1632 100644 --- a/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/CGIncludes/Spine-Common.cginc +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/CGIncludes/Spine-Common.cginc @@ -39,4 +39,18 @@ inline half4 PMAGammaToTargetSpace(half4 gammaPMAColor) { #endif } +// Saturated version to prevent numerical issues that occur at CanvasRenderer +// shader during linear-space PMA vertex color correction (countering automatic Unity conversion). +// Note: Only use this method when the original color.rgb values lie within [0,1] range and +// it's not an HDR color. This method is usually suitable for vertex color. +inline half4 PMAGammaToTargetSpaceSaturated(half4 gammaPMAColor) { +#if UNITY_COLORSPACE_GAMMA + return gammaPMAColor; +#else + return gammaPMAColor.a == 0 ? + half4(GammaToLinearSpace(gammaPMAColor.rgb), gammaPMAColor.a) : + half4(saturate(GammaToLinearSpace(gammaPMAColor.rgb / gammaPMAColor.a)) * gammaPMAColor.a, gammaPMAColor.a); +#endif +} + #endif diff --git a/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/SkeletonGraphic/CGIncludes/Spine-SkeletonGraphic-NormalPass.cginc b/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/SkeletonGraphic/CGIncludes/Spine-SkeletonGraphic-NormalPass.cginc index a5ed3c7ac..9b414b743 100644 --- a/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/SkeletonGraphic/CGIncludes/Spine-SkeletonGraphic-NormalPass.cginc +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/SkeletonGraphic/CGIncludes/Spine-SkeletonGraphic-NormalPass.cginc @@ -49,7 +49,8 @@ VertexOutput vert (VertexInput IN) { #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)); + // Saturated version used to prevent numerical issues of certain low-alpha values. + float4 vertexColor = PMAGammaToTargetSpaceSaturated(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; From d9c6e048a05a7c94d2137fce80148a25c8170430 Mon Sep 17 00:00:00 2001 From: Harald Csaszar Date: Thu, 28 Jul 2022 18:47:49 +0200 Subject: [PATCH 2/4] [unity] Fixed Inspector preview skeleton `PMA Vertex Color` not being enabled for all Spine shaders. Closes #2129. --- .../Spine/Editor/spine-unity/Editor/Utility/AssetUtility.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Utility/AssetUtility.cs b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Utility/AssetUtility.cs index 53455f111..be32b33f3 100644 --- a/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Utility/AssetUtility.cs +++ b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Utility/AssetUtility.cs @@ -1240,7 +1240,7 @@ namespace Spine.Unity.Editor { internal static readonly List additionalSpawnTypes = new List(); public static void TryInitializeSkeletonRendererSettings (SkeletonRenderer skeletonRenderer, Skin skin = null) { - const string PMAShaderQuery = "Spine/Skeleton"; + const string PMAShaderQuery = "Spine/"; const string TintBlackShaderQuery = "Tint Black"; if (skeletonRenderer == null) return; From 5fbbc156ac359593a8148cff219b1052011ff558 Mon Sep 17 00:00:00 2001 From: Harald Csaszar Date: Thu, 28 Jul 2022 20:19:11 +0200 Subject: [PATCH 3/4] [unity] SkeletonRenderTexture now supports correct arbitrary rotation around all axes simultaneously, while maintaining pixel-perfect projection. Closes #2112. Added base class. --- .../SkeletonRenderTexture.cs | 165 +++++++++--------- .../SkeletonRenderTextureBase.cs | 79 +++++++++ .../SkeletonRenderTextureFadeout.cs | 6 +- 3 files changed, 169 insertions(+), 81 deletions(-) create mode 100644 spine-unity/Assets/Spine Examples/Scripts/Sample Components/SkeletonRenderTexture/SkeletonRenderTextureBase.cs diff --git a/spine-unity/Assets/Spine Examples/Scripts/Sample Components/SkeletonRenderTexture/SkeletonRenderTexture.cs b/spine-unity/Assets/Spine Examples/Scripts/Sample Components/SkeletonRenderTexture/SkeletonRenderTexture.cs index 1cbb6879f..19c814c04 100644 --- a/spine-unity/Assets/Spine Examples/Scripts/Sample Components/SkeletonRenderTexture/SkeletonRenderTexture.cs +++ b/spine-unity/Assets/Spine Examples/Scripts/Sample Components/SkeletonRenderTexture/SkeletonRenderTexture.cs @@ -35,6 +35,7 @@ #define HAS_GET_SHARED_MATERIALS #endif +using System; using System.Collections.Generic; using UnityEngine; using UnityEngine.Rendering; @@ -50,46 +51,38 @@ namespace Spine.Unity.Examples { /// because of the additional rendering overhead. Only enable it when alpha blending is required. /// [RequireComponent(typeof(SkeletonRenderer))] - public class SkeletonRenderTexture : MonoBehaviour { + public class SkeletonRenderTexture : SkeletonRenderTextureBase { #if HAS_GET_SHARED_MATERIALS - public Color color = Color.white; public Material quadMaterial; public Camera targetCamera; - public int maxRenderTextureSize = 1024; protected SkeletonRenderer skeletonRenderer; protected MeshRenderer meshRenderer; protected MeshFilter meshFilter; - public GameObject quad; protected MeshRenderer quadMeshRenderer; protected MeshFilter quadMeshFilter; - protected Mesh quadMesh; - public RenderTexture renderTexture; + protected Vector3 worldCornerNoDistortion0; + protected Vector3 worldCornerNoDistortion1; + protected Vector3 worldCornerNoDistortion2; + protected Vector3 worldCornerNoDistortion3; + protected Vector2 uvCorner0; + protected Vector2 uvCorner1; + protected Vector2 uvCorner2; + protected Vector2 uvCorner3; - private CommandBuffer commandBuffer; private MaterialPropertyBlock propertyBlock; private readonly List materials = new List(); - - protected Vector2Int requiredRenderTextureSize; - protected Vector2Int allocatedRenderTextureSize; - - void Awake () { + protected override void Awake () { + base.Awake(); meshRenderer = this.GetComponent(); meshFilter = this.GetComponent(); skeletonRenderer = this.GetComponent(); if (targetCamera == null) targetCamera = Camera.main; - commandBuffer = new CommandBuffer(); propertyBlock = new MaterialPropertyBlock(); - CreateQuadChild(); } - void OnDestroy () { - if (renderTexture) - RenderTexture.ReleaseTemporary(renderTexture); - } - void CreateQuadChild () { quad = new GameObject(this.name + " RenderTexture", typeof(MeshRenderer), typeof(MeshFilter)); quad.transform.SetParent(this.transform.parent, false); @@ -138,46 +131,77 @@ namespace Spine.Unity.Examples { } protected void PrepareForMesh () { + // We need to get the min/max of all four corners, rotation of the skeleton + // in combination with perspective projection otherwise might lead to incorrect + // screen space min/max. Bounds boundsLocalSpace = meshFilter.sharedMesh.bounds; - Vector3 meshMinWorldSpace = transform.TransformPoint(boundsLocalSpace.min); - Vector3 meshMaxWorldSpace = transform.TransformPoint(boundsLocalSpace.max); - Vector3 meshMinXMaxYWorldSpace = new Vector3(meshMinWorldSpace.x, meshMaxWorldSpace.y); - Vector3 meshMaxXMinYWorldSpace = new Vector3(meshMaxWorldSpace.x, meshMinWorldSpace.y); + Vector3 localCorner0 = boundsLocalSpace.min; + Vector3 localCorner3 = boundsLocalSpace.max; + Vector3 localCorner1 = new Vector3(localCorner0.x, localCorner3.y, localCorner0.z); + Vector3 localCorner2 = new Vector3(localCorner3.x, localCorner0.y, localCorner3.z); - // We need to get the min/max of all four corners, close position and rotation of the skeleton - // in combination with perspective projection otherwise might lead to incorrect screen space min/max. - Vector3 meshMinProjected = targetCamera.WorldToScreenPoint(meshMinWorldSpace); - Vector3 meshMaxProjected = targetCamera.WorldToScreenPoint(meshMaxWorldSpace); - Vector3 meshMinXMaxYProjected = targetCamera.WorldToScreenPoint(meshMinXMaxYWorldSpace); - Vector3 meshMaxXMinYProjected = targetCamera.WorldToScreenPoint(meshMaxXMinYWorldSpace); - // To handle 180 degree rotation and thus min/max inversion, we get min/max of all four corners - Vector3 meshMinScreenSpace = - Vector3.Min(meshMinProjected, Vector3.Min(meshMaxProjected, - Vector3.Min(meshMinXMaxYProjected, meshMaxXMinYProjected))); - Vector3 meshMaxScreenSpace = - Vector3.Max(meshMinProjected, Vector3.Max(meshMaxProjected, - Vector3.Max(meshMinXMaxYProjected, meshMaxXMinYProjected))); + Vector3 worldCorner0 = transform.TransformPoint(localCorner0); + Vector3 worldCorner1 = transform.TransformPoint(localCorner1); + Vector3 worldCorner2 = transform.TransformPoint(localCorner2); + Vector3 worldCorner3 = transform.TransformPoint(localCorner3); + + Vector3 screenCorner0 = targetCamera.WorldToScreenPoint(worldCorner0); + Vector3 screenCorner1 = targetCamera.WorldToScreenPoint(worldCorner1); + Vector3 screenCorner2 = targetCamera.WorldToScreenPoint(worldCorner2); + Vector3 screenCorner3 = targetCamera.WorldToScreenPoint(worldCorner3); + + // To avoid perspective distortion when rotated, we project all vertices + // onto a plane parallel to the view frustum near plane. + // Avoids the requirement of 'noperspective' vertex attribute interpolation modifier in shaders. + float averageScreenDepth = (screenCorner0.z + screenCorner1.z + screenCorner2.z + screenCorner3.z) / 4.0f; + screenCorner0.z = screenCorner1.z = screenCorner2.z = screenCorner3.z = averageScreenDepth; + worldCornerNoDistortion0 = targetCamera.ScreenToWorldPoint(screenCorner0); + worldCornerNoDistortion1 = targetCamera.ScreenToWorldPoint(screenCorner1); + worldCornerNoDistortion2 = targetCamera.ScreenToWorldPoint(screenCorner2); + worldCornerNoDistortion3 = targetCamera.ScreenToWorldPoint(screenCorner3); + + Vector3 screenSpaceMin = + Vector3.Min(screenCorner0, Vector3.Min(screenCorner1, + Vector3.Min(screenCorner2, screenCorner3))); + Vector3 screenSpaceMax = + Vector3.Max(screenCorner0, Vector3.Max(screenCorner1, + Vector3.Max(screenCorner2, screenCorner3))); + // ensure we are on whole pixel borders + screenSpaceMin.x = Mathf.Floor(screenSpaceMin.x); + screenSpaceMin.y = Mathf.Floor(screenSpaceMin.y); + screenSpaceMax.x = Mathf.Ceil(screenSpaceMax.x); + screenSpaceMax.y = Mathf.Ceil(screenSpaceMax.y); + + // inverse-map screenCornerN to screenSpaceMin/screenSpaceMax area to get UV coordinates + uvCorner0 = InverseLerp(screenSpaceMin, screenSpaceMax, screenCorner0); + uvCorner1 = InverseLerp(screenSpaceMin, screenSpaceMax, screenCorner1); + uvCorner2 = InverseLerp(screenSpaceMin, screenSpaceMax, screenCorner2); + uvCorner3 = InverseLerp(screenSpaceMin, screenSpaceMax, screenCorner3); requiredRenderTextureSize = new Vector2Int( - Mathf.Min(maxRenderTextureSize, Mathf.CeilToInt(Mathf.Abs(meshMaxScreenSpace.x - meshMinScreenSpace.x))), - Mathf.Min(maxRenderTextureSize, Mathf.CeilToInt(Mathf.Abs(meshMaxScreenSpace.y - meshMinScreenSpace.y)))); + Math.Min(maxRenderTextureSize, Math.Abs((int)screenSpaceMax.x - (int)screenSpaceMin.x)), + Math.Min(maxRenderTextureSize, Math.Abs((int)screenSpaceMax.y - (int)screenSpaceMin.y))); PrepareRenderTexture(); - PrepareCommandBuffer(meshMinWorldSpace, meshMaxWorldSpace); + PrepareCommandBuffer(targetCamera, screenSpaceMin, screenSpaceMax); } - protected void PrepareCommandBuffer (Vector3 meshMinWorldSpace, Vector3 meshMaxWorldSpace) { + protected Vector2 InverseLerp (Vector2 a, Vector2 b, Vector2 value) { + return new Vector2( + (value.x - a.x) / (b.x - a.x), + (value.y - a.y) / (b.y - a.y)); + } + + protected void PrepareCommandBuffer (Camera targetCamera, Vector3 screenSpaceMin, Vector3 screenSpaceMax) { + commandBuffer.Clear(); commandBuffer.SetRenderTarget(renderTexture); commandBuffer.ClearRenderTarget(true, true, Color.clear); - Matrix4x4 projectionMatrix = Matrix4x4.Ortho( - meshMinWorldSpace.x, meshMaxWorldSpace.x, - meshMinWorldSpace.y, meshMaxWorldSpace.y, - float.MinValue, float.MaxValue); - - commandBuffer.SetProjectionMatrix(projectionMatrix); - commandBuffer.SetViewport(new Rect(Vector2.zero, requiredRenderTextureSize)); + commandBuffer.SetProjectionMatrix(targetCamera.projectionMatrix); + commandBuffer.SetViewMatrix(targetCamera.worldToCameraMatrix); + Vector2 targetCameraViewportSize = targetCamera.pixelRect.size; + commandBuffer.SetViewport(new Rect(-screenSpaceMin, targetCameraViewportSize)); } protected void RenderToRenderTexture () { @@ -191,15 +215,17 @@ namespace Spine.Unity.Examples { } protected void AssignAtQuad () { - Vector2 min = meshFilter.sharedMesh.bounds.min; - Vector2 max = meshFilter.sharedMesh.bounds.max; + Transform quadTransform = quadMeshRenderer.transform; + quadTransform.position = this.transform.position; + quadTransform.rotation = this.transform.rotation; + quadTransform.localScale = this.transform.localScale; + + Vector3 v0 = quadTransform.InverseTransformPoint(worldCornerNoDistortion0); + Vector3 v1 = quadTransform.InverseTransformPoint(worldCornerNoDistortion1); + Vector3 v2 = quadTransform.InverseTransformPoint(worldCornerNoDistortion2); + Vector3 v3 = quadTransform.InverseTransformPoint(worldCornerNoDistortion3); + Vector3[] vertices = new Vector3[4] { v0, v1, v2, v3 }; - Vector3[] vertices = new Vector3[4] { - new Vector3(min.x, min.y, 0), - new Vector3(max.x, min.y, 0), - new Vector3(min.x, max.y, 0), - new Vector3(max.x, max.y, 0) - }; quadMesh.vertices = vertices; int[] indices = new int[6] { 0, 2, 1, 2, 3, 1 }; @@ -213,35 +239,18 @@ namespace Spine.Unity.Examples { }; quadMesh.normals = normals; - float maxU = (float)(requiredRenderTextureSize.x) / allocatedRenderTextureSize.x; - float maxV = (float)(requiredRenderTextureSize.y) / allocatedRenderTextureSize.y; + float maxU = (float)requiredRenderTextureSize.x / (float)allocatedRenderTextureSize.x; + float maxV = (float)requiredRenderTextureSize.y / (float)allocatedRenderTextureSize.y; Vector2[] uv = new Vector2[4] { - new Vector2(0, 0), - new Vector2(maxU, 0), - new Vector2(0, maxV), - new Vector2(maxU, maxV) + new Vector2(uvCorner0.x * maxU, uvCorner0.y * maxV), + new Vector2(uvCorner1.x * maxU, uvCorner1.y * maxV), + new Vector2(uvCorner2.x * maxU, uvCorner2.y * maxV), + new Vector2(uvCorner3.x * maxU, uvCorner3.y * maxV), }; quadMesh.uv = uv; quadMeshFilter.mesh = quadMesh; quadMeshRenderer.sharedMaterial.mainTexture = this.renderTexture; quadMeshRenderer.sharedMaterial.color = color; - - quadMeshRenderer.transform.position = this.transform.position; - quadMeshRenderer.transform.rotation = this.transform.rotation; - quadMeshRenderer.transform.localScale = this.transform.localScale; - } - - protected void PrepareRenderTexture () { - Vector2Int textureSize = new Vector2Int( - Mathf.NextPowerOfTwo(requiredRenderTextureSize.x), - Mathf.NextPowerOfTwo(requiredRenderTextureSize.y)); - - if (textureSize != allocatedRenderTextureSize) { - if (renderTexture) - RenderTexture.ReleaseTemporary(renderTexture); - renderTexture = RenderTexture.GetTemporary(textureSize.x, textureSize.y); - allocatedRenderTextureSize = textureSize; - } } #endif } diff --git a/spine-unity/Assets/Spine Examples/Scripts/Sample Components/SkeletonRenderTexture/SkeletonRenderTextureBase.cs b/spine-unity/Assets/Spine Examples/Scripts/Sample Components/SkeletonRenderTexture/SkeletonRenderTextureBase.cs new file mode 100644 index 000000000..9a6e13959 --- /dev/null +++ b/spine-unity/Assets/Spine Examples/Scripts/Sample Components/SkeletonRenderTexture/SkeletonRenderTextureBase.cs @@ -0,0 +1,79 @@ +/****************************************************************************** + * Spine Runtimes License Agreement + * Last updated January 1, 2020. Replaces all prior versions. + * + * Copyright (c) 2013-2022, Esoteric Software LLC + * + * Integration of the Spine Runtimes into software or otherwise creating + * derivative works of the Spine Runtimes is permitted under the terms and + * conditions of Section 2 of the Spine Editor License Agreement: + * http://esotericsoftware.com/spine-editor-license + * + * Otherwise, it is permitted to integrate the Spine Runtimes into software + * or otherwise create derivative works of the Spine Runtimes (collectively, + * "Products"), provided that each user of the Products must obtain their own + * Spine Editor license and redistribution of the Products in any form must + * include this license and copyright notice. + * + * THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, + * BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *****************************************************************************/ + +#if UNITY_2019_3_OR_NEWER +#define HAS_FORCE_RENDER_OFF +#endif + +#if UNITY_2018_2_OR_NEWER +#define HAS_GET_SHARED_MATERIALS +#endif + +using UnityEngine; +using UnityEngine.Rendering; + +namespace Spine.Unity.Examples { + + public abstract class SkeletonRenderTextureBase : MonoBehaviour { +#if HAS_GET_SHARED_MATERIALS + public Color color = Color.white; + public int maxRenderTextureSize = 1024; + public GameObject quad; + protected Mesh quadMesh; + public RenderTexture renderTexture; + + protected CommandBuffer commandBuffer; + protected Vector2Int requiredRenderTextureSize; + protected Vector2Int allocatedRenderTextureSize; + + protected virtual void Awake () { + commandBuffer = new CommandBuffer(); + } + + void OnDestroy () { + if (renderTexture) + RenderTexture.ReleaseTemporary(renderTexture); + } + + protected void PrepareRenderTexture () { + Vector2Int textureSize = new Vector2Int( + Mathf.NextPowerOfTwo(requiredRenderTextureSize.x), + Mathf.NextPowerOfTwo(requiredRenderTextureSize.y)); + + if (textureSize != allocatedRenderTextureSize) { + if (renderTexture) + RenderTexture.ReleaseTemporary(renderTexture); + renderTexture = RenderTexture.GetTemporary(textureSize.x, textureSize.y); + renderTexture.filterMode = FilterMode.Point; + allocatedRenderTextureSize = textureSize; + } + } +#endif + } +} diff --git a/spine-unity/Assets/Spine Examples/Scripts/Sample Components/SkeletonRenderTexture/SkeletonRenderTextureFadeout.cs b/spine-unity/Assets/Spine Examples/Scripts/Sample Components/SkeletonRenderTexture/SkeletonRenderTextureFadeout.cs index 27605c9e1..e251ad16f 100644 --- a/spine-unity/Assets/Spine Examples/Scripts/Sample Components/SkeletonRenderTexture/SkeletonRenderTextureFadeout.cs +++ b/spine-unity/Assets/Spine Examples/Scripts/Sample Components/SkeletonRenderTexture/SkeletonRenderTextureFadeout.cs @@ -47,9 +47,9 @@ namespace Spine.Unity.Examples { /// At the end of the fadeout, the event delegate OnFadeoutComplete is called, to which you can bind e.g. /// a method that disables or destroys the entire GameObject. /// - [RequireComponent(typeof(SkeletonRenderTexture))] + [RequireComponent(typeof(SkeletonRenderTextureBase))] public class SkeletonRenderTextureFadeout : MonoBehaviour { - SkeletonRenderTexture skeletonRenderTexture; + SkeletonRenderTextureBase skeletonRenderTexture; public float fadeoutSeconds = 2.0f; protected float fadeoutSecondsRemaining; @@ -58,7 +58,7 @@ namespace Spine.Unity.Examples { public event FadeoutCallback OnFadeoutComplete; protected void Awake () { - skeletonRenderTexture = this.GetComponent(); + skeletonRenderTexture = this.GetComponent(); } protected void OnEnable () { From 1c150203abc79f949c6ca498f888970748405036 Mon Sep 17 00:00:00 2001 From: Mario Zechner Date: Fri, 29 Jul 2022 14:57:56 +0200 Subject: [PATCH 4/4] [godot] Fixes for latest 4.0 commits, automatically install MoltenVK on macOS via setup.sh --- spine-godot/build/install-macos-vulkan-sdk.sh | 10 ++++++++++ spine-godot/build/setup.sh | 4 ++++ spine-godot/spine_godot/SpineSprite.cpp | 6 +++--- 3 files changed, 17 insertions(+), 3 deletions(-) create mode 100755 spine-godot/build/install-macos-vulkan-sdk.sh diff --git a/spine-godot/build/install-macos-vulkan-sdk.sh b/spine-godot/build/install-macos-vulkan-sdk.sh new file mode 100755 index 000000000..7de9fd307 --- /dev/null +++ b/spine-godot/build/install-macos-vulkan-sdk.sh @@ -0,0 +1,10 @@ +set -euo pipefail +IFS=$'\n\t' + +# Download and install the Vulkan SDK. +curl -L "https://sdk.lunarg.com/sdk/download/latest/mac/vulkan-sdk.dmg" -o /tmp/vulkan-sdk.dmg +hdiutil attach /tmp/vulkan-sdk.dmg -mountpoint /Volumes/vulkan-sdk +/Volumes/vulkan-sdk/InstallVulkan.app/Contents/MacOS/InstallVulkan \ + --accept-licenses --default-answer --confirm-command install +hdiutil detach /Volumes/vulkan-sdk +rm -f /tmp/vulkan-sdk.dmg \ No newline at end of file diff --git a/spine-godot/build/setup.sh b/spine-godot/build/setup.sh index a400e3e18..262219c17 100755 --- a/spine-godot/build/setup.sh +++ b/spine-godot/build/setup.sh @@ -32,6 +32,10 @@ if [ $dev = "true" ]; then git apply ../build/livepp-v4.patch popd fi + + if [ `uname` == 'Darwin' ] && [ ! -d "$HOME/VulkanSDK" ]; then + ./build/install-macos-vulkan-sdk.sh + fi fi cp -r ../spine-cpp/spine-cpp spine_godot popd diff --git a/spine-godot/spine_godot/SpineSprite.cpp b/spine-godot/spine_godot/SpineSprite.cpp index 7a75649af..40ccc5a03 100644 --- a/spine-godot/spine_godot/SpineSprite.cpp +++ b/spine-godot/spine_godot/SpineSprite.cpp @@ -831,16 +831,16 @@ void SpineSprite::draw() { auto global_scale = get_global_scale(); draw_set_transform(mouse_position + Vector2(20, 0), -get_global_rotation(), Vector2(inverse_zoom * (1 / global_scale.x), inverse_zoom * (1 / global_scale.y))); - float line_height = default_font->get_height() + default_font->get_descent(); + float line_height = default_font->get_height(Font::DEFAULT_FONT_SIZE) + default_font->get_descent(Font::DEFAULT_FONT_SIZE); float rect_width = 0; for (int i = 0; i < hover_text_lines.size(); i++) { rect_width = MAX(rect_width, default_font->get_string_size(hover_text_lines[i]).x); } - Rect2 background_rect(0, -default_font->get_height() - 5, rect_width + 20, line_height * hover_text_lines.size() + 10); + Rect2 background_rect(0, -default_font->get_height(Font::DEFAULT_FONT_SIZE) - 5, rect_width + 20, line_height * hover_text_lines.size() + 10); if (hover_text_lines.size() > 0) draw_rect(background_rect, Color(0, 0, 0, 0.8)); for (int i = 0; i < hover_text_lines.size(); i++) { #if VERSION_MAJOR > 3 - draw_string(default_font, Vector2(10, 0 + i * default_font->get_height()), hover_text_lines[i], HORIZONTAL_ALIGNMENT_LEFT, -1, Font::DEFAULT_FONT_SIZE, Color(1, 1, 1, 1)); + draw_string(default_font, Vector2(10, 0 + i * default_font->get_height(Font::DEFAULT_FONT_SIZE)), hover_text_lines[i], HORIZONTAL_ALIGNMENT_LEFT, -1, Font::DEFAULT_FONT_SIZE, Color(1, 1, 1, 1)); #else draw_string(default_font, Vector2(10, 0 + i * default_font->get_height()), hover_text_lines[i], Color(1, 1, 1, 1)); #endif