前篇: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 、

unity3d 制造自己的水体water effect(二)的更多相关文章

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

    first,I wish you a happy new year, and study in spring festival’s eve means you are hardworking,haha ...

  2. Unity3D新手教学,让你十二小时,从入门到掌握!(三 ) [转]

    版权声明:本文为Aries原创文章,转载请标明出处.如有不足之处欢迎提出意见或建议,联系QQ531193915 这一讲,我会教大家如何写碰撞检测的代码,然后还会教大家如何使用我介绍给大家的第一个Uni ...

  3. Unity3D新手教学,让你十二小时,从入门到掌握!(二) [转]

    版权声明:本文为Aries原创文章,转载请标明出处.如有不足之处欢迎提出意见或建议,联系QQ531193915 继续上一讲的内容,首先呢, 为了接下来要做的小游戏,在这里我要小小的修改一下移动的代码. ...

  4. Unity3D笔记 GUI 三、实现选项卡二窗口

    实现目标: 1.使用个性化Box控件 2.个性化Lable控件 3.添加纵向滚动条 4.新建SelectedItem样式 一.最终效果: 二.主要代码 using UnityEngine; using ...

  5. Unity3D之空间转换学习笔记(二):基础数学

    这期笔记我们专注Unity提供的各种数学相关的类来学习. 时间Time API文档地址:http://docs.unity3d.com/ScriptReference/Time.html 时间加/减速 ...

  6. unity3D中使用Socket进行数据通信(二)

    上一篇博客主要介绍了使用socket搭建服务端和client程序,这一篇来说说socket的数据传输,我们使用socket的目的是解决点对点之间的数据传输,之前提到了socket中一个重要的概念:po ...

  7. Unity3D新手教学,让你十二小时,从入门到掌握!(一) [转]

    http://blog.csdn.net/aries_h/article/details/47307799 版权声明:本文为Aries原创文章,转载请标明出处.如有不足之处欢迎提出意见或建议,联系QQ ...

  8. Unity3D制作3D虚拟漫游场景(二)

    传送门: Unity3D制作3D虚拟漫游场景(一) -------------------------------------------------------------------------- ...

  9. Unity3D框架插件uFrame实践记录(二)

    5.创建属性和命令 本小节主要内容包括: 在Element节点上创建属性数据 在Element节点上创建命令数据 5.1.在Element节点上创建属性数据 在这里,我们首先为Login节点中的属性( ...

随机推荐

  1. SqlServer 三级联动、递归表

    SqlServer 省市县三级联动 三张表递归合并成一张表sql如下: insert into table2(area_name,area_parent_id) select province,'0' ...

  2. ListView优化分页优化

    缘由 我们在用ListView展现数据的时候.比如展现联系人,如果联系人太多就会出现卡的现象,比如如果有1000多条数据,从数据库里查询,然后装载到List容器这段时间是比较耗时的.虽然我们可以用as ...

  3. A题笔记(9)

    No.2283 No.1387 vector<vector<char> > before, after; 可以创建一个容器的容器,注意 char 后的两个 “>” ,之间 ...

  4. C#常用的关键字

    常用关键字有 this 1)当前类的对象 2)调用自己的构造函数 new base virtual interface abstract override parttial sealed return ...

  5. 应用程序中小红点设置方法 (ios)

    我们的手机上常常会看到软件的右上角出现小红点,上面显示着你未读的消息数.下面是设置小红点的方法. 1.tabBar上按钮的小红点      因为小红点代表你未读的消息数,所以这个小红点上的数据不是凭空 ...

  6. 解决UICollectionView ReloadData闪一下(隐式动画)

    方式一: [UIView setAnimationsEnabled:NO]; [collectionView performBatchUpdates:^{ [collectionView reload ...

  7. C++专题 - WPS是什么

    WPS,1988年诞生自一个叫求伯君的24岁年轻人之手,市场占有率一度超过90%,这个产品也成就了这个年轻人.在中国大陆,金山软件公司在政府采购中多次击败微软公司,中国大陆很多政府机关部门.企业都装有 ...

  8. java获取远程网络图片文件流、压缩保存到本地

    1.获取远程网路的图片 /** * 根据地址获得数据的字节流 * * @param strUrl * 网络连接地址 * @return */ public static byte[] getImage ...

  9. Linux 消息队列编程

    消息队列.信号量以及共享内存被称作 XSI IPC,它们均来自system V的IPC功能,因此具有许多共性. 键和标识符: 内核中的每一种IPC结构(比如信号量.消息队列.共享内存)都用一个非负整数 ...

  10. 把AS代码链接到fla文件

    在属性里找到类,输入AS脚本的文件名然后点击右边的编辑就可以打开编辑AS脚本的界面,下面为链接代码. package { import flash.display.MovieClip; public ...