UnityShader UV动画深入探讨(栅格化,棋盘格等效果实现)

UV=平面坐标,u=X轴

核心算法:

 fixed2 stepUv = step(sin((i.uv.r*_Value)),_Step);

 

GLSL中,step()函数用于计算两个值之间的步长。它接受两个参数:第一个参数是阈值,第二个参数是切变方向。

step()函数的原型如下:

float step(float edge, float x)  
vec2 step(vec2 edge, vec2 x)  
vec3 step(vec3 edge, vec3 x)  
vec4 step(vec4 edge, vec4 x)
vec2 step(float edge, vec2 x)  
vec3 step(float edge, vec3 x)  
vec4 step(float edge, vec4 x)

其中,edge是阈值,x是切变方向。

如果x大于edge,则step()函数返回1.0;如果x小于等于edge,则返回0.0。这个函数在着色器中常用于纹理映射、渐变和边缘检测等领域。

用途:一般用来做边缘检测。

完整代码如下:

 

Shader "Unlit/UV_Step01"
{

  //通过UV的X方向实现动态栅格化效果。
	Properties
	{
		_Value("Value",Range(0,50))=0
		_Step("Step",Range(0,1))=0
	}
	SubShader
	{
		Tags { "RenderType"="Opaque" }
		Pass
		{
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			#pragma multi_compile_fog
			#include "UnityCG.cginc"
			struct appdata
			{
				float4 vertex : POSITION;
				fixed2 uv : TEXCOORD0;
			};
			struct v2f
			{
				fixed2 uv : TEXCOORD0;
				UNITY_FOG_COORDS(1)
				float4 vertex : SV_POSITION;
			};
			fixed _Value;
			fixed _Step;						
			v2f vert (appdata v)
			{
				v2f o;
				o.vertex = UnityObjectToClipPos(v.vertex);
				o.uv =v.uv;
				UNITY_TRANSFER_FOG(o,o.vertex);
				return o;
			}			
			fixed4 frag (v2f i) : SV_Target
			{
			//若竖向展开效果 只需要接入i.uv.g通道,实际上就是取Y方向值;
			 //float stepUv = step(sin((i.uv.r*_Value)),_Step);		
			 fixed stepUv = step(sin((i.uv.g*_Value)),_Step);
			 
			 fixed4 col = fixed4(stepUv,stepUv,stepUv,1);
				UNITY_APPLY_FOG(i.fogCoord, col);
				return col;
			}
			ENDCG
		}
	}
}

我们再深入优化下:棋盘格效果应该如何实现呢?

栅格化效果:

    

核心代码:

    

   fixed2 remapUv = (sin((i.uv*_Value))*0.98+0.01).rg;
   fixed stepUv = step(min(remapUv.r,remapUv.g),_Step);

remap算法公式: y = (x - t1) / (t2 - t1) * (s2 - s1) + s1。

白话原理: remap:将a-b映射到c-d

具体实现原理请查阅:Shader实验室:remap函数 - 知乎

完整代码如下:

Shader "Unlit/UV_Step02"
{

  //深入实现格栅化效果
	Properties
	{
		_Value("Value",Range(0,50))=0
		_Step("Step",Range(-1,1))=0
	}
	SubShader
	{
		Tags { "RenderType"="Opaque" }
		Pass
		{
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			#pragma multi_compile_fog
			#include "UnityCG.cginc"
			struct appdata
			{
				float4 vertex : POSITION;
				fixed2 uv : TEXCOORD0;
			};
			struct v2f
			{
				fixed2 uv : TEXCOORD0;
				UNITY_FOG_COORDS(1)
				float4 vertex : SV_POSITION;
			};
			fixed _Value;
			fixed _Step;						
			v2f vert (appdata v)
			{
				v2f o;
				o.vertex = UnityObjectToClipPos(v.vertex);
				o.uv =v.uv;
				UNITY_TRANSFER_FOG(o,o.vertex);
				return o;
			}			
			fixed4 frag (v2f i) : SV_Target
			{

			   /*
			   remap:将a-b映射到c-d
			   */
			    fixed2 remapUv = (sin((i.uv*_Value))*0.98+0.01).rg;
			    fixed stepUv = step(min(remapUv.r,remapUv.g),_Step);

			 fixed4 col = fixed4(stepUv,stepUv,stepUv,1);
				UNITY_APPLY_FOG(i.fogCoord, col);
				return col;
			}
			ENDCG
		}
	}
}

扩展下思路,既然我们取最小值是数学算法,那我们可以做加法乘法除法么?

加法核心算法:

    

   fixed stepUv = step((remapUv.r+remapUv.g),_Step);

效果如下:

    

乘法核心算法: 

  fixed stepUv = step((remapUv.r*remapUv.g),_Step);

效果如下:

        

除法核心算法:

    

 fixed stepUv = step((remapUv.r/remapUv.g),_Step);

效果如下:

    

今天对UV做了最后的补充讲解,关于UV的tiling这些其实很简单,大家查阅下资料即可,就不再展开演示了 ,所以通过今天的博文,大家一定要有一个意识:思维思路大于死记硬背,不行我就多尝试,发散思维。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值