技术美术TA之UI材质

本文是视频课程《Unity技术美术TA:Shader篇》,算是对自己学习的总结,也希望分享下所学知识~~
(原课程链接传送门

模板测试是什么?
模板缓冲区,帧缓存中的一个缓冲区
存储的是像素的模板值,存储的是 8bit = 256 个值
默认值=0
如果把一块区域绘制为1,其他区域设置和1进行比较,选择到底是否绘制

UI中的遮罩实现方式
1.Mask:模板测试 Stencil

Properties
{
	//加了就看不见了,Unity会自动读取UI上的图片
	[PerRendererData] _MainTex ("Texture", 2D) = "white" {}
	
	//UI 里面改的是顶点色,不是直接定义 Color
	//[PerRendererData] _Color("Color", color) = (1,1,1,1)
	
	//想让 UNITY 自动设置,就需要改成默认名称
	_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

SubShader
{
    Tags
    {
        "Queue"="Transparent"
    }
    //AlphaBlend 效果
    Blend SrcAlpha OneMinusSrcAlpha
    Cull Off

	//Stencil
	Stencil
	{
	    //设定的参考值,这个值将用来与模板缓冲中的值进行比较.取值范围位为0-255的整数.
	    Ref [_Stencil]
	    //定义Ref与模板缓冲中的值比较的操作函数,默认值为always.
	    Comp [_StencilComp]
	    //当模板测试(和深度测试)通过时,则根据(stencilOperation值)对模板缓冲值进行处理,默认值为keep.
	    Pass [_StencilOp]
	    //模板缓冲中的值进行按位与(&)操作
	    ReadMask [_StencilReadMask]
	    WriteMask [_StencilWriteMask]
	}


//片断着色器里面接受顶点色数据 *=
fixed4 frag(v2f i) : SV_Target
{
    fixed4 c;
    fixed4 col = tex2D(_MainTex, i.uv);
    c = col;
    c *= i.color;
    return c;
}

2.RectMask2D:UNITY_UI_CLIP_RECT
计算的位置,设置 a 值

//先定义变体
#pragma multi_compile _ UNITY_UI_CLIP_RECT

// UNITY_UI_CLIP_RECT 声明后,需要声明这个
//      表示 RectMask2D 左上角的xy坐标与右上角的xy坐标
fixed4 _ClipRect;

//顶点着色器 拿到屏幕坐标
v2f vert(appdata v)
{
    v2f o;
    o.pos = UnityObjectToClipPos(v.vertex);
    o.uv = TRANSFORM_TEX(v.uv, _MainTex);
    o.color = v.color;
    
    //传到片段着色器经过差值之后,就自动转换成了屏幕坐标
    //			注意 UGUI 中间是 (0, 0)
    o.vertex = v.vertex;
    return o;
}

//片断着色器 计算位置是否在 Rect2DMask 里面
fixed4 frag(v2f i) : SV_Target
{
    fixed4 c;
    fixed4 col = tex2D(_MainTex, i.uv);
    c = col;
    c *= i.color;
    
    //放到 Rect2DMask 下面 自动就走到这个宏里,Unity 会控制宏的开关
    #if UNITY_UI_CLIP_RECT
    //
    // 尽量不用 if,性能很差
    // if ( i.vertex.x < _ClipRect.x
    //     || i.vertex.x > _ClipRect.z
    //     || i.vertex.y < _ClipRect.y
    //     || i.vertex.y > _ClipRect.w)
    // {
    //     c.a = 0;
    // }
    //
    // step(a,b) a < b 就是1,否则是0
    // fixed step1 = step(_ClipRect.x, i.vertex.x);
    // fixed step2 = step(i.vertex.x, _ClipRect.z);
    // fixed step3 = step(_ClipRect.y, i.vertex.y);
    // fixed step4 = step(i.vertex.y, _ClipRect.w);
    //
    // c.a *= step1 * step2 * step3 * step4;
    // step 也可以直接算多维向量
    // fixed2 step1 = step(_ClipRect.xy, i.vertex.xy);
    // fixed2 step2 = step(i.vertex.xy, _ClipRect.zw);
    //
    // c.a *= step1.x * step1.y * step2.x * step2.y;
    //
    // Unity 封装好了内置函数
    c.a *= UnityGet2DClipping(i. vertex, _ClipRect);
    
    #endif
    return c;
}

ColorMask 是啥?

	//颜色遮罩,默认值为:RGBA,表示写入RGBA四个通道。
	// 0 代表不输出任何颜色
	ColorMask [_ColorMask]

UI置灰效果如何实现?
1.换图
2.写Shader

fixed4 frag(v2f i) : SV_Target
{
    fixed4 c;
    fixed4 col = tex2D(_MainTex, i.uv);
    c = col;
    c *= i.color;
    
    #if _GRAYENABLED_ON
    //
    //要求不高可以直接用 一个通道
    // c.rgb = c.r;
    //
    //标准去色公式
    // c.rgb = c.r * 0.22 +c.g * 0.707 + c.b * 0.071;
    //
    //内置方法
    c.rgb = Luminance(c.rgb);
    
    #endif
    return c;
}
ENDCG

UI流光效果如何实现?
1.采样一张流光贴图
2.不采样,自己计算,代码如下


// 只定义三个属性
_Color("Color", color) = (1,1,1,0)
_Interval("Interval", float) = 2
_Width("Width", Range(0,1)) = 0.2

//片断着色器内部代码
fixed4 frag(v2f i) : SV_Target
{
    fixed4 c;
    fixed4 col = tex2D(_MainTex, i.uv);
    c = col;
    
    float x = i.uv.x;
    float y = i.uv.y;
    
    //根据时间计算当前偏移
    int count = floor(_Time.y / _Interval);
    float remain = _Time.y - count * _Interval;
    fixed offset = remain / _Interval * 2 - 1;
    
    //正比例函数,offset是偏移
    float fy = x - offset;
    
    //求到中点的 a 过度值
    float middle = abs(fy - y);
    float middlePct = middle / (_Width / 2);
    fixed3 middleColor = lerp(_Color.rgb, fixed3(0, 0, 0), middlePct);
    
    //限制在两边之间
    float rightPct = step(fy - _Width / 2, y);
    float leftPct = step(fy + _Width / 2, y);
    
    //叠加颜色
    c.rgb += middleColor.rgb * 1 * (rightPct - leftPct);
    
    return c;
}

效果如图:

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值