Unity 扭曲扰动Shader 效果解析

Unity 法线扭曲热浪Shader 效果解析

融合背景扭曲的热浪效果

其实扭曲最主要的两个函数就是:
1.GrabPass抓屏
2.ComputeGrabScreenPos (o.pos) 获取屏幕对应材质球的uv坐标
拿到这两个数据,剩下的就是进行uv的扰动和mask遮罩应用而已了。

直接上代码

Properties {
        _FinalPower ("Final Power", Range(0, 10)) = 0
        _Mask ("Mask", 2D) = "white" {}
        _DistortionAmount ("Distortion Amount", Range(0, 0.05)) = 0.0075
        _DistortionNormal ("DistortionNormal(可用Normalmap)", 2D) = "bump" {}
		_DistortFactorTime("FactorTime",Range(0,5)) = 0.5
        [HideInInspector]_Cutoff ("Alpha cutoff", Range(0,1)) = 0.5
    }
    SubShader {
        Tags {
            "IgnoreProjector"="True"
            "Queue"="Transparent"
            "RenderType"="Transparent"
        }
        GrabPass{ }
        Pass {
            Name "FORWARD"
            Tags {
                "LightMode"="ForwardBase"
            }
            Blend SrcAlpha OneMinusSrcAlpha
            Cull Off Lighting Off ZWrite Off
            
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #define UNITY_PASS_FORWARDBASE
            #include "../CGIncludes/UnityCG.cginc"
            #pragma multi_compile_fwdbase
			//#pragma only_renderers d3d9 d3d11 glcore gles 

            uniform sampler2D _GrabTexture;
            uniform half _FinalPower;
            uniform sampler2D _Mask;
            uniform half _DistortionAmount,_DistortFactorTime;
            uniform sampler2D _DistortionNormal; uniform half4 _DistortionNormal_ST;

			struct appdata
			{
				half4 vertex : POSITION;
                half2 texcoord0 : TEXCOORD0;
                half4 vertexColor : COLOR;
			};

			struct v2f
			{
				half4 pos : SV_POSITION;
                half2 uv : TEXCOORD0;
                half4 vertexColor : COLOR;
                half4 projPos : TEXCOORD1;
				half2 t2 : TEXCOORD2;
			};

			v2f vert (appdata v)
			{
 				v2f o;
				o.uv = TRANSFORM_TEX(v.texcoord0, _DistortionNormal);
				o.t2 = o.uv + _Time.xy * _DistortFactorTime;
				o.vertexColor = v.vertexColor;
                o.pos = UnityObjectToClipPos( v.vertex );
                o.projPos = ComputeGrabScreenPos (o.pos);
                return o;
			}

			half4 frag (v2f i) : COLOR
			{
  				half2 sceneUVs = (i.projPos.xy/i.projPos.w);
				half4 _Mask_var = tex2D(_Mask,i.uv);
                half3 _Distortion_var = UnpackNormal(tex2D(_DistortionNormal,i.t2));
                half _distortion_power = saturate(_Mask_var.r*_FinalPower*i.vertexColor.a);
				sceneUVs = lerp(sceneUVs.rg,sceneUVs.rg + _Distortion_var.rg * _distortion_power,_DistortionAmount);
				half3 finalColor =tex2D( _GrabTexture, sceneUVs).rgb;
				
                return fixed4(finalColor,_distortion_power);
			}
            
            ENDCG
        }
    }

另外需要注意的是GrabPass,官方文档上有两种GrabPass的写法:

第一种是直接GrabPass{}的写法,这种写法抓屏的图片就直接存到_GrabTexture这个系统预定义的贴图变量中了,我们可以直接访问该贴图,但是这种写法会导致每个使用GrabPass的物体进行一次这种旷日持久的抓屏操作!如果用这种shader的物体多了的话,想想就很可怕。

另一种是GrabPass{“TextureName”}的写法,其中TextureName是我们自定义的一个贴图名称,这种写法,Unity每帧只会为第一个使用了该名称的物体进行抓屏操作,但这样会造成如果有第二个相同扭曲效果的图片叠加的时候就会出现重合的边框。
切割前 切割后
扰动扭曲还可以改为法线贴图进行扰动,增加对高光的处理。让扭曲的效果更加锐利。

//法线扰动能让扭曲的折射效果更强烈,后期可以尝试加入高光的处理。
                half3 _Distortion_var = UnpackNormal(tex2D(_Distortion,i.t2));
  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Unity屏幕扰动是一种在游戏开发中常见的效果,可以给游戏画面增添动态感。它可以通过自定义层级来实现。扰动效果可以用于模拟物体的震动、爆炸或其他视觉特效。 在Unity中,我们可以通过使用自定义层级来控制扰动效果。首先,需要在项目中创建一个新的自定义层级。可以打开编辑器的Layer Inspector菜单,然后点击“Add Layer”按钮来添加一个新的层级。给这个层级取一个合适的名称,例如"Distortion"。 接下来,在层级视图中,可以将需要应用扰动效果的对象的Layer修改为自定义的"Distortion"层级。可以通过选中对象,然后在层级Inspector的Layer属性中选择"Distortion"层级来完成设置。 然后,在游戏场景中创建一个相机对象。通过将该相机的Culling Mask属性设置为只渲染"Distortion"层级上的物体,可以让该相机只显示被属于该层级的物体。这样,我们可以将扰动效果应用于这些物体。 最后,在脚本中编写相关的扰动逻辑。可以通过使用Unity的Post-processing插件,或者在Update函数中修改物体的位置、旋转等属性来实现屏幕扰动效果。 总而言之,Unity屏幕扰动效果可以通过自定义层级来实现。需要创建一个自定义的层级,并将需要应用扰动效果的对象的Layer设置为该层级。然后,创建一个只渲染该层级的相机,并在相应的脚本中编写扰动逻辑。通过这些步骤,我们可以实现屏幕的扰动效果

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值