unity3d 制造自己的水体water effect

first,I wish you a happy new year, and study in spring festival’s eve means you are hardworking,haha. I write in two languages. One passage write in Chineseone passage translate into English. My English is poor., If I write some thing wrong, welcome to correct my article.

首先祝各位看官新春快乐,能在大年三十看博文学习的都是勤奋的人。

我用了两种语言,一段英文一段中文。我英语不太好,如果有英语语法错误,或者写的不对的各位可以告诉我及时改正

I study some about water lately. Looks like this in the gif; It looks not bad, but it is incomplete and regret.This shader is surface shader, used the tessellation technology by DX11.Because of used the  tessellation ,this shader’s vertex function can’t pass
parameter like position and normal, then, caused the water’s reflect light inaccuracy、can’t specular other things ,etc. The reason that can’t specular other things is can’t analysis reflection map. But just now I try to write a fragment shader that can use
the tessellation, and succeed, then the shader can pass parameter. I will write it in the second blog article, this blog article just talk about water waves.

最近研究了一下水体,效果如下图gif所示,乍看感觉还可以,但是有很多残念,这个例子是用surface shader写的,运用了曲面细分等技术。由于用了曲面细分,所以surface shader的vert不能传出值,所以不能传出顶点坐标和normal值,造成了反光不准确,而且不能反射(大残念,水体不能反射= =),不能反射的原因是不能解析脚本传入的反射贴图reflection map。 但是写本文的同时突然试了一下 fragment shader,居然好用,这样也能传出值了,就在本文的(二)中研究,今天的(一)只研究水体的波动。

Most of maves are caused by the action of wind, it’s better to use circular waves in the pond scence.we just talk about the directional waves.

大多数的波动是由于风吹动引起的,对于池塘中的水用圆形波更好一点,我们只讨论方向波

Mentioned waves, we all think of sin、cos ,etc. This shader also used them.

if we just use sin , that effects looks awful.

说起波动,大家想到的肯定是sin,cos,等函数,我们的水体也是用它做一些变换。

如果单单是sin 未免有些单调,看起来也不真实。

so, in this shader, I used the Displacement mapping that I write a blog article about it before.

That can add some other waves in water.

所以本例中加入了之前写过曲面细分中的贴图置换(Displacement mapping),对水面加入一些杂波。

But why to use the tessellation?

our water in unity is a model. The plan model’s has little points, may be 100++. Used tessellation can add much more points, make the waves more smooth. The figure below is the waves not used tessellation.Looks like jag.

为什么要加入曲面细分呢?

我们的水面是一个平面,也就是plane,unity中的plane模型顶点数显而易见,看起来貌似100++,加入了曲面细分,顶点数就是原有的数倍,波浪看起来精致圆滑,

下图为未经曲面细分的水面,(= =;这不就是锯齿吗);

If you don’t want the real wave effect, you don’t need tessellation, like unity’s water4, water4 not wave truly, just some effects like normal, reflect ,etc. Brain always be cheated by eyes.

about tessellation you can see this I write before

如果你不想要真实可见的波浪效果,你大可不用曲面细分,如unity自带的那种水体water4,water4等没有真正的波动,只是normal,反光等对你眼睛的一种欺骗。

关于unity曲面细分的详细可见博主之前的这篇文章

Above I talked my shader is use sin, there are also many good waves like this. I refer to the water in 《GPU Gems》 , it used Gerstner Waves, its reality. The real waves have sharper peaks and wider troughs.

刚刚说我的例子用的是sin波,还有很多很好的波形,参考了一下GPU gems中的水体,书上用的是Gerstner波,理由是—真实,真实的浪波比较尖,波谷比较宽

Gerstner’s function is:

Gerstner波的函数是:

then I try this

然后我就试了一下

That’s pretty good, the waves has many transformation, sharper peaks and wider troughs, with some small waves. Cause of used tessellation, the plane’s mesh and vertex is disappeared in unity, may be that is a bug in unity.

效果巨好,变化也多,明显看出浪头很尖,还有很多小浪波,由于是用了曲面细分导致水平面不显示网格顶点,貌似是unity的bug,残念。。

Here are the code, Cause of that can’t pass parameter, the water not have graet highlight, shade inaccurate, looks bad.

给出代码,有兴趣的看官可以研究下Gerstner波。

因为surface shader不能传出normal信息,没有高光,明暗的显示,再好的波也看不出来= =;

		float wave(float x, float z, float timer)
		{
			float y = 0;
			float oct = _OCT;
			float fac = _FAC;
			float d = sqrt(x * x + z * z);// length(float2(x, z));
			for (oct; oct>0; oct--)
			{
				y -= fac * cos(timer * _SP + (1 / fac) * x * z * _WS);
				fac /= 2;

			}
			return 2 * _VS * d * y;

		}

Then again to talk about sin, although less detail than Gerstner. But I think that’s also great. It’s not troublesome.

再说回sin波,前面的例子是sin波的,没有Gerstner波变化细致,但我也很满足了,本例的实现不需要像Gerstner波一样需要叠加,也没有Gerstner波那么复杂,

首先让我们研究下波:

1.    Wavelength(L): the crest-to-crest distance between waves;

2.    Amplitude(A): the height from the water plane to the wave crest.

3.    Speed(S):the distance the crest moves forward per second.

4.    Direction(D):the horizontal vector perpendicular to the wave front along which the crext travels.

1.    波长(L):波峰到波峰之间的距离。

2.    振幅(A):从水平面到波峰的高度。

3.    速度(S):每秒钟波峰移动的距离。

4.    方向(D):运动方向,垂直于波阵面的水平方向;

We can use this to defined the wave:

我们就可以通过这些参数定义波了

the code:

主要代码如下:

float time = _Time * _Speed/2;
float waveValueA = sin((v.vertex.x + v.vertex.z) * _Frequency + time * _Frequency) * _Amplitude;

That’s very easy, right?

很简单对吧

Simply put how to find the normal ,although can’t pass it,

The normal is given by the cross product of the binormal and tangent,as:

N = B * T;

虽然传不了normal值求normal也没什么意义,简单说下求法,

求出副法线B和切线T向量,分别为x,z方向的偏导数,

向量N = B * T;

然后就ok了。

我们得到了普通的波如下:

Then, we used the Displacement mapping.

We used the texture in unity’s water ----water4 to be our displacement map.

之后就要杂波登场了,贴图置换(Displacement mapping)。

我们用unity自带water4中的贴图作为贴图置换的资源

You can extract the texture in the water4.

Then is the blog article I write before about tessellation.We define a _Displacement value to control the other waves’s amplitude.

Define a _SpeedStrength value to control the other waves’s speed and direction.

看官们可从water4中自取。

然后就是之前曲面细分的内容了,我们设置随法线偏移度设为外部变量_Displacement来控制杂波的振幅,

又在外部定义了个参数_SpeedStrength来控制杂波移动速度和移动方向,

code:

此处代码如下:

			float d = tex2Dlod(_MainTex, float4(v.texcoord.xy+_SpeedStrength.xy*_Time.x,0,0)).r * _Displacement;
			v.vertex.xyz += v.normal * d;

here is the effect:

之后就可以看效果了

That is the end effect about waves.

就是本例最终实现的波形。

正题结束。

Cause of the real waves have sharper peaks and wider troughs. I try to change the sin waves.That is 1- abs(sin);

由于真实的浪波比较尖,波谷比较宽,博主右对sin波进行了小变换。就是1-(sin的绝对值),

Then we have the waves like the figure above, that’s more better than “Just sin”.

得到了这种波形,比普通的sin波好上许多。。。。

I will gonna to try the fragment shader water wish to have a better effect.

博主会继续研究fragment shader争取得到更好的效果,(= =;开学在即,在模电的煎熬中。。。逃太多了)

The waves here is over, the surf function will write in the second blog article, maybe I will write things about the refraction.

In the end, I wish you a happy spring festival, again.

波的研究结束了,具体的着色surf函数会在(二)中详细讨论,有关折射反射等等;

最后祝大家过个愉快的春节;

------------------------------by wolf96

前篇:unity3d 制造自己的水体water effect(一)

曲面细分:Unity3d 使用DX11的曲面细分

PBR:

讲求基本算法

Unity3d 基于物理渲染Physically-Based Rendering之specular BRDF

plus篇

Unity3d 基于物理渲染Physically-Based Rendering之实现
最终篇
Unity3d 基于物理渲染Physically-Based Rendering之最终篇
 

之前一直在用unity4.6写shader,终于下定决心换unity5,然后发现,unity5的渲染比4强太多,

这次完成之前2月份自制拖着没解决的normal问题,算出normal真的很简单。

本次水体分别使用两种波动算法,一个是ShaderX6 中Szecsi 和 Arman的算法,另一个是Gpu gems1里的Gerstner波算法。然后再用PBR渲染。然后还是曲面细分。

这次的效果:

Szecsi & Arman波动算法

首先来看ShaderX6 中的波动算法:

求波动速度,λ为波长,波长就是波峰到波峰之间的距离,速度v为每秒钟波峰移动的距离。

然后是相函数,k为波动方向,运动方向,垂直于波阵面的水平方向,p为position,t为时间(_Time.y)

求得一个波的位移S,a为振幅,振幅就是从水平面到波峰的高度。

最终我们的水是多个波组合在一起的,所以最终结果为:

博主整共合了4个波

关键代码如下:

                               vv = sqrt(_G * _Lambda / (2 * _PIE));
				psi = 2 * _PIE / _Lambda *(dot(v.vertex.xyz, _K.xyz) + vv*_Time.y);
				s = lerp(-cos(psi), sin(psi), _A)*0.05;
				p.y += s;
				vv = sqrt(_G * _Lambda2 / (2 * _PIE));
				psi = 2 * _PIE / _Lambda2 *(dot(v.vertex.xyz, _K2.xyz) + vv*_Time.y);
				s = lerp(-cos(psi), sin(psi), _A2)*0.05;

				p.y += s;

				vv = sqrt(_G * _Lambda3 / (2 * _PIE));
				psi = 2 * _PIE / _Lambda3 *(dot(v.vertex.xyz, _K3.xyz) + vv*_Time.y);
				s = lerp(-cos(psi), sin(psi), _A3)*0.1;

				p.y += s;

				vv = sqrt(_G * _Lambda4 / (2 * _PIE));
				psi = 2 * _PIE / _Lambda4 *(dot(v.vertex.xyz, _K4.xyz) + vv*_Time.y);
				s = lerp(-cos(psi), sin(psi), _A4)*0.1;

				p.y += s;

				v.vertex.xyz = p.xyz;</span>

产生了波动效果:

加上之前的pbr,可以模拟各种液体

牛奶

血,等等

但是由于曲面细分,离近了看水面上还是有小面的细节,这点有待解决。

Gerstner波

然后Gerstner波

关键代码如下:

  float wave(float x, float z, float timer)
    {
        float y = 0;
        float oct = _OCT;
        float fac = _FAC;
        float d = sqrt(x * x + z * z);// length(float2(x, z));
        for (oct; oct>0; oct--)
        {
            y -= fac * cos(timer * _SP + (1 / fac) * x * z * _WS);
            fac /= 2;  

        }
        return 2 * _VS * d * y;  

    }  </span>

曲面细分带来的小面不是很明显,而且面不用分得很细就能看到平滑的效果

normal的生成

最后我们讲讲normal的生成,

Normal的生成有复杂的和简单的,但本质上都是求偏导。

先看复杂的,来自GPU Gems1的42章

首先求出Jacobian

举个例子(直接截图了^ _ ^):

是不是很麻烦。。

法线本质上的求法就是这样的,但是,我们有函数:ddx,ddy这两个神器

我们只需要求出世界坐标点,worldpos

就可以简单地求出法线:

N = cross(ddx(worldpos),ddy(worldpos))

方法很简单,不过别忘记,本质上还是上面的一大串。。。

切记:ddx,ddy只能在fragment shader中使用。

只有漫反射的水体如下:

         --------   by wolf96 、

再分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!https://blog.csdn.net/jiangjunshow

原文地址:https://www.cnblogs.com/skiwnchiwns/p/10344089.html

时间: 2024-10-13 02:04:07

unity3d 制造自己的水体water effect的相关文章

unity3d 制造自己的水体water effect(二)

前篇:unity3d 制造自己的水体water effect(一) 曲面细分:Unity3d 使用DX11的曲面细分 PBR: 讲求基本算法 Unity3d 基于物理渲染Physically-Based Rendering之specular BRDF plus篇 Unity3d 基于物理渲染Physically-Based Rendering之实现 最终篇 Unity3d 基于物理渲染Physically-Based Rendering之最终篇 之前一直在用unity4.6写shader,终于下

unity3d 制造自己的水体water effect(一)

first,I wish you a happy new year, and study in spring festival's eve means you are hardworking,haha. I write in two languages. One passage write in Chineseone passage translate into English. My English is poor., If I write some thing wrong, welcome

water effect(1)

在GPU Gems1的第一小节中,可以看到通过Gerstner wave function来模拟海洋的波浪效果,同时在Unity自带的Water(Pro)效果中,FX/Water4中的部分水波效果正是通过该公式来模拟的. 首先来看看FX-Water4.shader的代码. Tags {"RenderType"="Transparent" "Queue"="Transparent"} Lod 500 ColorMask RGB

water effect(2)

这节主要记录的是第二个Subshader的具体效果,相对于的vert200, vert300顶点着色器主要会对mesh中的顶点进行变换,主要函数是Gerstner,根据gpugems第一小节的描述,Gerstner wave function是对 sin() 次方运算的简化版,具体公式如下,下面的条件中默认初始值为0. 其中A是坡度,即从低谷到高峰的高度值,W为波的频率值,即两个波峰之间的距离越小,W越大,D为波的方向向量,Q为控制波的程度.在unity中,WaterInclude.cginc的

Unity3d 实现顶点动画

在今年GDC上发现一个非常有趣的演讲,叫做Animating With Math,遂实现之,是讲述顶点shader动画的,举了几个经典的例子,但是讲者并没有给代码,而是像虚幻引擎那样的节点,这样更加清楚明了之前博主通过顶点着色器实现了水的波动算法: unity3d 制造自己的水体water effect(二) 顶点着色器动画可以减少动画的开销,并减少关节joint的数量开始举的例子都很简单,可以着手一试   关于vertex color是自定义的一个贴图,会控制各种参数下面会说明接下来的例子是一

进阶光照与材质之物体和材质

第四章主要介绍分析真实世界中某些常见材质的特性与细节,作者提醒我们应该时刻关注大自然真实世界中材质的特点,加强自己的思考与敏锐的观察力和感知力对渲染实现很有帮助.作者主要对如下材质进行了分析:塑料木头:树,木材,被油漆过的木材叶子和植物金属混凝土和石头:混凝土,砖石,自然界的石头皮肤头发和毛发大气半透明材质:玻璃,水油漆旧的磨损的材质 塑料  塑料有很多种颜色形状甚至有的上了不同的漆,但是它的材质构成是一致的.大部分塑料由白色或半透明的基质构成,这些基质充满了染色粒子,像下图这样 当 光照射到塑

(转)水面渲染小结

转自:http://blog.csdn.net/soilwork/article/details/1548490 水面渲染小结 本文版权归我所有,仅供个人学习使用,请勿转载,勿用于任何商业用途.由于本人水平有限,难免出错,欢迎大家和我交流.作者:claymanBlog:http://blog.csdn.net/soilwork[email protected] 从几何模型上来看,水面其实和地面是一样的,可以看做普通的均匀网格,不同点在于地形中,顶点高度是固定的,而水面是动态的.此外,对于水面来说

unity free asset

Unity Test Tools https://www.assetstore.unity3d.com/#/content/13802 Sample Assets (beta) https://www.assetstore.unity3d.com/#/content/14474 Unity Samples: Robot Lab https://www.assetstore.unity3d.com/#/content/7006 Stylized foliages pack https://www.

随便聊聊水面效果的2D实现(一)

0. 引子 一直想随便写写自己关于水面效果2D实现的一些了解,可惜各种原因一直拖沓,幸而近来有些事情终算告一段落,自己也有了一些闲暇时间,于是便有了这篇东西 :) 1. 概述 关于水面效果的实现方法,google一下非常之多,目前的很多游戏也有非常好的呈现,其中最令我印象深刻的当数<Crysis>~ 自己由于工作原因接触过一段时间的CryEngine,对于Crysis的水面渲染有一点点的了解,当然其中细节非常复杂,但就基本原理来讲,就是将整块水面细分成适当粒度的三角面,然后通过动态改变各个三角