C for Graphic:语言(frag操作)

      紧接上一篇:https://blog.csdn.net/yinhun2012/article/details/82752910

      之前我们随便尝试了下vertex顶点函数能干些什么稀奇古怪的事情,本质上来说就是让我们开发者自己写代码操作顶点变换。这一篇就看看frag片段函数能干什么!如果看过前面的博客(当然我的意思是肯定要按顺序看前面的博客的),那么也就知道frag片段函数在图形流水线中,需要经过vertex顶点函数处理完顶点数据,再经过光栅化,才到frag片段函数处理最后的像素颜色。

      这里就先通过一个小例子来看看效果,代码如下:

Shader "Unlit/FragEffectUnlitShader"
{
	Properties
	{
		_MainTex ("Texture", 2D) = "white" {}
	}
	SubShader
	{
		Tags { "RenderType"="Opaque" }
		LOD 100

		Pass
		{
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag

			#include "UnityCG.cginc"

			struct appdata
			{
				float4 vertex : POSITION;
				float2 uv : TEXCOORD0;
			};

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

			sampler2D _MainTex;
			float4 _MainTex_ST;
			
			v2f vert (appdata v)
			{
				v2f o;
				o.vertex = UnityObjectToClipPos(v.vertex);
				o.uv = TRANSFORM_TEX(v.uv, _MainTex);
				return o;
			}
			
			fixed4 reverseColor(fixed4 col)
			{
				//将颜色反转
				return fixed4(1.0-col.x,1.0-col.y,1.0-col.z,col.w);	
			}

			fixed4 frag (v2f i) : SV_Target
			{
				fixed4 col = tex2D(_MainTex, i.uv);
				//反转颜色值后,提交到图形流水线后续流程更新像素值
				col = reverseColor(col);
				return col;
			}
			ENDCG
		}
	}
}

      效果如下:

      

     用iphone的小伙伴们可能知道这个效果,就是辅助功能中的颜色反转。简单解释一下就是通过一个reverseColor函数将颜色值反转一下(这里颜色值分量是0-1.0f的浮点数),代码很简单,所以我直接写注释中解释。

     当然还有其他效果了,如下:

     

Properties
{
	_MainTex ("Texture", 2D) = "white" {}
	_Appro("Approximate",Range(0.01,1.0)) = 0.1
}

float _Appro;

//判断一个浮点数是否在某个近似区间
bool approValue(float refer,float col)
{
	if(col<refer+_Appro && col>refer-_Appro)
	{
		return true;
	}
	return false;
}	
//判断一个颜色值rgb分量是否在某个近似区间
bool approColor(fixed4 refer,fixed4 col)
{
	if(approValue(refer.x,col.x) && approValue(refer.y,col.y) && approValue(refer.z,col.z))
	{
		return true;
	}
	return false;
}
//判断frag颜色值是否近似白色并修改成红色
fixed4 whiteCol2Red(fixed4 col)
{
	if(approColor(fixed4(1.0,1.0,1.0,1.0),col))
	{
		col = fixed4(1.0,0.0,0.0,1.0);
	}
	return col;
}

fixed4 frag (v2f i) : SV_Target
{
	fixed4 col = tex2D(_MainTex, i.uv);
	//将近似白色转红色
	col = whiteCol2Red(col);
	return col;
}

       效果如下图:

       

      这里我解释下,代码贴出关键部分,而且有注释很简单,就是判断片段tex2D采样函数中采样出来的col颜色值是否近似白色(当然我添加了一个近似阀值Approximate控制),通过手动拖拽修改近似阀值,就将纹理中白色值转换成红色值,可以看出最近接白色的uv坐标点颜色值最开始该变成红色,符合预期。

      接下来来个动态效果看看,代码如下:

      

Properties
{
	_MainTex ("Texture", 2D) = "white" {}
	_Appro("Approximate",Range(0.01,1.0)) = 0.1
	_Col("Col",Color) = (0,0,0,0)
	_PingPong("PingPong",Range(0.01,5.0)) = 0.01
} 

float4 _Col;
float _PingPong;   

fixed4 frag (v2f i) : SV_Target
{
	fixed4 col = tex2D(_MainTex, i.uv);
	float _ppTime = 0.0;
	//计算时间值于pingpong时间的关系,处于单数pingpong时间内就递增,双数就递减
	if((((int)_Time.y/(int)_PingPong))%2 == 1)
	{
		_ppTime = _Time.y % _PingPong;
	}
	else
	{
		_ppTime = _PingPong-(_Time.y % _PingPong);
	}
	//给一个颜色值做叠加呼吸效果
	col += _ppTime * _Col;
	return col;
}

      效果图如下:

      

     代码也只贴出关键部分,其实也很简单,定义一个pingpong时间,一个叠加color值,通过_Time去处理pingpong呼吸灯颜色效果,顺便说一下,_Time这个结构变量,是有四个分量的,其中y分量就是unity提供的开始运行的增加时间量,贴下UnityShaderVariables.cginc代码,如下:

     

     写到这里了,我想表达的意思就是fragment片段函数从图形流水线流程来看,就是提供给我们开发改变颜色值的接口函数,我们可以发挥自己想象力,写出炫丽的效果,上面三个简单的例子是为了形象的告诉大家fragment片段函数该怎么去处理,后面我们实现更高级的着色器效果的时候能看到更炫的代码。

     so,接下来我们继续。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值