找回密码
 注册帐号

扫一扫,访问微社区

蓬莱仙羽 【Aladdin-Unity3D-Shader编程】之八-2D图常用的Shader效果

21
回复
2389
查看
[ 复制链接 ]
排名
916
昨日变化

38

主题

524

帖子

2790

积分

Rank: 9Rank: 9Rank: 9

UID
1261
好友
38
蛮牛币
1926
威望
0
注册时间
2013-7-31
在线时间
674 小时
最后登录
2019-10-14

专栏作家认证开发者

2019-4-11 17:58:52 显示全部楼层 阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?注册帐号

x
前言
Shader效果常用于3D模型,但2D图也有不少常用的效果,例如:圆角头像,图片灰态,边缘着色等等,下面我就依次做一个介绍。

图片灰态
效果


核心思路
在片元着色器里面对每个图元进行采样,将图元的颜色x,y,z分别乘上灰度系数然后赋值给片源颜色,就将彩色变成了灰色了。

代码
[AppleScript] 纯文本查看 复制代码
//-----------------------------------------------【Shader说明】--------------------------------------------------------
//     Shader功能:   2D图片变灰  核心思路: 采样之后的图元xyz分别各自乘以灰度系数0.299,0.518,0.184之后的值就是灰色的
//     使用语言:   Shaderlab
//     开发所用IDE版本:Unity2018.3.6 、Visual Studio 2017
//     2016年9月16日  Created by Aladdin(阿拉丁)   
//     更多内容或交流请访问我的博客:http://blog.csdn.net/s10141303/article/category/6670402
//---------------------------------------------------------------------------------------------------------------------


Shader "阿拉丁Shader编程/4-1.2D图片变灰"
{
   Properties
    {
        _MainTex ("Sprite Texture", 2D) = "white" {}
        _Color ("Tint", Color) = (1,1,1,1)
        _GrayScale ("GrayScale", Float) = 1
		[Toggle]_Open("Open", Int) = 1	//Toggle控制是否开启
    }

    SubShader
    {
        Tags
        { 
            "Queue"="Transparent" 
            "IgnoreProjector"="True" 
            "RenderType"="Transparent" 
            "PreviewType"="Plane"
            "CanUseSpriteAtlas"="True"
        }

        Cull Off
        Lighting Off
        ZWrite Off
        Blend One OneMinusSrcAlpha

        Pass
        {
        CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma multi_compile _ PIXELSNAP_ON	  //告诉Unity编译不同版本的Shader,这里和后面vert中的PIXELSNAP_ON对应
            #include "UnityCG.cginc"

            struct appdata_t
            {
                float4 vertex   : POSITION;
                float4 color    : COLOR;
                float2 texcoord : TEXCOORD0;
            };

            struct v2f
            {
                float4 vertex   : SV_POSITION;
                fixed4 color    : COLOR;
                half2 texcoord  : TEXCOORD0;
            };

            fixed4 _Color;
			fixed _Open;
            v2f vert(appdata_t IN)
            {
                v2f OUT;
                OUT.vertex = UnityObjectToClipPos(IN.vertex);
                OUT.texcoord = IN.texcoord;
                OUT.color = IN.color * _Color;
                #ifdef PIXELSNAP_ON
                OUT.vertex = UnityPixelSnap (OUT.vertex);
                #endif

                return OUT;
            }

            sampler2D _MainTex;
            float _GrayScale;

            fixed4 frag(v2f IN) : SV_Target
            {
				if(_Open > 0)
				{
					fixed4 c = tex2D(_MainTex, IN.texcoord) * IN.color;
				   float cc = (c.r * 0.299 + c.g * 0.518 + c.b * 0.184);  //乘以一个灰度系数
					cc *= _GrayScale;
					c.r = c.g = c.b = cc;

					c.rgb *= c.a;
					return c;
				}
                else
				{
				   return tex2D(_MainTex, IN.texcoord) * IN.color;
				}
            }
        ENDCG
        }
    }
}



边缘着色效果

核心思路

在片源 着色器中每个图元检测alpha跟阀值进行对比就能找到边缘

代码
[AppleScript] 纯文本查看 复制代码
//-----------------------------------------------【Shader说明】--------------------------------------------------------
//     Shader功能:   2D图片描边	 核心思路:检测某个图元的alpha值是否在某个阀值之间
//     使用语言:   Shaderlab
//     开发所用IDE版本:Unity2018.3.6 、Visual Studio 2017
//     2016年9月16日  Created by Aladdin(阿拉丁)   
//     更多内容或交流请访问我的博客:http://blog.csdn.net/s10141303/article/category/6670402
//---------------------------------------------------------------------------------------------------------------------


Shader "阿拉丁Shader编程/4-2.2D图片描边"
{
	Properties
	{
		[PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
		_Color ("Tint", Color) = (1,1,1,1) //图像回合颜色
		_OutLineColor("OutLineColor", Color) = (1,1,1,1) //边缘颜色
		_CheckRange("CheckRange",Float) = 1	  //检测的范围
		_CheckAccuracy("CheckAccuracy",Float) = 0.5
		_LineWidth("LineWidth",Float) = 2	   //边缘宽度
	}
 
	SubShader
	{
		Tags
		{ 
			"Queue"="Transparent" 
			"IgnoreProjector"="True" 
			"RenderType"="Transparent" 
			"PreviewType"="Plane"
			"CanUseSpriteAtlas"="True"
		}
 
		Cull Off         //关闭背面剔除
		Lighting Off     //关闭灯光
		ZWrite Off       //关闭Z缓冲
		Blend One OneMinusSrcAlpha     //混合源系数one(1)  目标系数OneMinusSrcAlpha(1-one=0)
 
		Pass
		{
		CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			#pragma multi_compile _ PIXELSNAP_ON       //告诉Unity编译不同版本的Shader,这里和后面vert中的PIXELSNAP_ON对应
			#include "UnityCG.cginc"
			sampler2D _MainTex;
			float4 _MainTex_TexelSize;
			
			fixed4 _Color;
			fixed4 _OutLineColor;
			float _CheckAccuracy;
			float _LineWidth;
			float _CheckRange;
			struct appdata_t                           //vert输入
			{
				float4 vertex   : POSITION;
				float4 color    : COLOR;
				float2 texcoord : TEXCOORD0;
			};
 
			struct v2f                                 //vert输出数据结构
			{
				float4 vertex   : SV_POSITION;
				fixed4 color    : COLOR;
				float2 texcoord  : TEXCOORD0;
			};
 
			v2f vert(appdata_t IN)
			{
				v2f OUT;
				OUT.vertex = UnityObjectToClipPos(IN.vertex);
				OUT.texcoord = IN.texcoord;
				OUT.color = IN.color * _Color;
				#ifdef PIXELSNAP_ON
				OUT.vertex = UnityPixelSnap (OUT.vertex);
				#endif
 
				return OUT;
			}
 
			fixed4 SampleSpriteTexture (float2 uv)
			{
				fixed4 color = tex2D (_MainTex, uv);
				return color;
			}
			
			fixed4 frag(v2f IN) : SV_Target
			{
				fixed4 c = SampleSpriteTexture (IN.texcoord) * IN.color;
				c.rgb *= c.a;
				float isOut = step(abs(1/_LineWidth),c.a);	//检测每个图元的aplha是否在某个值 那么他就是边缘	  //step(a, x) Returns (x >= a) ? 1 : 0	   abs(x) 返回绝对值
				if(isOut != 0)
				{
					fixed4 pixelUp = tex2D(_MainTex, IN.texcoord + fixed2(0, _MainTex_TexelSize.y*_CheckRange));  
					fixed4 pixelDown = tex2D(_MainTex, IN.texcoord - fixed2(0, _MainTex_TexelSize.y*_CheckRange));  
					fixed4 pixelRight = tex2D(_MainTex, IN.texcoord + fixed2(_MainTex_TexelSize.x*_CheckRange, 0));  
					fixed4 pixelLeft = tex2D(_MainTex, IN.texcoord - fixed2(_MainTex_TexelSize.x*_CheckRange, 0));  
					float bOut = step((1-_CheckAccuracy),pixelUp.a*pixelDown.a*pixelRight.a*pixelLeft.a);
					c = lerp(_OutLineColor,c,bOut);
					return c;
				}
				return c;
			}
		ENDCG
		}
	}
}



圆角头像效果


核心思路


根据圆相关的知识,将正方形图分成四块象限区域然后每个象限一个最大的半径为0.5的圆,计算像素是否在圆角之内是关键核心,首先计算四个圆心中间的像素,然后在根据像素距离圆心的长度是否交于半径,小于则在圆角之内,否则舍弃。

代码
[AppleScript] 纯文本查看 复制代码
//-----------------------------------------------【Shader说明】--------------------------------------------------------
//     Shader功能:   2D圆角头像	
//	   核心思路:根据圆相关的知识,将正方形图分成四块象限区域然后每个象限一个最大的半径为0.5的圆,计算像素是否在圆角
//     之内是关键核心,首先计算四个圆心中间的像素,然后在根据像素距离圆心的长度是否交于半径,小于则在圆角之内,否则舍弃
//     使用语言:   Shaderlab
//     开发所用IDE版本:Unity2018.3.6 、Visual Studio 2017
//     2016年9月16日  Created by Aladdin(阿拉丁)   
//     更多内容或交流请访问我的博客:http://blog.csdn.net/s10141303/article/category/6670402
//---------------------------------------------------------------------------------------------------------------------

Shader "阿拉丁Shader编程/4-3.2D圆角头像" {
	Properties {
		_MainTex ("Base (RGB)", 2D) = "white" {}
		_RADIUSBUCE("Radius(圆角半径)",Range(0,0.5))= 0.2   //圆角半径
	}
	SubShader
	{
		pass
		{
			CGPROGRAM
			#pragma exclude_renderers gles
			#pragma vertex vert
			#pragma fragment frag
			#include "unitycg.cginc"
			float _RADIUSBUCE;
			sampler2D _MainTex;

			struct v2f
			{
				float4 pos : SV_POSITION;
				float2 ModeUV: TEXCOORD0;
				float2 RadiusBuceVU : TEXCOORD1;
			};
			v2f vert(appdata_base v)
			{
				v2f o;
				o.pos=UnityObjectToClipPos(v.vertex); //v.vertex;
				o.ModeUV=v.texcoord;
				o.RadiusBuceVU=v.texcoord-float2(0.5,0.5);       //将模型UV坐标原点置为中心原点,为了方便计算  原本坐标原点在左下角
				return o;
			}


			fixed4 frag(v2f i):COLOR
			{
				fixed4 col;
				col=(0,1,1,0);

				if(abs(i.RadiusBuceVU.x)<0.5-_RADIUSBUCE||abs(i.RadiusBuceVU.y)<0.5-_RADIUSBUCE)   //像素点坐标在中间一块	不在四个角落	渲染原本的图元颜色
				{
					col=tex2D(_MainTex,i.ModeUV);
				}
				else //如果在四个角落
				{
					if(length(abs(i.RadiusBuceVU)-float2(0.5-_RADIUSBUCE,0.5-_RADIUSBUCE)) <_RADIUSBUCE)  //在圆角的内的像素 坐标到圆心的距离是否小于半径 小于则在圆角之内
					{
						col=tex2D(_MainTex,i.ModeUV);
					}
					else
					{
						discard;  //舍弃图元 相当于clip
					}		
				}
				return col;		
			}
			ENDCG
		}
	}
}



待添加。。。

工程地址

游客,如果您要查看本帖隐藏内容请回复






回复

使用道具 举报

3偶尔光临
216/300

0

主题

29

帖子

216

积分

Rank: 3Rank: 3Rank: 3

UID
309624
好友
1
蛮牛币
349
威望
0
注册时间
2018-12-25
在线时间
187 小时
最后登录
2019-12-12
2019-4-11 19:10:31 显示全部楼层
给力给力
回复

使用道具 举报

6蛮牛粉丝
1399/1500
排名
3288
昨日变化

24

主题

141

帖子

1399

积分

Rank: 6Rank: 6Rank: 6

UID
123454
好友
0
蛮牛币
2120
威望
0
注册时间
2015-9-22
在线时间
780 小时
最后登录
2019-12-12
2019-4-11 21:23:34 显示全部楼层
感谢楼主分享
回复

使用道具 举报

7日久生情
1795/5000
排名
1516
昨日变化

0

主题

348

帖子

1795

积分

Rank: 7Rank: 7Rank: 7Rank: 7

UID
151586
好友
0
蛮牛币
1821
威望
0
注册时间
2016-6-11
在线时间
609 小时
最后登录
2019-12-13
QQ
2019-4-12 10:13:29 显示全部楼层
66666666666666666666666666666
回复 支持 反对

使用道具 举报

3偶尔光临
277/300
排名
39864
昨日变化

0

主题

119

帖子

277

积分

Rank: 3Rank: 3Rank: 3

UID
207933
好友
0
蛮牛币
58
威望
0
注册时间
2017-3-8
在线时间
152 小时
最后登录
2019-11-15
2019-4-12 14:54:53 显示全部楼层
66666666666666666666666666666
回复 支持 反对

使用道具 举报

5熟悉之中
887/1000
排名
3265
昨日变化

0

主题

25

帖子

887

积分

Rank: 5Rank: 5

UID
13439
好友
1
蛮牛币
1848
威望
0
注册时间
2014-1-27
在线时间
406 小时
最后登录
2019-12-13
2019-4-12 16:11:17 显示全部楼层
感谢分享,赞
回复

使用道具 举报

3偶尔光临
244/300

0

主题

97

帖子

244

积分

Rank: 3Rank: 3Rank: 3

UID
143781
好友
0
蛮牛币
296
威望
0
注册时间
2016-3-29
在线时间
147 小时
最后登录
2019-12-11
2019-4-13 14:20:20 显示全部楼层
感谢分享,先看一看
回复 支持 反对

使用道具 举报

7日久生情
2405/5000
排名
479
昨日变化

2

主题

104

帖子

2405

积分

Rank: 7Rank: 7Rank: 7Rank: 7

UID
69739
好友
0
蛮牛币
3139
威望
0
注册时间
2015-1-20
在线时间
757 小时
最后登录
2019-11-7
2019-4-15 09:09:12 显示全部楼层
学习学习
回复

使用道具 举报

3偶尔光临
244/300
排名
18294
昨日变化

1

主题

34

帖子

244

积分

Rank: 3Rank: 3Rank: 3

UID
295537
好友
0
蛮牛币
403
威望
0
注册时间
2018-9-3
在线时间
176 小时
最后登录
2019-12-11
2019-4-15 13:33:10 显示全部楼层
弱弱地问一句,对UI上图片使用圆角shader会影响合批吗?
回复 支持 反对

使用道具 举报

5熟悉之中
580/1000
排名
5983
昨日变化

0

主题

42

帖子

580

积分

Rank: 5Rank: 5

UID
242896
好友
0
蛮牛币
1236
威望
0
注册时间
2017-9-12
在线时间
306 小时
最后登录
2019-12-11
2019-4-18 11:40:22 显示全部楼层
楼主给力 终于看到有真正价值的了
回复 支持 反对

使用道具 举报

4四处流浪
454/500
排名
9202
昨日变化

0

主题

44

帖子

454

积分

Rank: 4

UID
250135
好友
0
蛮牛币
430
威望
0
注册时间
2017-10-22
在线时间
284 小时
最后登录
2019-12-6
2019-4-19 09:48:07 显示全部楼层
感谢分享
回复

使用道具 举报

5熟悉之中
848/1000
排名
3902
昨日变化

9

主题

138

帖子

848

积分

Rank: 5Rank: 5

UID
232340
好友
0
蛮牛币
87
威望
0
注册时间
2017-7-15
在线时间
317 小时
最后登录
2019-12-11
2019-4-29 14:44:12 显示全部楼层
谢谢分享
回复

使用道具 举报

4四处流浪
468/500
排名
11088
昨日变化

1

主题

219

帖子

468

积分

Rank: 4

UID
205241
好友
0
蛮牛币
18
威望
0
注册时间
2017-2-6
在线时间
157 小时
最后登录
2019-12-1
2019-5-10 10:26:45 显示全部楼层
很给力,10个字数限制...
回复 支持 反对

使用道具 举报

6蛮牛粉丝
1263/1500
排名
16957
昨日变化

4

主题

772

帖子

1263

积分

Rank: 6Rank: 6Rank: 6

UID
199204
好友
1
蛮牛币
2255
威望
0
注册时间
2017-1-5
在线时间
447 小时
最后登录
2019-12-12
2019-5-22 17:22:28 显示全部楼层
谢谢分享
回复

使用道具 举报

6蛮牛粉丝
1263/1500
排名
16957
昨日变化

4

主题

772

帖子

1263

积分

Rank: 6Rank: 6Rank: 6

UID
199204
好友
1
蛮牛币
2255
威望
0
注册时间
2017-1-5
在线时间
447 小时
最后登录
2019-12-12
2019-5-22 17:27:24 显示全部楼层
谢谢分享
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册帐号

本版积分规则