日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
WebGL實(shí)現(xiàn)雨水特效實(shí)驗(yàn)

今天我們將要和大家分享一些 WebGL 實(shí)驗(yàn),在這個(gè)實(shí)驗(yàn)中我們將創(chuàng)建一個(gè)非常逼真的雨滴效果,并把它放到不同的場(chǎng)景中去。在這篇文章中,我們將給出制作這種效果所用到的一些一般性技術(shù)和技巧的概覽。

目前創(chuàng)新互聯(lián)已為超過(guò)千家的企業(yè)提供了網(wǎng)站建設(shè)、域名、虛擬主機(jī)、綿陽(yáng)服務(wù)器托管、企業(yè)網(wǎng)站設(shè)計(jì)、東營(yíng)區(qū)網(wǎng)站維護(hù)等服務(wù),公司將堅(jiān)持客戶導(dǎo)向、應(yīng)用為本的策略,正道將秉承"和諧、參與、激情"的文化,與客戶和合作伙伴齊心協(xié)力一起成長(zhǎng),共同發(fā)展。

請(qǐng)注意:文中制作的效果還處于試驗(yàn)階段,可能無(wú)法在所有瀏覽器中都看到預(yù)期的效果。***使用 Chrome。

入門

如果我們想制作一個(gè)基于現(xiàn)實(shí)世界的效果,那么首先我們需要剖析一下它看起來(lái)究竟是什么樣子的,這樣制作出的效果才能顯得真實(shí)。如果你去找一些水滴落在窗戶上的圖片來(lái)看(當(dāng)然,你肯定已經(jīng)在生活中觀察過(guò)他們了),你會(huì)發(fā)現(xiàn)由于折射,雨滴似乎會(huì)把它后面的圖像上下顛倒。

圖片來(lái)源:Wikipedia, GGB reflection in raindrop

同時(shí)你還會(huì)看到相互之間距離很近的雨滴會(huì)合并成一個(gè)——而且如果超過(guò)了一定的尺寸,它就會(huì)向下滑落,并且留下一道小小的痕跡。

為了模擬這種行為,我們必須繪制大量的雨滴,在每一幀上都更新它們的折射效果,并且要在一個(gè)合適的幀率下做這些事情,為此我們需要極好的性能———所以,為了能夠使用顯卡的硬件加速,我們將使用 WebGL。

WebGL

WebGL 是一個(gè)繪制 2D 和 3D 圖形的 JavaScript 接口,并且允許使用 GPU 以獲得更好的性能。它基于 OpenGL ES,著色器由一門叫做 GLSL 的語(yǔ)言寫成,而不是 JS。

總之,如果你僅僅做過(guò)網(wǎng)頁(yè)開(kāi)發(fā),那么它看起來(lái)是很難使用的——這不僅僅是一門新的語(yǔ)言,而且還是一個(gè)全新的概念——但是一旦你掌握了一些核心的概念,它就會(huì)變得容易不少。

在這篇文章中我們將僅給出一些基本的使用示例,更多深入的解析請(qǐng)參閱 WebGl Fundamentals 。

首先我們需要一個(gè) canvas 標(biāo)簽。WebGL 是在 canvas 上繪制的,它是一個(gè)繪制環(huán)境,類似于我們用 getContext('2d') 獲取到的繪制環(huán)境。

 
 
 
 
  1.  
  2.  
  3.  
  4. var canvas = document.getElementById("container"); 
  5.  
  6. var gl = canvas.getContext("webgl"); 

接下來(lái)我們需要一段程序,它由頂點(diǎn)著色器和片段著色器(譯注:『片段著色器』又稱『像素著色器』)構(gòu)成。著色器就是一些函數(shù):頂點(diǎn)著色器在每個(gè)頂點(diǎn)執(zhí)行一次,而片段著色器在每個(gè)像素上都被調(diào)用一次。它們的任務(wù)分別是返回坐標(biāo)和顏色。這是我們的 WebGL 應(yīng)用的核心。

首先來(lái)創(chuàng)建我們的著色器。這是一個(gè)頂點(diǎn)著色器,我們不會(huì)對(duì)頂點(diǎn)做任何修改,所以簡(jiǎn)單地讓數(shù)據(jù)穿過(guò)它就好了:

 
 
 
 
  1.  

這個(gè)是片段著色器。這個(gè)著色器將會(huì)根據(jù)坐標(biāo)來(lái)設(shè)置每個(gè)像素點(diǎn)的顏色。

 
 
 
 
  1.  

現(xiàn)在我們把著色器連接到 WebGL 環(huán)境中去:

 
 
 
 
  1. function createShader(gl,source,type){ 
  2.  
  3. var shader = gl.createShader(type); 
  4.  
  5. source = document.getElementById(source).text; 
  6.  
  7. gl.shaderSource(shader, source); 
  8.  
  9. gl.compileShader(shader); 
  10.  
  11. return shader; 
  12.  
  13.  
  14. var vertexShader = createShader(gl, 'vert-shader', gl.VERTEX_SHADER); 
  15.  
  16. var fragShader = createShader(gl, 'frag-shader', gl.FRAGMENT_SHADER); 
  17.  
  18. var program = gl.createProgram(); 
  19.  
  20. gl.attachShader(program, vertexShader); 
  21.  
  22. gl.attachShader(program, fragShader); 
  23.  
  24. gl.linkProgram(program); 
  25.  
  26. gl.useProgram(program); 

接下來(lái)我們創(chuàng)建一個(gè)對(duì)象然后在它上面繪制我們的著色器。這里我們來(lái)畫個(gè)矩形——確切地說(shuō),畫兩個(gè)矩形。

 
 
 
 
  1. // create rectangle 
  2.  
  3. var buffer = gl.createBuffer(); 
  4.  
  5. gl.bindBuffer(gl.ARRAY_BUFFER, buffer); 
  6.  
  7. gl.bufferData( 
  8.  
  9. gl.ARRAY_BUFFER, 
  10.  
  11. new Float32Array([ 
  12.  
  13. -1.0, -1.0, 
  14.  
  15. 1.0, -1.0, 
  16.  
  17. -1.0, 1.0, 
  18.  
  19. -1.0, 1.0, 
  20.  
  21. 1.0, -1.0, 
  22.  
  23. 1.0, 1.0]), 
  24.  
  25. gl.STATIC_DRAW); 
  26.  
  27. // vertex data 
  28.  
  29. var positionLocation = gl.getAttribLocation(program, "a_position"); 
  30.  
  31. gl.enableVertexAttribArray(positionLocation); 
  32.  
  33. gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, 0, 0); 

***,繪制整個(gè)圖像:

 
 
 
 
  1. gl.drawArrays(gl.TRIANGLES, 0, 6); 

結(jié)果如下:

之后你可以盡情玩弄這些著色器以便搞明白它是怎么工作的。你可以在 ShaderToy 上找到很多很棒的著色器的例子。

雨滴

現(xiàn)在讓我們來(lái)看看如何制作雨滴的效果。首先我們來(lái)看一下單個(gè)的雨滴是什么樣的:

現(xiàn)在這里發(fā)生了很多事情。

Alpha 通道變成了這樣是因?yàn)槲覀兪褂昧祟愃朴谖恼?Creative Gooey Effects 中提到的一個(gè)技術(shù)來(lái)讓雨滴粘連到一起。

顏色變成這樣也是有原因的:我們使用了類似 法線貼圖 的技術(shù)來(lái)實(shí)現(xiàn)折射效果。我們將利用雨滴的顏色來(lái)獲取我們透過(guò)雨滴看到的貼圖的坐標(biāo)。這是沒(méi)有遮罩時(shí)它的樣子:

在這張圖片中,我們將通過(guò)綠色通道的數(shù)據(jù)來(lái)獲取 X 坐標(biāo),通過(guò)紅色通道的數(shù)據(jù)來(lái)獲取 Y 坐標(biāo)。

現(xiàn)在我們可以寫我們的著色器了,并且可以同時(shí)使用貼圖數(shù)據(jù)和雨滴的位置來(lái)翻轉(zhuǎn)并扭曲雨滴后方的貼圖了。

下雨過(guò)程

在創(chuàng)建雨滴之后,我們就可以開(kāi)始對(duì)下雨進(jìn)行模擬了。

讓雨點(diǎn)之間相互作用是很難快速計(jì)算的——隨著新的雨點(diǎn)的到來(lái),運(yùn)算量將會(huì)呈指數(shù)級(jí)增長(zhǎng)——所以我們必須做一點(diǎn)優(yōu)化。

在這個(gè)示例中,我把大雨點(diǎn)和小雨點(diǎn)分開(kāi)了。小雨點(diǎn)繪制在一個(gè)單獨(dú)的 canvas 上,并且沒(méi)有沒(méi)追蹤。這樣我就可以繪制上千個(gè)小雨滴而且不會(huì)讓速度有任何減慢。缺點(diǎn)是它們都是靜態(tài)的,而且由于我們每幀都在創(chuàng)建新雨滴,他們將會(huì)累積起來(lái)。為了修復(fù)這個(gè)問(wèn)題,我們將會(huì)使用大一點(diǎn)的雨滴。

由于大雨滴是會(huì)移動(dòng)的,于是我們可以利用它們來(lái)清除它們下方的小雨滴。擦除操作在 canvas 中比較麻煩:實(shí)際上我們還是要畫一些東西出來(lái),但是要使用 globalCompositeOperation='destination-out。因此,每當(dāng)一個(gè)大的雨滴移動(dòng),我們就會(huì)在小雨滴的 canvas 上繪制一個(gè)圓,并使用復(fù)合操作來(lái)清除這些雨滴,使效果更加逼真。

***,我們把所有這些繪制在一個(gè)大的 canvas 上,然后把它作為我們的 WebGL 著色器的貼圖。

為了把它做得更輕便一點(diǎn),我們要利用背景會(huì)失焦這一事實(shí),因此我們用了一個(gè)小尺寸的貼圖,然后把它放大。在 WebGL 中,貼圖的尺寸會(huì)直接影響到性能。我們需要用另外一個(gè)沒(méi)有失焦的貼圖來(lái)制作雨滴。模糊是一個(gè)代價(jià)很高的操作,實(shí)時(shí)的模糊處理應(yīng)該盡量避免掉——但是由于雨滴很小,我們可以把貼圖也變得很小。

總結(jié)

為了制作像雨滴這樣的逼真的效果,我們需要考慮很多復(fù)雜的細(xì)節(jié)。先將效果從現(xiàn)實(shí)世界中分離出來(lái)是重建任何一個(gè)效果的關(guān)鍵所在,一旦知道了它在現(xiàn)實(shí)世界中是如何工作的,我們就可以把它的行為映射到虛擬世界。有了 WebGL,我們可以獲得很高的性能(我們可以使用顯卡的硬件加速)因此對(duì)于這類效果,它是一個(gè)很不錯(cuò)的選擇。

希望各位喜歡這個(gè)實(shí)驗(yàn)并且受到啟發(fā)!

示例(http://tympanus.net/Development/RainEffect/)

源碼(http://tympanus.net/Development/RainEffect/RainEffect.zip)


新聞標(biāo)題:WebGL實(shí)現(xiàn)雨水特效實(shí)驗(yàn)
標(biāo)題來(lái)源:http://www.5511xx.com/article/dhoheei.html