不得不说,水涟漪效果的确很棒,在这里有个基于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();
}
}