Skip to content

Commit

Permalink
fix: incorrect behavior when a world space canvas and an overlay canv…
Browse files Browse the repository at this point in the history
…as are enabled together

close #107
  • Loading branch information
mob-sakai committed Oct 8, 2020
1 parent a64a202 commit a6e82fa
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 26 deletions.
21 changes: 0 additions & 21 deletions Packages/SoftMaskForUGUI/Scripts/SoftMask.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,6 @@ public enum DownSamplingRate
private static int s_ColorMaskId;
private static int s_MainTexId;
private static int s_SoftnessId;
private static int s_GameVPId;
private static int s_GameTVPId;
private static int s_Alpha;
private static int s_PreviousWidth;
private static int s_PreviousHeight;
Expand Down Expand Up @@ -363,10 +361,6 @@ protected override void OnEnable()
s_MainTexId = Shader.PropertyToID("_MainTex");
s_SoftnessId = Shader.PropertyToID("_Softness");
s_Alpha = Shader.PropertyToID("_Alpha");
#if UNITY_EDITOR
s_GameVPId = Shader.PropertyToID("_GameVP");
s_GameTVPId = Shader.PropertyToID("_GameTVP");
#endif
}
}

Expand Down Expand Up @@ -611,28 +605,13 @@ private void UpdateMaskTexture()
{
var p = GL.GetGPUProjectionMatrix(cam.projectionMatrix, false);
_cb.SetViewProjectionMatrices(cam.worldToCameraMatrix, p);

#if UNITY_EDITOR
var pv = p * cam.worldToCameraMatrix;
_cb.SetGlobalMatrix(s_GameVPId, pv);
_cb.SetGlobalMatrix(s_GameTVPId, pv);
#endif
}
else
{
var pos = c.transform.position;
var vm = Matrix4x4.TRS(new Vector3(-pos.x, -pos.y, -1000), Quaternion.identity, new Vector3(1, 1, -1f));
var pm = Matrix4x4.TRS(new Vector3(0, 0, -1), Quaternion.identity, new Vector3(1 / pos.x, 1 / pos.y, -2 / 10000f));
_cb.SetViewProjectionMatrices(vm, pm);

#if UNITY_EDITOR
var scale = c.transform.localScale.x;
var size = (c.transform as RectTransform).sizeDelta;
var gameVp = Matrix4x4.TRS(new Vector3(0, 0, 0.5f), Quaternion.identity, new Vector3(2 / size.x, 2 / size.y, 0.0005f * scale));
var gameTvp = Matrix4x4.TRS(new Vector3(0, 0, 0), Quaternion.identity, new Vector3(1 / pos.x, 1 / pos.y, -2 / 2000f)) * Matrix4x4.Translate(-pos);
_cb.SetGlobalMatrix(s_GameVPId, gameVp);
_cb.SetGlobalMatrix(s_GameTVPId, gameTvp);
#endif
}

Profiler.EndSample();
Expand Down
57 changes: 53 additions & 4 deletions Packages/SoftMaskForUGUI/Scripts/SoftMaskable.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Profiling;
using UnityEngine.Rendering;
using UnityEngine.UI;
using MaskIntr = UnityEngine.SpriteMaskInteraction;
Expand Down Expand Up @@ -28,6 +30,8 @@ public class SoftMaskable : MonoBehaviour, IMaterialModifier, ICanvasRaycastFilt
private static int s_SoftMaskTexId;
private static int s_StencilCompId;
private static int s_MaskInteractionId;
private static int s_GameVPId;
private static int s_GameTVPId;
private static List<SoftMaskable> s_ActiveSoftMaskables;
private static int[] s_Interactions = new int[4];

Expand Down Expand Up @@ -98,6 +102,8 @@ public SoftMask softMask
get { return _softMask ? _softMask : _softMask = this.GetComponentInParentEx<SoftMask>(); }
}

public Material modifiedMaterial { get; private set; }

/// <summary>
/// Perform material modification in this function.
/// </summary>
Expand All @@ -106,6 +112,7 @@ public SoftMask softMask
Material IMaterialModifier.GetModifiedMaterial(Material baseMaterial)
{
_softMask = null;
modifiedMaterial = null;

// If this component is disabled, the material is returned as is.
// If the parents do not have a soft mask component, the material is returned as is.
Expand All @@ -126,14 +133,16 @@ Material IMaterialModifier.GetModifiedMaterial(Material baseMaterial)
);

// Generate soft maskable material.
var modifiedMaterial = MaterialCache.Register(baseMaterial, _effectMaterialHash, mat =>
modifiedMaterial = MaterialCache.Register(baseMaterial, _effectMaterialHash, mat =>
{
mat.shader = Shader.Find(string.Format("Hidden/{0} (SoftMaskable)", mat.shader.name));
mat.SetTexture(s_SoftMaskTexId, softMask.softMaskBuffer);
mat.SetInt(s_StencilCompId, m_UseStencil ? (int) CompareFunction.Equal : (int) CompareFunction.Always);
#if UNITY_EDITOR
mat.EnableKeyword("SOFTMASK_EDITOR");
UpdateMaterialForSceneView(mat);
#endif
mat.SetTexture(s_SoftMaskTexId, softMask.softMaskBuffer);
mat.SetInt(s_StencilCompId, m_UseStencil ? (int) CompareFunction.Equal : (int) CompareFunction.Always);
var root = MaskUtilities.FindRootSortOverrideCanvas(transform);
var stencil = MaskUtilities.GetStencilDepth(transform, root);
Expand Down Expand Up @@ -235,6 +244,11 @@ private void OnEnable()
s_SoftMaskTexId = Shader.PropertyToID("_SoftMaskTex");
s_StencilCompId = Shader.PropertyToID("_StencilComp");
s_MaskInteractionId = Shader.PropertyToID("_MaskInteraction");

#if UNITY_EDITOR
s_GameVPId = Shader.PropertyToID("_GameVP");
s_GameTVPId = Shader.PropertyToID("_GameTVP");
#endif
}

s_ActiveSoftMaskables.Add(this);
Expand All @@ -258,6 +272,41 @@ private void OnDisable()
}

#if UNITY_EDITOR
private void UpdateMaterialForSceneView(Material mat)
{
if(!mat || !graphic || !graphic.canvas || !mat.shader || !mat.shader.name.EndsWith(" (SoftMaskable)")) return;

// Set view and projection matrices.
Profiler.BeginSample("Set view and projection matrices");
var c = graphic.canvas.rootCanvas;
var cam = c.worldCamera ?? Camera.main;
if (c && c.renderMode != RenderMode.ScreenSpaceOverlay && cam)
{
var p = GL.GetGPUProjectionMatrix(cam.projectionMatrix, false);
var pv = p * cam.worldToCameraMatrix;
mat.SetMatrix(s_GameVPId, pv);
mat.SetMatrix(s_GameTVPId, pv);
}
else
{
var pos = c.transform.position;
var scale = c.transform.localScale.x;
var size = (c.transform as RectTransform).sizeDelta;
var gameVp = Matrix4x4.TRS(new Vector3(0, 0, 0.5f), Quaternion.identity, new Vector3(2 / size.x, 2 / size.y, 0.0005f * scale));
var gameTvp = Matrix4x4.TRS(new Vector3(0, 0, 0), Quaternion.identity, new Vector3(1 / pos.x, 1 / pos.y, -2 / 2000f)) * Matrix4x4.Translate(-pos);

mat.SetMatrix(s_GameVPId, gameVp);
mat.SetMatrix(s_GameTVPId, gameTvp);
}
Profiler.EndSample();
}

private void LateUpdate()
{
UpdateMaterialForSceneView(modifiedMaterial);
}


/// <summary>
/// This function is called when the script is loaded or a value is changed in the inspector (Called in the editor only).
/// </summary>
Expand Down
2 changes: 1 addition & 1 deletion Packages/SoftMaskForUGUI/Shaders/SoftMask.cginc
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ float SoftMaskInternal(float4 clipPos)
fixed4 mask = tex2D(_SoftMaskTex, view);
half4 alpha = saturate(lerp(fixed4(1, 1, 1, 1), lerp(mask, 1 - mask, _MaskInteraction - 1), _MaskInteraction));
#if SOFTMASK_EDITOR
alpha = lerp(fixed4(1, 1, 1, 1), alpha, step(0, view.x) * step(view.x, 1) * step(0, view.y) * step(view.y, 1));
alpha *= step(0, view.x) * step(view.x, 1) * step(0, view.y) * step(view.y, 1);
#endif

return alpha.x * alpha.y * alpha.z * alpha.w;
Expand Down

0 comments on commit a6e82fa

Please sign in to comment.