unity3d 製造自己的水體water effect(二),unity3deffect

來源:互聯網
上載者:User

unity3d 製造自己的水體water effect(二),unity3deffect

前篇: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個波

關鍵代碼如下:

                               <span style="font-size:14px;"> 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波

 

關鍵代碼如下:

<span style="font-size:14px;">    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  http://blog.csdn.net/wolf96






著作權聲明:本文為博主原創文章,未經博主允許不得轉載。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.