从零开始学Shader之练手的马赛克

1 篇文章 0 订阅
1 篇文章 0 订阅

写在前面

刚刚接触学习Shader,希望以后都能够通过博客记录自己的学习过程,本篇也是我开始学习Shader的第一篇。本篇以实现马赛克效果来进行练手熟练一些Shader的基本内容。

目标

  • 实现2D图片的马赛克效果
  • 通过阀值控制模糊程度

思路

  • n*n范围内的像素取同一颜色

预览

实现

Shader "Temp/MSK" 
{
	Properties 
	{
		_MainTex("MainTex", 2D) = "white" {}
		_Value("Value", Range(1,50) ) = 25
	}
	SubShader 
	{
		Pass 
		{
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag 

			sampler2D _MainTex;
			float _Value;

			struct a2f
			{
				float4 pos : POSITION ;
				float2 uv : TEXCOORD0 ; 	
			} ;

			struct v2f
			{
				float4 pos : SV_POSITION;
				float2 uv : TEXCOORD0 ; 	
			} ;

			v2f  vert(a2f v)
			{
				v2f f;
				f.pos = UnityObjectToClipPos(v.pos);
				f.uv = v.uv;
				return f;
			}

			float4 frag(v2f i):SV_Target
			{
				half v = 1/_Value;
				half x = floor(i.uv.x/v)*v; //i.uv.x;
				half y = floor(i.uv.y/v)*v; //i.uv.y;
				half2 uv = float2(x, y);
				float3 res = tex2D(_MainTex, uv).rgb;
				return float4 (res, 1);
			}

			ENDCG
		}
	}

	Fallback "Diffuse"
}

以上代码便是其全部实现,接下来我来详细解释一下。

首先代码的第一行表明这个Shader的名字,然后Properties中声明了一些材质的属性。此外为了能够在CG代码中访问到它们我们还需要在CG代码中提前定义一个新的变量,而在CGPROGRAM和ENDCG中包裹着的就是我们的CG代码片段了,其中#pragma vertex vert和#pragma fragment frag 两句指明了我们的顶点函数是vert片元函数是frag,并且我们还定义了两个结构体a2f和v2f,冒号后面的内容则表示这个值从哪里来或者要到哪里去。

struct a2f
{
	float4 pos : POSITION ;
	float2 uv : TEXCOORD0 ; 	
} ;

struct v2f
{
	float4 pos : SV_POSITION;
	float2 uv : TEXCOORD0 ; 	
} ;

比如上面的a2f结构体中POSITION表明当作为输入时pos属性将会来自于模型空间的顶点坐标而TEXCOORD0表明使用第一对纹理对。而在v2f中我们使用了SV_POSITION语义,它表明我们使用或输出的是裁剪空间的定点坐标。

在顶点函数中我们通过UnityObjectToClipPos内置方法将输入的模型空间顶点转换为了裁剪空间顶点坐标并进行了输出。而在片元函数中我们则根据数据进行了一些计算,其核心原理为通过tex2D函数使用uv取值,在在此之前我们对uv进行了一下小小的修改,使其只为1/_Value的整数倍(uv的取值范围为0-1表明图片的横纵坐标)最后返回结果就得到了我们的马赛克效果。

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值