shader利用噪声实现2D屏幕水波纹

    在这之前试着通过计算输出正弦(sin)相关的uv坐标来实现波动效果,结果比较失望,那种方法大概适合使用在3D的波浪效果上。

    shader使用噪声效果+屏幕捕获实现

Shader "Custom/wave" {
    Properties{
        _MainTex("Maintex", 2D) = "white" {}

        _Noise_Mask("Noise_Mask", 2D) = "white" {}
        _Noise("Noise", 2D) = "white" {}
        _Noise_Power("Noise_Power", Float) = 0.05
        _Noise_SV("Noise_SV", Vector) = (1,1,1,1)
        _node_8634("node_8634", Color) = (0.5,0.5,0.5,1)
        [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
        ZWrite Off

        CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#define UNITY_PASS_FORWARDBASE
#include "UnityCG.cginc"
#pragma multi_compile_fwdbase
#pragma exclude_renderers xbox360 xboxone ps3 ps4 psp2 
#pragma target 3.0
        uniform float4 _TimeEditor;
        uniform sampler2D _MainTex;
        uniform float4 _MainTex_ST;

        uniform sampler2D _Noise; uniform float4 _Noise_ST;
        uniform float4 _Noise_SV;
        uniform float _Noise_Power;
        uniform sampler2D _Noise_Mask; uniform float4 _Noise_Mask_ST;
        uniform float4 _node_8634;
        uniform sampler2D _GrabTexture;
        float4 _GrabTexture_ST;

        struct VertexInput {
            float4 vertex : POSITION;
            float2 texcoord0 : TEXCOORD0;
            float4 vertexColor : COLOR;
        };

        struct VertexOutput {
            float4 pos : SV_POSITION;
            float2 uv0 : TEXCOORD0;
            float4 vertexColor : COLOR;
        };

        VertexOutput vert(VertexInput v)
        {
            VertexOutput o = (VertexOutput)0;
            o.uv0 = v.texcoord0;
            o.vertexColor = v.vertexColor;
            o.pos = UnityObjectToClipPos(v.vertex);

            //计算该模型顶点在屏幕坐标的纹理信息(是的仅捕获对象后的屏幕纹理而非全屏)
            float4 screenUV = ComputeGrabScreenPos(o.pos);
            o.uv0 = screenUV.xy / screenUV.w;

            return o;
        }

        float4 frag(VertexOutput i, float facing : VFACE) : COLOR
        {
            float isFrontFace = (facing >= 0 ? 1 : 0);
            float faceSign = (facing >= 0 ? 1 : -1);
            // Lighting:
            // Emissive:
            float4 node_7596 = _Time + _TimeEditor;
            float2 node_3132 = (i.uv0 + (float2(_Noise_SV.r,_Noise_SV.g)*node_7596.g));
            float4 node_6583 = tex2D(_Noise,TRANSFORM_TEX(node_3132, _Noise));
            float2 node_5883 = (i.uv0 + (node_7596.g*float2(_Noise_SV.b,_Noise_SV.a)));
            float4 node_133 = tex2D(_Noise,TRANSFORM_TEX(node_5883, _Noise));
            float4 _Noise_Mask_var = tex2D(_Noise_Mask,TRANSFORM_TEX(i.uv0, _Noise_Mask));
            float2 node_9379 = (i.uv0 + ((float2(node_6583.r,node_133.g)*_Noise_Power)*_Noise_Mask_var.r));
            float4 _Maintex_var = tex2D(_GrabTexture,TRANSFORM_TEX(node_9379, _GrabTexture));
            float3 emissive = (_Maintex_var.rgb*_node_8634.rgb*i.vertexColor.rgb*2.0);
            float3 finalColor = emissive;
            return fixed4(finalColor,(_node_8634.a*i.vertexColor.a*_Maintex_var.a));
        }
        ENDCG
        }
    }
    FallBack "Diffuse"
}
修改不同的_Noise达到不同的效果

1.

 

 

2.

 

 不过官方说GrabPass比较耗(感觉Pc上似乎没问题,具体手机上没测试过)。是这样的话,可以通过摄像机,将渲染的内容写到RenderTexture中,脚本赋值Tex实现(shader需要相应修改)。

    网上现成的代码

    public Camera m_camera;          // 和主摄像机参数一样的拍照摄像机
    private RenderTexture m_tex;    // 摄像机渲染的材质
    public Material mat;            // 要控制的材质

    void Start()
    {
        m_tex = new RenderTexture(Screen.width, Screen.height, 16);
        m_camera.targetTexture = m_tex;
    }

    void OnPreCull()
    {
        mat.SetTexture("_MainTex", m_tex);   // 给shader的主材质赋值,为屏幕纹理
    }
    void OnPostRender()
    {
        mat.SetTexture("_MainTex", null);
    }

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Sam_ONE

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值