internal void _PreUpdateMask(UpdateContext context, uint maskId) { //_maskFlag: 0-new mask, 1-active mask, 2-mask complete if (_maskFlag == 0) { if (_stencilEraser == null) { _stencilEraser = new StencilEraser(gameObject.transform); _stencilEraser.meshFilter.mesh = mesh; } else { _stencilEraser.enabled = true; } } _maskFlag = 1; if (_manager != null) { //这里使用maskId而不是clipInfo.clipId,是因为遮罩有两个用途,一个是写入遮罩,一个是擦除,两个不能用同一个材质 Material mat = _manager.GetMaterial((int)MaterialFlags.AlphaMask + _materialFlags, BlendMode.Normal, maskId); if (!Material.ReferenceEquals(mat, _stencilEraser.meshRenderer.sharedMaterial)) { _stencilEraser.meshRenderer.sharedMaterial = mat; } context.ApplyAlphaMaskProperties(mat, true); } }
/// <summary> /// /// </summary> public void Dispose() { if (mesh != null) { if (Application.isPlaying) { Object.Destroy(mesh); } else { Object.DestroyImmediate(mesh); } mesh = null; } if (_manager != null) { _manager.Release(); _manager = null; } _material = null; meshRenderer = null; meshFilter = null; _stencilEraser = null; meshModifier = null; }
/// <summary> /// /// </summary> public void Dispose() { if (mesh != null) { if (Application.isPlaying) { Object.Destroy(mesh); } else { Object.DestroyImmediate(mesh); } mesh = null; } if ((_customMatarial & 128) != 0 && _material != null) { Object.DestroyImmediate(_material); } _manager = null; _material = null; meshRenderer = null; meshFilter = null; _stencilEraser = null; meshModifier = null; }
public void Dispose() { if (mesh != null) { if (Application.isPlaying) { Mesh.Destroy(mesh); } else { Mesh.DestroyImmediate(mesh); } mesh = null; } if (_manager != null) { _manager.Release(); _manager = null; } if (_customMatarial && _material != null) { if (Application.isPlaying) { Material.Destroy(_material); } else { Material.DestroyImmediate(_material); } } _material = null; meshRenderer = null; meshFilter = null; _stencilEraser = null; }
internal void _SetAsMask(bool value) { if (_isMask != value) { _isMask = value; if (_isMask) { //设置擦除stencil的drawcall if (_stencilEraser == null) { _stencilEraser = new StencilEraser(gameObject.transform); _stencilEraser.meshFilter.mesh = mesh; } else { _stencilEraser.enabled = true; } } else { if (_stencilEraser != null) { _stencilEraser.enabled = false; } } } }
internal void _PreUpdateMask(UpdateContext context) { //_maskFlag: 0-new mask, 1-active mask, 2-mask complete if (_maskFlag == 0) { if (_stencilEraser == null) { _stencilEraser = new StencilEraser(gameObject.transform); _stencilEraser.meshFilter.mesh = mesh; } else { _stencilEraser.enabled = true; } } _maskFlag = 1; if (_manager != null) { NMaterial nm = _manager.GetMaterial(6, blendMode, context.clipInfo.clipId); Material mat = nm.material; if ((object)mat != (object)_stencilEraser.meshRenderer.sharedMaterial) { _stencilEraser.meshRenderer.sharedMaterial = mat; } int refValue = context.stencilReferenceValue - 1; mat.SetInt(ShaderConfig._properyIDs._StencilComp, (int)UnityEngine.Rendering.CompareFunction.Equal); mat.SetInt(ShaderConfig._properyIDs._Stencil, refValue); mat.SetInt(ShaderConfig._properyIDs._StencilOp, (int)UnityEngine.Rendering.StencilOp.Replace); mat.SetInt(ShaderConfig._properyIDs._StencilReadMask, refValue); mat.SetInt(ShaderConfig._properyIDs._ColorMask, 0); } }
public void UpdateMaterial(UpdateContext context) { NMaterial nm = null; if (_manager != null && !_customMatarial) { nm = _manager.GetMaterial(this, context); _material = nm.material; if ((object)_material != (object)meshRenderer.sharedMaterial && (object)_material.mainTexture != null) { meshRenderer.sharedMaterial = _material; } if (nm.combined) { _material.SetTexture("_AlphaTex", _manager.texture.alphaTexture.nativeTexture); } } if (maskFrameId != 0 && maskFrameId != UpdateContext.frameId) { //曾经是遮罩对象,现在不是了 if (_stencilEraser != null) { _stencilEraser.enabled = false; } } if (_material != null) { if (blendMode != BlendMode.Normal) //GetMateria已经保证了不同的blendMode会返回不同的共享材质,所以这里可以放心设置 { BlendModeUtils.Apply(_material, blendMode); } if (context.clipped) { if (maskFrameId != UpdateContext.frameId && context.rectMaskDepth > 0) //在矩形剪裁下,且不是遮罩对象 { _material.SetVector("_ClipBox", context.clipInfo.clipBox); if (context.clipInfo.soft) { _material.SetVector("_ClipSoftness", context.clipInfo.softness); } } if (context.stencilReferenceValue > 0) { if (maskFrameId == UpdateContext.frameId) //是遮罩 { if (context.stencilReferenceValue == 1) { _material.SetInt("_StencilComp", (int)UnityEngine.Rendering.CompareFunction.Always); _material.SetInt("_Stencil", 1); _material.SetInt("_StencilOp", (int)UnityEngine.Rendering.StencilOp.Replace); _material.SetInt("_StencilReadMask", 255); _material.SetInt("_ColorMask", 0); } else { _material.SetInt("_StencilComp", (int)UnityEngine.Rendering.CompareFunction.Equal); _material.SetInt("_Stencil", context.stencilReferenceValue | (context.stencilReferenceValue - 1)); _material.SetInt("_StencilOp", (int)UnityEngine.Rendering.StencilOp.Replace); _material.SetInt("_StencilReadMask", context.stencilReferenceValue - 1); _material.SetInt("_ColorMask", 0); } //设置擦除stencil的drawcall if (_stencilEraser == null) { _stencilEraser = new StencilEraser(gameObject.transform); _stencilEraser.meshFilter.mesh = mesh; } else { _stencilEraser.enabled = true; } if (nm != null) { NMaterial eraserNm = _manager.GetMaterial(this, context); eraserNm.stencilSet = true; Material eraserMat = eraserNm.material; if ((object)eraserMat != (object)_stencilEraser.meshRenderer.sharedMaterial) { _stencilEraser.meshRenderer.sharedMaterial = eraserMat; } int refValue = context.stencilReferenceValue - 1; eraserMat.SetInt("_StencilComp", (int)UnityEngine.Rendering.CompareFunction.Equal); eraserMat.SetInt("_Stencil", refValue); eraserMat.SetInt("_StencilOp", (int)UnityEngine.Rendering.StencilOp.Replace); eraserMat.SetInt("_StencilReadMask", refValue); eraserMat.SetInt("_ColorMask", 0); } } else { int refValue = context.stencilReferenceValue | (context.stencilReferenceValue - 1); _material.SetInt("_StencilComp", (int)UnityEngine.Rendering.CompareFunction.Equal); _material.SetInt("_Stencil", refValue); _material.SetInt("_StencilOp", (int)UnityEngine.Rendering.StencilOp.Keep); _material.SetInt("_StencilReadMask", refValue); _material.SetInt("_ColorMask", 15); } if (nm != null) { nm.stencilSet = true; } } else if (nm != null && nm.stencilSet) { _material.SetInt("_StencilComp", (int)UnityEngine.Rendering.CompareFunction.Always); _material.SetInt("_Stencil", 0); _material.SetInt("_StencilOp", (int)UnityEngine.Rendering.StencilOp.Keep); _material.SetInt("_StencilReadMask", 255); _material.SetInt("_ColorMask", 15); nm.stencilSet = false; } else { _material.SetInt("_StencilComp", (int)UnityEngine.Rendering.CompareFunction.Always); _material.SetInt("_Stencil", 0); _material.SetInt("_StencilOp", (int)UnityEngine.Rendering.StencilOp.Keep); _material.SetInt("_StencilReadMask", 255); _material.SetInt("_ColorMask", 15); } } } }
/// <summary> /// /// </summary> /// <param name="context"></param> public void UpdateMaterial(UpdateContext context) { Stats.GraphicsCount++; NMaterial nm = null; bool firstInstance = true; if (!_customMatarial) { if (_manager != null) { nm = _manager.GetMaterial(this, context, out firstInstance); _material = nm.material; if ((object)_material != (object)meshRenderer.sharedMaterial) { meshRenderer.sharedMaterial = _material; } } else { _material = null; if ((object)meshRenderer.sharedMaterial != null) { meshRenderer.sharedMaterial = null; } } } if (maskFrameId != 0 && maskFrameId != UpdateContext.frameId) { //曾经是遮罩对象,现在不是了 if (_stencilEraser != null) { _stencilEraser.enabled = false; } } if (firstInstance && (object)_material != null) { if (blendMode != BlendMode.Normal) //GetMateria已经保证了不同的blendMode会返回不同的共享材质,所以这里可以放心设置 { BlendModeUtils.Apply(_material, blendMode); } bool clearStencil = false; if (context.clipped) { if (maskFrameId != UpdateContext.frameId && context.rectMaskDepth > 0) //在矩形剪裁下,且不是遮罩对象 { _material.SetVector(ShaderConfig._properyIDs._ClipBox, context.clipInfo.clipBox); if (context.clipInfo.soft) { _material.SetVector(ShaderConfig._properyIDs._ClipSoftness, context.clipInfo.softness); } } if (context.stencilReferenceValue > 0) { if (maskFrameId == UpdateContext.frameId) //是遮罩 { if (context.stencilReferenceValue == 1) { _material.SetInt(ShaderConfig._properyIDs._StencilComp, (int)UnityEngine.Rendering.CompareFunction.Always); _material.SetInt(ShaderConfig._properyIDs._Stencil, 1); _material.SetInt(ShaderConfig._properyIDs._StencilOp, (int)UnityEngine.Rendering.StencilOp.Replace); _material.SetInt(ShaderConfig._properyIDs._StencilReadMask, 255); _material.SetInt(ShaderConfig._properyIDs._ColorMask, 0); } else { _material.SetInt(ShaderConfig._properyIDs._StencilComp, (int)UnityEngine.Rendering.CompareFunction.Equal); _material.SetInt(ShaderConfig._properyIDs._Stencil, context.stencilReferenceValue | (context.stencilReferenceValue - 1)); _material.SetInt(ShaderConfig._properyIDs._StencilOp, (int)UnityEngine.Rendering.StencilOp.Replace); _material.SetInt(ShaderConfig._properyIDs._StencilReadMask, context.stencilReferenceValue - 1); _material.SetInt(ShaderConfig._properyIDs._ColorMask, 0); } //设置擦除stencil的drawcall if (_stencilEraser == null) { _stencilEraser = new StencilEraser(gameObject.transform); _stencilEraser.meshFilter.mesh = mesh; } else { _stencilEraser.enabled = true; } if (nm != null) { NMaterial eraserNm = _manager.GetMaterial(this, context, out firstInstance); eraserNm.stencilSet = true; Material eraserMat = eraserNm.material; if ((object)eraserMat != (object)_stencilEraser.meshRenderer.sharedMaterial) { _stencilEraser.meshRenderer.sharedMaterial = eraserMat; } int refValue = context.stencilReferenceValue - 1; eraserMat.SetInt(ShaderConfig._properyIDs._StencilComp, (int)UnityEngine.Rendering.CompareFunction.Equal); eraserMat.SetInt(ShaderConfig._properyIDs._Stencil, refValue); eraserMat.SetInt(ShaderConfig._properyIDs._StencilOp, (int)UnityEngine.Rendering.StencilOp.Replace); eraserMat.SetInt(ShaderConfig._properyIDs._StencilReadMask, refValue); eraserMat.SetInt(ShaderConfig._properyIDs._ColorMask, 0); } } else { int refValue = context.stencilReferenceValue | (context.stencilReferenceValue - 1); if (context.clipInfo.reversedMask) { _material.SetInt(ShaderConfig._properyIDs._StencilComp, (int)UnityEngine.Rendering.CompareFunction.NotEqual); } else { _material.SetInt(ShaderConfig._properyIDs._StencilComp, (int)UnityEngine.Rendering.CompareFunction.Equal); } _material.SetInt(ShaderConfig._properyIDs._Stencil, refValue); _material.SetInt(ShaderConfig._properyIDs._StencilOp, (int)UnityEngine.Rendering.StencilOp.Keep); _material.SetInt(ShaderConfig._properyIDs._StencilReadMask, refValue); _material.SetInt(ShaderConfig._properyIDs._ColorMask, 15); } if (nm != null) { nm.stencilSet = true; } } else { clearStencil = nm == null || nm.stencilSet; } } else { clearStencil = nm == null || nm.stencilSet; } if (clearStencil) { _material.SetInt(ShaderConfig._properyIDs._StencilComp, (int)UnityEngine.Rendering.CompareFunction.Always); _material.SetInt(ShaderConfig._properyIDs._Stencil, 0); _material.SetInt(ShaderConfig._properyIDs._StencilOp, (int)UnityEngine.Rendering.StencilOp.Keep); _material.SetInt(ShaderConfig._properyIDs._StencilReadMask, 255); _material.SetInt(ShaderConfig._properyIDs._ColorMask, 15); } } }
/// <summary> /// /// </summary> /// <param name="context"></param> public void UpdateMaterial(UpdateContext context) { Stats.GraphicsCount++; NMaterial nm = null; if (_manager != null && !_customMatarial) { nm = _manager.GetMaterial(this, context); _material = nm.material; if ((object)_material != (object)meshRenderer.sharedMaterial && (object)_material.mainTexture != null) meshRenderer.sharedMaterial = _material; if (nm.combined) _material.SetTexture("_AlphaTex", _manager.texture.alphaTexture.nativeTexture); } if (maskFrameId != 0 && maskFrameId != UpdateContext.frameId) { //曾经是遮罩对象,现在不是了 if (_stencilEraser != null) _stencilEraser.enabled = false; } if (_material != null) { if (blendMode != BlendMode.Normal) //GetMateria已经保证了不同的blendMode会返回不同的共享材质,所以这里可以放心设置 BlendModeUtils.Apply(_material, blendMode); bool clearStencil = false; if (context.clipped) { if (maskFrameId != UpdateContext.frameId && context.rectMaskDepth > 0) //在矩形剪裁下,且不是遮罩对象 { _material.SetVector("_ClipBox", context.clipInfo.clipBox); if (context.clipInfo.soft) _material.SetVector("_ClipSoftness", context.clipInfo.softness); } if (context.stencilReferenceValue > 0) { if (maskFrameId == UpdateContext.frameId) //是遮罩 { if (context.stencilReferenceValue == 1) { _material.SetInt("_StencilComp", (int)UnityEngine.Rendering.CompareFunction.Always); _material.SetInt("_Stencil", 1); _material.SetInt("_StencilOp", (int)UnityEngine.Rendering.StencilOp.Replace); _material.SetInt("_StencilReadMask", 255); _material.SetInt("_ColorMask", 0); } else { _material.SetInt("_StencilComp", (int)UnityEngine.Rendering.CompareFunction.Equal); _material.SetInt("_Stencil", context.stencilReferenceValue | (context.stencilReferenceValue - 1)); _material.SetInt("_StencilOp", (int)UnityEngine.Rendering.StencilOp.Replace); _material.SetInt("_StencilReadMask", context.stencilReferenceValue - 1); _material.SetInt("_ColorMask", 0); } //设置擦除stencil的drawcall if (_stencilEraser == null) { _stencilEraser = new StencilEraser(gameObject.transform); _stencilEraser.meshFilter.mesh = mesh; } else _stencilEraser.enabled = true; if (nm != null) { NMaterial eraserNm = _manager.GetMaterial(this, context); eraserNm.stencilSet = true; Material eraserMat = eraserNm.material; if ((object)eraserMat != (object)_stencilEraser.meshRenderer.sharedMaterial) _stencilEraser.meshRenderer.sharedMaterial = eraserMat; int refValue = context.stencilReferenceValue - 1; eraserMat.SetInt("_StencilComp", (int)UnityEngine.Rendering.CompareFunction.Equal); eraserMat.SetInt("_Stencil", refValue); eraserMat.SetInt("_StencilOp", (int)UnityEngine.Rendering.StencilOp.Replace); eraserMat.SetInt("_StencilReadMask", refValue); eraserMat.SetInt("_ColorMask", 0); } } else { int refValue = context.stencilReferenceValue | (context.stencilReferenceValue - 1); _material.SetInt("_StencilComp", (int)UnityEngine.Rendering.CompareFunction.Equal); _material.SetInt("_Stencil", refValue); _material.SetInt("_StencilOp", (int)UnityEngine.Rendering.StencilOp.Keep); _material.SetInt("_StencilReadMask", refValue); _material.SetInt("_ColorMask", 15); } if (nm != null) nm.stencilSet = true; } else clearStencil = nm == null || nm.stencilSet; } else clearStencil = nm == null || nm.stencilSet; if (clearStencil) { _material.SetInt("_StencilComp", (int)UnityEngine.Rendering.CompareFunction.Always); _material.SetInt("_Stencil", 0); _material.SetInt("_StencilOp", (int)UnityEngine.Rendering.StencilOp.Keep); _material.SetInt("_StencilReadMask", 255); _material.SetInt("_ColorMask", 15); } } }
/// <summary> /// /// </summary> public void Dispose() { if (mesh != null) { if (Application.isPlaying) Mesh.Destroy(mesh); else Mesh.DestroyImmediate(mesh); mesh = null; } if (_manager != null) { _manager.Release(); _manager = null; } if (_customMatarial && _material != null) { if (Application.isPlaying) Material.Destroy(_material); else Material.DestroyImmediate(_material); } _material = null; meshRenderer = null; meshFilter = null; _stencilEraser = null; meshModifier = null; }