使用透明度实现Mask遮罩的Unity Shader

【使用透明度实现Mask遮罩的Unity Shader】 原创文章,转载请注明出处使用透明度实现Mask遮罩的Unity Shader

你好,用你的shader后在pc编辑器上是没有问题的,在5.4环境下打包到手机上也没问题,但是升级到5.5后打包到手机(ios,android的还没试)上就显示为粉红色,不知道博主有没有解决方案
感谢提醒,有时间我会修正一下
关于遮罩的需求 将矩形的图片做成圆角矩形、圆形
常用实现方式
  1. 使用UGUI自带的Mask组件实现
  2. 使用网上一搜一大把的简单切割shader实现
存在的问题 这些实现方案容易出现锯齿问题,见下图
使用透明度实现Mask遮罩的Unity Shader
文章图片

常见实现方案的锯齿 锯齿的由来 由于屏幕都是像素化的,所以看似圆滑的曲线,在屏幕上其实都是有锯齿的,但由于人眼的识别能力有限,所以当锯齿小到一定程度的时候就会认为曲线是圆滑的。
然而,由于分辨率问题,我们很难做到锯齿足够小,所以需要在产生锯齿的边缘添加颜色过渡,避免明显的分界线,从而使人眼忽略锯齿问题。
现有方案的锯齿原因 由于现有方案是简单的判断遮罩的边界:
  1. UGUI的Mask组件是通过透明度判断,如果遮罩某像素点透明度达到一个值,则该像素点对应的颜色透明度不变,否则透明度置为0 ,使用遮罩的透明度作为掩码写入缓冲区,之后只渲染缓冲区为1的区域。
    以下为官方文档说明Implementation Masking is implemented using the stencil buffer of the GPU.
    The first Mask element writes a 1 to the stencil buffer
    All elements below the mask check when rendering, and only render to areas where there is a 1 in the stencil buffer
    Nested Masks will write incremental bit masks into the buffer, this means that renderable children need to have the logical & of the stencil values to be rendered.
  2. 简单切割shader的实现是通过边缘检测来判断该点是否显示,不显示则透明度置为0
发现了吗,这些方案都是非黑即白的的方案,根本实现不了颜色过渡,所以存在锯齿的现象
解决方案 我给出的方案是使用透明度叠加来做
1.制作一张PS做的带透明度过渡的遮罩
2.编写shader,获取这张遮罩的透明度,将该透明度和目标图片的透明度进行混合
效果 使用透明度实现Mask遮罩的Unity Shader
文章图片

使用遮罩前 使用透明度实现Mask遮罩的Unity Shader
文章图片

制作材质球 使用透明度实现Mask遮罩的Unity Shader
文章图片

添加材质球 使用透明度实现Mask遮罩的Unity Shader
文章图片

使用遮罩后 使用透明度实现Mask遮罩的Unity Shader
文章图片

其他形状的遮罩 shader代码
Shader "ImageEffect/MaskIcon" { Properties { [PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {} _Mask ("Base (RGB)", 2D) = "white" {}_Color ("Tint", Color) = (1,1,1,1) _StencilComp ("Stencil Comparison", Float) = 8 _Stencil ("Stencil ID", Float) = 0 _StencilOp ("Stencil Operation", Float) = 0 _StencilWriteMask ("Stencil Write Mask", Float) = 255 _StencilReadMask ("Stencil Read Mask", Float) = 255 _ColorMask ("Color Mask", Float) = 15 [Toggle(UNITY_UI_ALPHACLIP)] _UseUIAlphaClip ("Use Alpha Clip", Float) = 0 }SubShader { Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" "PreviewType"="Plane" "CanUseSpriteAtlas"="True" }Stencil { Ref [_Stencil] Comp [_StencilComp] Pass [_StencilOp] ReadMask [_StencilReadMask] WriteMask [_StencilWriteMask] }Cull Off Lighting Off ZWrite Off ZTest [unity_GUIZTestMode] Blend SrcAlpha OneMinusSrcAlpha ColorMask [_ColorMask]Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag#include "UnityCG.cginc" #include "UnityUI.cginc"#pragma multi_compile __ UNITY_UI_ALPHACLIPstruct a2v { fixed2 uv : TEXCOORD0; half4 vertex : POSITION; float4 color: COLOR; }; fixed4 _Color; struct v2f { fixed2 uv : TEXCOORD0; half4 vertex : SV_POSITION; float4 color: COLOR; }; sampler2D _MainTex; sampler2D _Mask; v2f vert (a2v i) { v2f o; o.vertex = mul(UNITY_MATRIX_MVP, i.vertex); o.uv = i.uv; o.color = i.color * _Color; return o; }fixed4 frag (v2f i) : COLOR { half4 color = tex2D(_MainTex, i.uv) * i.color; half4 mask = tex2D(_Mask, i.uv); color.a *= mask.a; return color; } ENDCG } } }

    推荐阅读