Files
Liubing\LB 3d8d4d18f3 first commit
先修复一下,错误的场景

删除不必要的钓场资产

修复into场景

update:更新meta文件,修复报错

update:修复资源

修复第一章节建造

修复建造第三章

update:删除多余内容

update:更新README.md

update:还原图标

update:更新README

update:更新配置
2026-04-28 02:17:22 +08:00

903 lines
30 KiB
C#

using System;
using System.Collections.Generic;
using Coffee.UISoftMaskInternal;
using UnityEditor;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Profiling;
using UnityEngine.Rendering;
using UnityEngine.UI;
#if URP_ENABLE
using UnityEngine.Rendering.Universal;
#endif
namespace Coffee.UISoftMask
{
/// <summary>
/// SoftMask.
/// </summary>
[DisallowMultipleComponent]
[ExecuteAlways]
[Icon("Packages/com.coffee.softmask-for-ugui/Icons/SoftMaskIcon.png")]
public class SoftMask : Mask, ISoftMasking, IMaskable, IMaskingShapeContainerOwner, ISerializationCallbackReceiver
{
/// <summary>
/// Down sampling rate.
/// </summary>
public enum DownSamplingRate
{
None = 0,
x1 = 1,
x2 = 2,
x4 = 4,
x8 = 8
}
/// <summary>
/// Masking mode.<br />
/// <b>SoftMasking</b>: Use soft masking.<br />
/// <b>AntiAliasing</b>: Use anti-aliasing.
/// </summary>
public enum MaskingMode
{
SoftMasking,
AntiAliasing,
Normal
}
public static Action<SoftMask> onRenderSoftMaskBuffer = null;
private static readonly Camera.MonoOrStereoscopicEye[] s_MonoEyes = { Camera.MonoOrStereoscopicEye.Mono };
private static readonly Camera.MonoOrStereoscopicEye[] s_StereoEyes =
{ Camera.MonoOrStereoscopicEye.Left, Camera.MonoOrStereoscopicEye.Right };
[Tooltip("Masking mode.\n\n" +
"SoftMasking: Use RenderTexture as a soft mask buffer. The alpha of the masking graphic can be used.\n" +
"AntiAliasing: Suppress the jaggedness of the masking graphic. The masking graphic cannot be displayed.\n" +
"Normal: Same as Mask component's stencil mask.")]
[SerializeField]
private MaskingMode m_MaskingMode = MaskingMode.SoftMasking;
[Tooltip("The transparent part of the mask cannot be clicked.\n" +
"This can be achieved by enabling Read/Write enabled in the Texture Import Settings for the texture.\n\n" +
"NOTE: Enable this only if necessary, as it will require more graphics memory and processing time.")]
[SerializeField]
private bool m_AlphaHitTest;
[Tooltip("The minimum and maximum alpha values used for soft masking.\n" +
"The larger the gap between these values, the stronger the softness effect.")]
[SerializeField]
private MinMax01 m_SoftnessRange = new MinMax01(0, 1f);
[Tooltip("The down sampling rate for soft mask buffer.\n" +
"The higher this value, the lower the quality of the soft masking, but the performance will improve.")]
[SerializeField]
private DownSamplingRate m_DownSamplingRate = DownSamplingRate.x1;
[Tooltip("The threshold for anti-alias masking.\n" +
"The smaller this value, the less jagged it is.")]
[SerializeField]
[Range(0f, 1f)]
private float m_AntiAliasingThreshold;
[SerializeField]
[Obsolete]
internal float m_Alpha = -1;
[SerializeField]
[Obsolete]
internal float m_Softness = -1;
[SerializeField]
[Obsolete]
private bool m_PartOfParent;
private CanvasGroup _canvasGroup;
private CommandBuffer _cb;
private List<SoftMask> _children;
private bool _hasResolutionChanged;
private bool _hasSoftMaskBufferDrawn;
private Mesh _mesh;
private MaterialPropertyBlock _mpb;
private Action _onBeforeCanvasRebuild;
private Action _onCanvasViewChanged;
private SoftMask _parent;
private Matrix4x4 _prevTransformMatrix;
private Action _renderSoftMaskBuffer;
private Canvas _rootCanvas;
private UnityAction _setSoftMaskDirty;
private MaskingShapeContainer _shapeContainer;
internal RenderTexture _softMaskBuffer;
private UnityAction _updateParentSoftMask;
private CanvasViewChangeTrigger _viewChangeTrigger;
private List<SoftMask> children =>
_children != null ? _children : _children = InternalListPool<SoftMask>.Rent();
public MaskingShape.MaskingMethod maskingMethod => MaskingShape.MaskingMethod.Additive;
public MaskingShape.RaycastMethod raycastMethod => MaskingShape.RaycastMethod.Additive;
/// <summary>
/// Masking mode.<br />
/// <b>SoftMasking</b>: Use RenderTexture as a soft mask buffer. The alpha of the masking graphic can be used.<br />
/// <b>AntiAliasing</b>: Suppress the jaggedness of the masking graphic. The masking graphic cannot be displayed.<br />
/// <b>Normal</b>: Same as Mask component's stencil mask.
/// </summary>
public MaskingMode maskingMode
{
get => m_MaskingMode;
set
{
if (m_MaskingMode == value) return;
m_MaskingMode = value;
AddSoftMaskableOnChildren();
UpdateAntiAlias();
SetDirtyAndNotify();
if (graphic)
{
graphic.SetMaterialDirty();
}
}
}
public DownSamplingRate downSamplingRate
{
get => m_DownSamplingRate;
set
{
if (m_DownSamplingRate == value) return;
m_DownSamplingRate = value;
SetDirtyAndNotify();
}
}
/// <summary>
/// Threshold for anti-alias masking.
/// The smaller this value, the less jagged it is.
/// </summary>
public float antiAliasingThreshold
{
get => m_AntiAliasingThreshold;
set => m_AntiAliasingThreshold = value;
}
/// <summary>
/// The transparent part of the mask cannot be clicked.
/// This can be achieved by enabling Read/Write enabled in the Texture Import Settings for the texture.
/// <para></para>
/// NOTE: Enable this only if necessary, as it will require more graphics memory and processing time.
/// </summary>
public bool alphaHitTest
{
get => m_AlphaHitTest;
set => m_AlphaHitTest = value;
}
/// <summary>
/// The soft mask depth.
/// </summary>
public int softMaskDepth
{
get
{
var depth = -1;
for (var current = this; current; current = current._parent)
{
if (current.SoftMaskingEnabled())
{
depth++;
}
}
return depth;
}
}
/// <summary>
/// Is the soft mask a part of parent soft mask?
/// </summary>
[Obsolete("Use MaskingShape component instead.", false)]
public bool partOfParent
{
get => m_PartOfParent;
set => m_PartOfParent = value;
}
/// <summary>
/// The value used by the soft mask to select the area of influence defined over the soft mask's graphic.
/// </summary>
[Obsolete("Use softnessRange instead.", false)]
public float softness
{
get => softnessRange.max;
set
{
softnessRange = new MinMax01(0, Mathf.Clamp01(value));
m_Softness = -1;
}
}
public bool hasSoftMaskBuffer => _softMaskBuffer;
/// <summary>
/// The soft mask buffer.
/// </summary>
public RenderTexture softMaskBuffer
{
get
{
if (SoftMaskingEnabled())
{
var size = RenderTextureRepository.GetScreenSize((int)downSamplingRate);
var hash = new Hash128((uint)GetInstanceID(), (uint)size.x, (uint)size.y, 0);
if (!RenderTextureRepository.Valid(hash, _softMaskBuffer))
{
RenderTextureRepository.Get(hash, ref _softMaskBuffer,
x => new RenderTexture(RenderTextureRepository.GetDescriptor(x, false))
{
hideFlags = HideFlags.DontSave
}, size);
}
return _softMaskBuffer;
}
RenderTextureRepository.Release(ref _softMaskBuffer);
return null;
}
}
/// <summary>
/// The minimum and maximum alpha values used for soft masking.
/// The larger the gap between these values, the stronger the softness effect.
/// </summary>
public MinMax01 softnessRange
{
get => m_SoftnessRange;
set
{
if (m_SoftnessRange.Approximately(value)) return;
m_SoftnessRange = value;
SetSoftMaskDirty();
}
}
/// <summary>
/// Clear color for the soft mask buffer.
/// </summary>
public Color clearColor
{
get;
set;
}
public bool isDirty
{
get;
private set;
}
public bool allowRenderScale
{
get
{
#if URP_ENABLE
if (_rootCanvas
&& _rootCanvas.renderMode != RenderMode.ScreenSpaceOverlay
&& _rootCanvas.worldCamera
&& GraphicsSettings.currentRenderPipeline is UniversalRenderPipelineAsset)
{
return true;
}
#endif
return false;
}
}
public bool allowDynamicResolution
{
get
{
var isSupported =
#if UNITY_XBOXONE || UNITY_PS5 || UNITY_PS4 || UNITY_SWITCH || UNITY_IOS || UNITY_EDITOR_WIN || UNITY_STANDALONE_WIN
true;
#elif UNITY_EDITOR_OSX || UNITY_STANDALONE_OSX || UNITY_TVOS
SystemInfo.graphicsDeviceType == GraphicsDeviceType.Metal;
#elif UNITY_ANDROID
SystemInfo.graphicsDeviceType == GraphicsDeviceType.Vulkan;
#elif UNITY_WSA
SystemInfo.graphicsDeviceType == GraphicsDeviceType.Direct3D12;
#else
false;
#endif
return isSupported
&& _rootCanvas
&& _rootCanvas.renderMode != RenderMode.ScreenSpaceOverlay
&& _rootCanvas.worldCamera
&& _rootCanvas.worldCamera.allowDynamicResolution;
}
}
/// <summary>
/// Called when the component is enabled.
/// </summary>
protected override void OnEnable()
{
UIExtraCallbacks.onBeforeCanvasRebuild +=
_onBeforeCanvasRebuild ?? (_onBeforeCanvasRebuild = OnBeforeCanvasRebuild);
UIExtraCallbacks.onAfterCanvasRebuild +=
_renderSoftMaskBuffer ?? (_renderSoftMaskBuffer = RenderSoftMaskBuffer);
if (graphic)
{
graphic.RegisterDirtyMaterialCallback(
_updateParentSoftMask ?? (_updateParentSoftMask = UpdateParentSoftMask));
graphic.RegisterDirtyVerticesCallback(
_setSoftMaskDirty ?? (_setSoftMaskDirty = SetSoftMaskDirty));
graphic.SetVerticesDirty();
}
AddSoftMaskableOnChildren();
OnCanvasHierarchyChanged();
_shapeContainer = GetComponent<MaskingShapeContainer>();
base.OnEnable();
}
/// <summary>
/// Called when the component is disabled.
/// </summary>
protected override void OnDisable()
{
UIExtraCallbacks.onBeforeCanvasRebuild -=
_onBeforeCanvasRebuild ?? (_onBeforeCanvasRebuild = OnBeforeCanvasRebuild);
UIExtraCallbacks.onAfterCanvasRebuild -=
_renderSoftMaskBuffer ?? (_renderSoftMaskBuffer = RenderSoftMaskBuffer);
if (graphic)
{
graphic.UnregisterDirtyMaterialCallback(
_updateParentSoftMask ?? (_updateParentSoftMask = UpdateParentSoftMask));
graphic.UnregisterDirtyVerticesCallback(
_setSoftMaskDirty ?? (_setSoftMaskDirty = SetSoftMaskDirty));
graphic.SetVerticesDirty();
}
UpdateParentSoftMask(null);
children.Clear();
MeshExtensions.Return(ref _mesh);
SoftMaskUtils.materialPropertyBlockPool.Return(ref _mpb);
SoftMaskUtils.commandBufferPool.Return(ref _cb);
RenderTextureRepository.Release(ref _softMaskBuffer);
UpdateCanvasViewChangeTrigger(null);
_rootCanvas = null;
_shapeContainer = null;
UpdateAntiAlias();
base.OnDisable();
}
protected override void OnDestroy()
{
InternalListPool<SoftMask>.Return(ref _children);
_onBeforeCanvasRebuild = null;
_renderSoftMaskBuffer = null;
_setSoftMaskDirty = null;
_onCanvasViewChanged = null;
_updateParentSoftMask = null;
}
/// <summary>
/// Called when the state of the parent Canvas is changed.
/// </summary>
protected override void OnCanvasHierarchyChanged()
{
if (!isActiveAndEnabled) return;
_rootCanvas = this.GetRootComponent<Canvas>();
UpdateCanvasViewChangeTrigger(null);
}
/// <summary>
/// Call from unity if animation properties have changed.
/// </summary>
protected override void OnDidApplyAnimationProperties()
{
SetSoftMaskDirty();
}
/// <summary>
/// This callback is called if an associated RectTransform has its dimensions changed. The call is also made to all child
/// rect transforms, even if the child transform itself doesn't change - as it could have, depending on its anchoring.
/// </summary>
protected override void OnRectTransformDimensionsChange()
{
SetDirtyAndNotifyIfBufferSizeChanged();
}
protected void OnTransformChildrenChanged()
{
AddSoftMaskableOnChildren();
}
protected override void OnTransformParentChanged()
{
UpdateParentSoftMask();
UpdateCanvasViewChangeTrigger(CanvasViewChangeTrigger.Find(transform));
}
#if UNITY_EDITOR
protected override void OnValidate()
{
base.OnValidate();
AddSoftMaskableOnChildren();
SetSoftMaskDirty();
UpdateAntiAlias();
if (graphic)
{
graphic.SetVerticesDirty();
}
var list = InternalListPool<IMaskable>.Rent();
GetComponents(list);
for (var i = 0; i < list.Count; i++)
{
if (list[i] == null) continue;
list[i].RecalculateMasking();
}
InternalListPool<IMaskable>.Return(ref list);
}
#endif
void IMaskable.RecalculateMasking()
{
SetSoftMaskDirty();
if (!SoftMaskingEnabled() && _softMaskBuffer)
{
RenderTextureRepository.Release(ref _softMaskBuffer);
}
}
void IMaskingShapeContainerOwner.Register(MaskingShapeContainer container)
{
_shapeContainer = container;
}
void IMeshModifier.ModifyMesh(Mesh mesh)
{
if (!mesh || !SoftMaskingEnabled())
{
MeshExtensions.Return(ref _mesh);
return;
}
mesh.CopyTo(_mesh ? _mesh : _mesh = MeshExtensions.Rent());
}
void IMeshModifier.ModifyMesh(VertexHelper verts)
{
if (!SoftMaskingEnabled())
{
MeshExtensions.Return(ref _mesh);
return;
}
verts.CopyTo(_mesh ? _mesh : _mesh = MeshExtensions.Rent());
}
private void SetDirtyAndNotifyIfBufferSizeChanged()
{
if (!SoftMaskingEnabled() || !_softMaskBuffer) return;
Logging.Log(this, "SetDirtyAndNotifyIfBufferSizeChanged");
var size = RenderTextureRepository.GetScreenSize((int)downSamplingRate);
var hash = new Hash128((uint)GetInstanceID(), (uint)size.x, (uint)size.y, 0);
if (RenderTextureRepository.Valid(hash, _softMaskBuffer)) return;
// If the size of the soft mask buffer is changed, reset the SoftMaskable.
SetDirtyAndNotify();
}
private void AddSoftMaskableOnChildren()
{
if (!SoftMaskingEnabled()) return;
SoftMaskUtils.AddSoftMaskableOnChildren(this, true);
}
private void OnBeforeCanvasRebuild()
{
switch (maskingMode)
{
// SoftMasking mode: If transform or view has changed, set dirty flag.
case MaskingMode.SoftMasking:
{
if (transform.HasChanged(ref _prevTransformMatrix, UISoftMaskProjectSettings.transformSensitivity))
{
SetSoftMaskDirty();
}
if (!_viewChangeTrigger && _rootCanvas)
{
UpdateCanvasViewChangeTrigger(CanvasViewChangeTrigger.Find(transform));
SetSoftMaskDirty();
}
break;
}
// AntiAliasing mode: Update anti-aliasing for graphic.
case MaskingMode.AntiAliasing:
{
if (!this || !graphic) return;
Utils.UpdateAntiAlias(graphic, isActiveAndEnabled, antiAliasingThreshold);
break;
}
}
}
private void UpdateCanvasViewChangeTrigger(CanvasViewChangeTrigger trigger)
{
if (_viewChangeTrigger != trigger)
{
Logging.Log(this, $"UpdateCanvasViewChangeTrigger: {_viewChangeTrigger} -> {trigger}");
if (_viewChangeTrigger)
{
_viewChangeTrigger.onCanvasViewChanged -=
_onCanvasViewChanged ?? (_onCanvasViewChanged = OnCanvasViewChanged);
}
if (trigger)
{
trigger.onCanvasViewChanged +=
_onCanvasViewChanged ?? (_onCanvasViewChanged = OnCanvasViewChanged);
}
}
_viewChangeTrigger = trigger;
}
public override bool IsRaycastLocationValid(Vector2 sp, Camera eventCamera)
{
if (FrameCache.TryGet(this, nameof(IsRaycastLocationValid), out bool valid))
{
return valid;
}
if (!isActiveAndEnabled)
{
FrameCache.Set(this, nameof(IsRaycastLocationValid), true);
return true;
}
// Check parent
if (_parent && !_parent.IsRaycastLocationValid(sp, eventCamera))
{
FrameCache.Set(this, nameof(IsRaycastLocationValid), false);
return false;
}
Profiler.BeginSample("(SM4UI)[SoftMask] IsRaycastLocationValid > Base");
valid = base.IsRaycastLocationValid(sp, eventCamera);
Profiler.EndSample();
if (!SoftMaskingEnabled())
{
FrameCache.Set(this, nameof(IsRaycastLocationValid), valid);
return valid;
}
if (valid && alphaHitTest)
{
Profiler.BeginSample("(SM4UI)[SoftMask] IsRaycastLocationValid > Alpha hit test");
valid = Utils.AlphaHitTestValid(graphic, sp, eventCamera, 0.01f);
Profiler.EndSample();
}
if (_shapeContainer)
{
Profiler.BeginSample("(SM4UI)[SoftMask] IsRaycastLocationValid > Shapes");
valid = _shapeContainer.IsInside(sp, eventCamera, valid, 0.5f);
Profiler.EndSample();
}
FrameCache.Set(this, nameof(IsRaycastLocationValid), valid);
return valid;
}
public override Material GetModifiedMaterial(Material baseMaterial)
{
if (!isActiveAndEnabled || !graphic || !graphic.canvas) return baseMaterial;
return base.GetModifiedMaterial(baseMaterial);
}
private void SetDirtyAndNotify()
{
if (!this || !isActiveAndEnabled) return;
SetSoftMaskDirty();
MaskUtilities.NotifyStencilStateChanged(this);
}
private void OnCanvasViewChanged()
{
_hasResolutionChanged = true;
SetDirtyAndNotify();
Misc.QueuePlayerLoopUpdate();
#if UNITY_EDITOR
EditorApplication.delayCall += () =>
{
if (!this || !isActiveAndEnabled) return;
_hasResolutionChanged = true;
SetDirtyAndNotify();
};
#endif
}
public void SetSoftMaskDirty()
{
if (isDirty || !this || !isActiveAndEnabled) return;
Logging.LogIf(!isDirty, this, $"! SetSoftMaskDirty {GetInstanceID()}");
isDirty = true;
for (var i = children.Count - 1; i >= 0; i--)
{
if (children[i])
{
children[i].SetSoftMaskDirty();
}
else
{
children.RemoveAt(i);
}
}
}
public bool SoftMaskingEnabled()
{
return GetActualMaskingMode() == MaskingMode.SoftMasking && MaskEnabled();
}
public bool AntiAliasingEnabled()
{
return GetActualMaskingMode() == MaskingMode.AntiAliasing && MaskEnabled();
}
internal MaskingMode GetActualMaskingMode()
{
return maskingMode == MaskingMode.Normal
? MaskingMode.Normal
: UISoftMaskProjectSettings.softMaskEnabled && maskingMode == MaskingMode.SoftMasking
? MaskingMode.SoftMasking
: MaskingMode.AntiAliasing;
}
private void UpdateParentSoftMask()
{
if (SoftMaskingEnabled())
{
var stopAfter = MaskUtilities.FindRootSortOverrideCanvas(transform);
var parentSoftMask =
transform.GetComponentInParent<SoftMask>(false, stopAfter, x => x.SoftMaskingEnabled());
UpdateParentSoftMask(parentSoftMask);
}
else
{
UpdateParentSoftMask(null);
}
}
private void UpdateParentSoftMask(SoftMask newParent)
{
if (_parent && _parent.children.Contains(this))
{
_parent.children.Remove(this);
}
if (newParent && !newParent.children.Contains(this))
{
newParent.children.Add(this);
}
if (_parent != newParent)
{
SetSoftMaskDirty();
}
_parent = newParent;
}
private void UpdateAntiAlias()
{
var useAA = isActiveAndEnabled && maskingMode == MaskingMode.AntiAliasing;
Utils.UpdateAntiAlias(graphic, useAA, antiAliasingThreshold);
}
private bool IsInScreen()
{
if (graphic && graphic.IsInScreen()) return true;
if (_shapeContainer && _shapeContainer.IsInScreen()) return true;
return false;
}
private void RenderSoftMaskBuffer()
{
if (!SoftMaskingEnabled() || !graphic || !graphic.canvas) return;
if (FrameCache.TryGet(this, nameof(RenderSoftMaskBuffer), out bool _)) return;
FrameCache.Set(this, nameof(RenderSoftMaskBuffer), true);
if (!isDirty) return;
isDirty = false;
if (_parent)
{
_parent.RenderSoftMaskBuffer();
}
var depth = softMaskDepth;
if (depth < 0 || 4 <= depth) return;
if (_cb == null)
{
Profiler.BeginSample("(SM4UI)[SoftMask] RenderSoftMaskBuffer > Rent cb");
_cb = SoftMaskUtils.commandBufferPool.Rent();
_cb.name = "[SoftMask] SoftMaskBuffer";
Profiler.EndSample();
}
if (_mpb == null)
{
Profiler.BeginSample("(SM4UI)[SoftMask] RenderSoftMaskBuffer > Rent mpb");
_mpb = SoftMaskUtils.materialPropertyBlockPool.Rent();
_mpb.Clear();
Profiler.EndSample();
}
if (!IsInScreen())
{
if (_hasSoftMaskBufferDrawn || _hasResolutionChanged)
{
Profiler.BeginSample("(SM4UI)[SoftMask] RenderSoftMaskBuffer > Clear");
_cb.Clear();
_cb.SetRenderTarget(softMaskBuffer);
_cb.ClearRenderTarget(true, true, clearColor);
Graphics.ExecuteCommandBuffer(_cb);
Profiler.EndSample();
}
_hasSoftMaskBufferDrawn = false;
_hasResolutionChanged = false;
return;
}
Profiler.BeginSample("(SM4UI)[SoftMask] RenderSoftMaskBuffer > Init command buffer");
_cb.Clear();
_cb.SetRenderTarget(softMaskBuffer);
if (softMaskDepth == 0 || _hasResolutionChanged)
{
_cb.ClearRenderTarget(true, true, clearColor);
}
Profiler.EndSample();
var eyes = UISoftMaskProjectSettings.stereoEnabled && graphic.canvas.IsStereoCanvas()
? s_StereoEyes
: s_MonoEyes;
for (var i = 0; i < eyes.Length; i++)
{
RenderSoftMaskBuffer(_cb, eyes[i]);
}
{
Profiler.BeginSample("(SM4UI)[SoftMask] RenderSoftMaskBuffer > Execute command buffer");
Graphics.ExecuteCommandBuffer(_cb);
_hasSoftMaskBufferDrawn = true;
_hasResolutionChanged = false;
Logging.Log(this, $" >>>> SoftMaskBuffer '{softMaskBuffer.name}' will render.");
Profiler.EndSample();
}
Misc.QueuePlayerLoopUpdate();
onRenderSoftMaskBuffer?.Invoke(this);
}
private void RenderSoftMaskBuffer(CommandBuffer cb, Camera.MonoOrStereoscopicEye eye)
{
if (_hasResolutionChanged)
{
var p = _parent;
while (p)
{
p.RenderSoftMaskBuffer(cb, eye);
p = p._parent;
}
}
{
Profiler.BeginSample("(SM4UI)[SoftMask] RenderSoftMaskBuffer > SetVpMatricesCommandBuffer");
graphic.canvas.rootCanvas.GetViewProjectionMatrix(eye, out var viewMatrix, out var projectionMatrix);
cb.SetViewProjectionMatrices(viewMatrix, projectionMatrix);
Profiler.EndSample();
Profiler.BeginSample("(SM4UI)[SoftMask] RenderSoftMaskBuffer > ApplyMaterialPropertyBlock");
var proxy = GraphicProxy.Find(graphic);
var texture = proxy.GetMainTexture(graphic);
var alpha = proxy.GetAlpha(graphic);
SoftMaskUtils.ApplyMaterialPropertyBlock(_mpb, softMaskDepth, texture, softnessRange, alpha);
Profiler.EndSample();
}
if (!_hasResolutionChanged && eye != Camera.MonoOrStereoscopicEye.Right && _parent)
{
Profiler.BeginSample("(SM4UI)[SoftMask] RenderSoftMaskBuffer > Copy texture from parent");
if (_parent.softMaskBuffer)
{
_cb.Blit(_parent.softMaskBuffer, softMaskBuffer);
}
Profiler.EndSample();
}
if (eye != Camera.MonoOrStereoscopicEye.Mono)
{
Profiler.BeginSample("(SM4UI)[SoftMask] RenderSoftMaskBuffer > Set viewport");
var w = softMaskBuffer.width * 0.5f;
var h = softMaskBuffer.height;
cb.SetViewport(new Rect(w * (int)eye, 0f, w, h));
Profiler.EndSample();
}
var mesh = _mesh;
if (mesh)
{
Profiler.BeginSample("(SM4UI)[SoftMask] RenderSoftMaskBuffer > Draw mesh");
var softMaterial = SoftMaskUtils.GetSoftMaskingMaterial(MaskingShape.MaskingMethod.Additive);
cb.DrawMesh(mesh, transform.localToWorldMatrix, softMaterial, 0, 0, _mpb);
Profiler.EndSample();
}
if (_shapeContainer)
{
Profiler.BeginSample("(SM4UI)[SoftMask] RenderSoftMaskBuffer > Draw shapes");
_shapeContainer.DrawSoftMaskBuffer(cb, softMaskDepth);
Profiler.EndSample();
}
}
void ISerializationCallbackReceiver.OnBeforeSerialize()
{
}
void ISerializationCallbackReceiver.OnAfterDeserialize()
{
#pragma warning disable CS0612, CS0618 // Type or member is obsolete
if (0 <= m_Softness)
{
m_SoftnessRange = new MinMax01(0, Mathf.Clamp01(m_Softness));
m_Softness = -1;
}
if (m_PartOfParent)
{
Debug.LogWarning(
$"[SoftMask] The 'partOfParent' property is obsolete. Use MaskingShape component instead.", this);
}
#pragma warning restore CS0612, CS0618 // Type or member is obsolete
}
}
}