菜鸡shader:L9 屏幕UV及屏幕UV扰动

屏幕UV

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
最主要的代码是屏幕UV的获取:
在这里插入图片描述
这里具体可以参考这位大佬的博客:

代码

Shader "shader forge/L17_ScreenUV"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}           //主纹理
        _ScreenTex("Screen Tex", 2D) = "gray"{}      //屏幕纹理
        _Opacity ("Opacity",Range(0.0,1.0)) = 0.5    //透明度,是一张灰度图
    }
    SubShader
    {
        Tags {
            "Queue" = "Transparent"
            "RenderType"="Transparent" 
            "ForceNoShadowCasting" = "True"
            "IgnoreProjector" = "True"
        }
        LOD 100

        Pass
        {
            NAME "FORWARD"
            Tags{
                "LightMode" = "ForwardBase"
            }
            Blend One OneMinusSrcAlpha

            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;
                float2 screenUV : TEXCOORD1;
            };

            uniform sampler2D _MainTex;
            uniform sampler2D _ScreenTex;
            uniform float4 _ScreenTex_ST;
            uniform half _Opacity;

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = v.uv;
                //下面是获取屏幕UV的写法
                half3 posVS = UnityObjectToViewPos(v.vertex).xyz;       //将顶点转换到视图空间下
                half originDist = UnityObjectToViewPos(float3(0.0,0.0,0.0)).z;  //将模型空间的原点转换到视图空间下,取得视图空间下模型空间的原点距离摄像机的z距离
                o.screenUV = posVS.xy / posVS.z;    //透视转正交
                o.screenUV *= originDist;           //大小锁定
                //xy是Tiling,zw是offset,因为zw是两个分量,所以分别调整zw的值都会让屏幕贴图根据调整z(x)或w(y)的方向流动起来
                o.screenUV = o.screenUV * _ScreenTex_ST.xy - frac(_Time.x * _ScreenTex_ST.zw);  
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                half4 var_MainTex = tex2D(_MainTex,i.uv);
                half var_ScreenTex = tex2D(_ScreenTex,i.screenUV).r;
                //最终颜色和不透明度
                half3 finalColor = var_MainTex;
                half opacity = _Opacity * var_ScreenTex * var_MainTex.a;

                //return half4(finalColor,opacity);
                return half4(finalColor * opacity,opacity);
            }
            ENDCG
        }
    }
}

最后效果

在这里插入图片描述
在这里插入图片描述

屏幕UV扰动

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

代码

Shader "shader forge/L17_ScreenWrap"
{
    Properties
    {
        _MainTex ("Main Texture   RGB:Color  A:toutie", 2D) = "white" {}
        _WrapMidVal ("Wrap Mid Value", Range(0.0,1.0)) = 0.2
        _WrapInt("Wrap Intensity",Range(0.0,3.0)) = 0.5
        _Opacity("Opacity",Range(0.0,1.0)) = 0.5
    }
    SubShader
    {
        Tags {
            "Queue" = "Transparent"
            "RenderType"="Transparent" 
            "ForceNoShadowCasting" = "True"
            "IgnoreProjector" = "True"
        }
        LOD 100

        GrabPass{
            "_BgTex"
        }

        Pass
        {
            NAME "FORWARD"
            Tags{
                "LightMode" = "ForwardBase"
            }
            Blend One OneMinusSrcAlpha

            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;
                float4 grabPos : TEXCOORD1;
            };

            uniform sampler2D _MainTex;
            uniform float4 _MainTex_ST;
            uniform sampler2D _BgTex;
            uniform half _WrapMidVal;
            uniform half _WrapInt;
            uniform half _Opacity;

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                o.grabPos = ComputeGrabScreenPos(o.vertex);
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                //采样MainTex,A通道是透贴
                half4 var_MainTex = tex2D(_MainTex,i.uv);

                //扰动背景纹理,采样uv。以主纹理的某个灰度通道作为扰动背景纹理UV的源,扰动背景纹理UV。
                //减去一个值(中间值)是为了能在正负方向上都能偏移;再乘上一个透明度是因为越不透明折射越强,越透明越没有折射
                i.grabPos.xy += (var_MainTex.r - _WrapMidVal) * _WrapInt * _Opacity;       
                half3 var_BgTex = tex2Dproj(_BgTex, i.grabPos).rgb;
                //获取最终颜色和透明度
                half3 finalColor = lerp(1.0, var_MainTex.rgb, _Opacity) * var_BgTex;
                half opacity = var_MainTex.a * _Opacity;

                return half4(finalColor * opacity, opacity);
                //return half4(var_BgTex,1.0);
            }
            ENDCG
        }
    }
}

最后效果

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值