Shader水涟漪效果

不得不说,水涟漪效果的确很棒,在这里有个基于Unity和UGUI的水涟漪效果,我再移植的时候遇到了UGUI的画布要比NGUI大很多倍的问题

http://www.manew.com/thread-92365-1-1.html

在这个网址里,有着完整的代码和场景,其中最核心的就是Image(1),他用来实现水涟漪效果,但是背景也是不可缺少的.此外

一共有样是核心:shader和算法和场景.和显示水波纹的图片(只有一张,不是两张)


如果放在ngui里面,应该给一个图片声明texture而不是uisprite,然后设置其Matrail是水波纹材质,此时就将图片设置好了,为水波纹显示

水波纹移植失败,等有时间处理

把shader贴出来

// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'


Shader "HeatDistort_WLJ" {
Properties{
_MainTex("Texture", 2D) = "black" {}
_BumpMap("Normalmap", 2D) = "bump" {}
_BumpAmt("Distortion", Float) = 10
}


Category{


Tags { "Queue" = "Transparent"  "IgnoreProjector" = "True"  "RenderType" = "Opaque" }
Blend SrcAlpha OneMinusSrcAlpha
Cull Off
Lighting Off
ZWrite Off
Fog { Mode Off}


SubShader {
GrabPass {
Name "BASE"
Tags { "LightMode" = "Always" }
}
Pass {
Name "BASE"
Tags { "LightMode" = "Always" }


CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma fragmentoption ARB_precision_hint_fastest
#pragma multi_compile_particles
#include "UnityCG.cginc"


struct appdata_t {
float4 vertex : POSITION;
float2 texcoord: TEXCOORD0;
fixed4 color : COLOR;
};


struct v2f {
float4 vertex : POSITION;
float4 uvgrab : TEXCOORD0;
float2 uvbump : TEXCOORD1;
float2 uvmain : TEXCOORD2;


fixed4 color : COLOR;
#ifdef SOFTPARTICLES_ON
float4 projPos : TEXCOORD4;
#endif
};


sampler2D _MainTex;


sampler2D _BumpMap;


float _BumpAmt;


sampler2D _GrabTexture;
float4 _GrabTexture_TexelSize;






float4 _BumpMap_ST;
float4 _MainTex_ST;




v2f vert(appdata_t v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
#ifdef SOFTPARTICLES_ON
o.projPos = ComputeScreenPos(o.vertex);
COMPUTE_EYEDEPTH(o.projPos.z);
#endif
o.color = v.color;
#if UNITY_UV_STARTS_AT_TOP
float scale = -1.0;
#else
float scale = 1.0;
#endif
o.uvgrab.xy = (float2(o.vertex.x, o.vertex.y*scale) + o.vertex.w) * 0.5;
o.uvgrab.zw = o.vertex.zw;
o.uvbump = TRANSFORM_TEX(v.texcoord, _BumpMap);
o.uvmain = TRANSFORM_TEX(v.texcoord, _MainTex);




return o;
}


sampler2D _CameraDepthTexture;




half4 frag(v2f i) : COLOR
{


half2 bump = UnpackNormal(tex2D(_BumpMap, i.uvbump)).rg;
float2 offset = bump * _BumpAmt * _GrabTexture_TexelSize.xy;
i.uvgrab.xy = offset * i.uvgrab.z + i.uvgrab.xy;


half4 col = tex2Dproj(_GrabTexture, UNITY_PROJ_COORD(i.uvgrab));
fixed4 tex = tex2D(_MainTex, i.uvmain) * i.color;


fixed4 emission = col * i.color;
emission.a = i.color.a;
return emission;
}
ENDCG
}
}


SubShader {
Blend DstColor Zero
Pass {
Name "BASE"
SetTexture[_MainTex] { combine texture }
}
}
}


}

//把算法贴出来,为了以防万一,实现的效果就是每一动鼠标,就有水涟漪

using UnityEngine;
using System.Collections;
using System;
using UnityEngine.UI;


public class WaterRipper : MonoBehaviour
{
    public Texture2D ww;
    public Material xxx;
    public Color32[] ALLColor;
    public float[] buf1;
    public float[] buf2;
    public Color32 CC;
    public float DowenPower;//波能衰减力度
    public int Width_Tex;
    public int Hight_Tex;
    public float Times;
    //TODO
    //137行被注释代码
    //public Text textpois;//这个用来检测像素值
    //62行被注释代码
    //public RawImage P;//这个用来简版的描绘波纹


    // Use this for initialization
    void Start()
    {


        Width_Tex = Screen.width / 10;
        Hight_Tex = Screen.height / 10;


        ww = new Texture2D(Width_Tex, Hight_Tex, TextureFormat.ARGB32, false);


        xxx.SetTexture("_BumpMap", ww);


        ALLColor = new Color32[Width_Tex * Hight_Tex];


        buf1 = new float[Width_Tex * Hight_Tex];//保存上一帧的波幅
        buf2 = new float[Width_Tex * Hight_Tex];//这一帧的波幅


        Debug.Log(ALLColor.Length);
    }


    // Update is called once per frame
    void Update()
    {
        if (Times < 0.01f)
        {
            Times += Time.deltaTime;
        }
        else {
            RippleSpread();
            BufToColor();
            Change();
            Times = 0;
        }


        OnClickWater();
        //if (Input.GetMouseButton(0))
        //{
        //}
        //if (Input.touchCount > 0) {
        //    OnClickWater();
        //}
        //P.texture = ww;
    }
    //*******************************************************//计算波能数据缓冲区//*******************************************************
    public void RippleSpread()
    {
        float X1;
        float X2;
        float X3;
        float X4;


        for (int i = 0; i < buf1.Length; i++)
        {        //波能扩散 


            //水波边界反弹
            if ((i % Width_Tex - 1) >= 0)
            {
                X1 = buf1[i - 1];
            }
            else {
                X1 = buf1[i + 1];
            }
            if ((i % Width_Tex + 1) < Width_Tex)
            {
                X2 = buf1[i + 1];
            }
            else {
                X2 = buf1[i - 1];
            }
            if ((i - Width_Tex) >= 0)
            {
                X3 = buf1[i - Width_Tex];
            }
            else {
                X3 = buf1[i + Width_Tex];
            }
            if ((i + Width_Tex) < buf1.Length)
            {
                X4 = buf1[i + Width_Tex];
            }
            else {
                X4 = buf1[i - Width_Tex];
            }


            //波能扩散
            buf2[i] = (X1 + X2 + X3 + X4) / 2f - buf1[i];
            //波能衰减
            buf2[i] -= buf2[i] / 32f;
            if (buf2[i] < 1)
            {
                buf2[i] = 0;
            }
        }
        buf1 = buf2;
    }


    /// <summary>
    /// 将波幅度转换成图片颜色
    /// </summary>
    public void BufToColor()
    {
        for (int i = 0; i < buf1.Length; i++)
        {
            ALLColor[i].g = (byte)(buf1[i] - 128f);
            ALLColor[i].a = (byte)(buf1[i] - 128f);
            //ALLColor[i].r = (byte)(buf1[i] + 128f);
            //ALLColor[i].b = (byte)(buf1[i] + 128f);


        }
    }
    //*****************************************************//增加波源//*****************************************************
    public void OnClickWater()
    {
        Vector3 V3 = Input.mousePosition;
        //Vector3 V3 = Input.GetTouch(0).position;
            DropStone(((int)V3.x), (int)V3.y, 100, 255);
        //textpois.text = V3.ToString();
    }
    public void DropStone(int x, int y, int stoneSize, int stoneweight)
    {   //根据传入的坐标,在对应的波幅中添加波


        int X1 = x / 10;
        int y1 = y / 10;
        //为了不报越界错误错,在这里加入限制条件,这些数的计算结果没有超过数组的大小
        if (Width_Tex * y1 + X1 < buf2.Length)
        {
            for (int posx = X1 - stoneSize; posx < X1 + stoneSize; ++posx)
            {
                for (int posy = y1 - stoneSize; posy < y1 + stoneSize; ++posy)
                {
                    if ((posx - X1) * (posx - X1) + (posy - y1) * (posy - y1) < stoneSize * stoneSize)
                    {
                        buf2[Width_Tex * y1 + X1] = stoneweight;
                    }
                }
            }
        }
    }
    public void Change()
    {
        ww.SetPixels32(ALLColor);
        ww.Apply();
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值