From 2f3d1e969964474722c5a1743de2e7823e0c8d40 Mon Sep 17 00:00:00 2001 From: mob-sakai Date: Fri, 1 Feb 2019 16:27:56 +0900 Subject: [PATCH] fix #16; SceneView does not display SoftMask properly --- Scripts/SoftMask.cs | 4 +-- Scripts/SoftMaskable.cs | 34 ++++++++++++++++---- Shaders/Resources/UI-Default-SoftMask.shader | 2 +- SoftMask.cginc | 20 ++++++------ 4 files changed, 41 insertions(+), 19 deletions(-) diff --git a/Scripts/SoftMask.cs b/Scripts/SoftMask.cs index c3a16f2..fb2445c 100644 --- a/Scripts/SoftMask.cs +++ b/Scripts/SoftMask.cs @@ -445,8 +445,8 @@ namespace Coffee.UIExtensions else { var pos = c.transform.localPosition; - var vm = Matrix4x4.TRS(-pos, 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 / 1000f)); + 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); } diff --git a/Scripts/SoftMaskable.cs b/Scripts/SoftMaskable.cs index bebcd67..2ba9872 100644 --- a/Scripts/SoftMaskable.cs +++ b/Scripts/SoftMaskable.cs @@ -175,6 +175,9 @@ namespace Coffee.UIExtensions static int s_SoftMaskTexId; static int s_StencilCompId; static int s_MaskInteractionId; + static int s_SceneVId; + static int s_ScenePId; + static int s_GameVPId; static List s_ActiveSoftMaskables; static int[] s_Interactions = new int[4]; static Material s_DefaultMaterial; @@ -195,16 +198,30 @@ namespace Coffee.UIExtensions Matrix4x4 w2c = cam.worldToCameraMatrix; Matrix4x4 prj = cam.projectionMatrix; + s_ActiveSoftMaskables.RemoveAll(x=>!x); foreach (var sm in s_ActiveSoftMaskables) { - if (sm) + if (!sm || !sm._maskMaterial || !sm.graphic || !sm.graphic.canvas) { - Material mat = sm._maskMaterial; - if (mat) - { - mat.SetMatrix("_SceneView", w2c); - mat.SetMatrix("_SceneProj", prj); - } + continue; + } + + Material mat = sm._maskMaterial; + mat.SetMatrix(s_SceneVId, w2c); + mat.SetMatrix(s_ScenePId, prj); + + var c = sm.graphic.canvas.rootCanvas; + if (c.renderMode != RenderMode.ScreenSpaceOverlay && c.worldCamera) + { + var wcam = c.worldCamera; + var pv = wcam.projectionMatrix * wcam.worldToCameraMatrix; + mat.SetMatrix(s_GameVPId, pv); + } + else + { + var pos = c.transform.localPosition; + var pv = Matrix4x4.TRS(new Vector3(0, 0, 0), Quaternion.identity, new Vector3(1 / pos.x, 1 / pos.y, -2 / 1000f)) * Matrix4x4.Translate(-pos); + mat.SetMatrix(s_GameVPId, pv); } } } @@ -233,6 +250,9 @@ namespace Coffee.UIExtensions #if UNITY_EDITOR UnityEditor.EditorApplication.update += UpdateSceneViewMatrixForShader; + s_SceneVId = Shader.PropertyToID("_SceneV"); + s_ScenePId = Shader.PropertyToID("_SceneP"); + s_GameVPId = Shader.PropertyToID("_GameVP"); #endif s_SoftMaskTexId = Shader.PropertyToID("_SoftMaskTex"); diff --git a/Shaders/Resources/UI-Default-SoftMask.shader b/Shaders/Resources/UI-Default-SoftMask.shader index 3ab56d0..6e92234 100644 --- a/Shaders/Resources/UI-Default-SoftMask.shader +++ b/Shaders/Resources/UI-Default-SoftMask.shader @@ -108,7 +108,7 @@ Shader "UI/Default-SoftMask" clip (color.a - 0.001); #endif - color.a *= SoftMask(IN.vertex); // Add for soft mask + color.a *= SoftMask(IN.vertex, IN.worldPosition); // Add for soft mask return color; } diff --git a/SoftMask.cginc b/SoftMask.cginc index c5e4e47..43df64f 100644 --- a/SoftMask.cginc +++ b/SoftMask.cginc @@ -3,8 +3,9 @@ sampler2D _SoftMaskTex; float _Stencil; -float4x4 _SceneView; -float4x4 _SceneProj; +float4x4 _SceneV; +float4x4 _SceneP; +float4x4 _GameVP; half4 _MaskInteraction; fixed Approximately(float4x4 a, float4x4 b) @@ -15,7 +16,7 @@ fixed Approximately(float4x4 a, float4x4 b) max(d._m10,max(d._m11,max(d._m12,max(d._m13, max(d._m20,max(d._m21,max(d._m22,max(d._m23, max(d._m30,max(d._m31,max(d._m32,d._m33))))))))))))))), - 0.01); + 1); } fixed GetMaskAlpha(fixed alpha, fixed stencilId, fixed interaction) @@ -25,9 +26,15 @@ fixed GetMaskAlpha(fixed alpha, fixed stencilId, fixed interaction) return lerp(alpha, 1 - alpha, onStencil * step(2, interaction)); } -half SoftMask(float4 clipPos) +half SoftMask(float4 clipPos, float4 wpos) { half2 view = clipPos.xy/_ScreenParams.xy; + #if SOFTMASK_EDITOR + fixed isSceneView = max(Approximately(UNITY_MATRIX_V, _SceneV), Approximately(UNITY_MATRIX_P, _SceneP)); + float4 cpos = mul(_GameVP, mul(UNITY_MATRIX_M, wpos)); + view = lerp(view, cpos.xy / cpos.w * 0.5 + 0.5, isSceneView); + #endif + #if UNITY_UV_STARTS_AT_TOP view.y = 1.0 - view.y; #endif @@ -38,11 +45,6 @@ half SoftMask(float4 clipPos) * GetMaskAlpha(mask.z, 7, _MaskInteraction.z) * GetMaskAlpha(mask.w, 15, _MaskInteraction.w); - #if SOFTMASK_EDITOR - fixed isSceneView = max(Approximately(UNITY_MATRIX_V, _SceneView), Approximately(UNITY_MATRIX_P, _SceneProj)); - alpha = lerp(alpha, 1, isSceneView); - #endif - return alpha; }