[Three.js]WebGL心形效果

 [Three.js]WebGL心形效果html

         本文實現效果參考自 Three.jsSparks.js的examples。若是你的瀏覽器支持WebGL,能夠點擊 這裏查看效果^^。
 
1、墊腳石

         WebGL,瀏覽器上的3D技術,基於OpenGL ES 2.0。基礎教程可見Hi,WebGL!Learning WebGLgit

         Three.js,WebGL的一個3D引擎庫。呃,有須要的,能夠看這一篇, Click here
 
2、單刀直入
1 )下載源碼
         附件!恩,能夠先打開html看看效果。
 
         查看源碼發現還有個Stats.js,是左上角統計FPS用的。
 
         瀏覽388行,運行入口,也基本肯定了咱們的實現流程。
 
  
  
           
  
  
  1. function threeStart() { 
  2.   initScene(); 
  3.   initParticles(); 
  4.   initShape(); 
  5.   initEmitter(); 
  6.   animate(); 
  7.  
  8. window.addEventListener('load', threeStart, false); 
 
2 )initScene ()
         瀏覽70行,上方先定義好了方法內要給外部用的變量,以後的方法都會如此。
         基本就這麼個流程:camera->scene->renderer[->stats]。
 
3 )initParticles()
3.1)着色器

         瀏覽121-147行,THREE .ShaderMaterial的定義,其中attributes, uniforms,對應於GLSL內的變量,其type類型,在WebGLRenderer.js內搜索‘switch ( type )’便可找到。Vertex Shader&Fragment Shader以下:github

  
  
           
  
  
  1. <!-- 頂點着色器 --> 
  2. <script type="x-shader/x-vertex" id="vertexshader">  
  3.     attribute float size
  4.     attribute vec3 ca; 
  5.  
  6.     varying vec3 vColor; 
  7.  
  8.     void main() { 
  9.         vColor = ca; 
  10.  
  11.         /* 
  12.          * 對於簡單構造的粒子,能夠用一個Object的各頂點表示粒子。 
  13.          * 利用gl_PointSize屬性設置每一個粒子大小。更快。 
  14.          */ 
  15.  
  16.         // 變換後的頂點座標 
  17.         vec4 mvPosition = modelViewMatrix * vec4(position, 1.0); 
  18.         // 頂點大小 
  19.         gl_PointSize = size * (200.0 / length(mvPosition.xyz)); 
  20.         // 輸出頂點世界座標 
  21.         gl_Position = projectionMatrix * mvPosition; 
  22.     } 
  23. </script>  
  24. <!-- 片元着色器 --> 
  25. <script type="x-shader/x-fragment" id="fragmentshader">  
  26.     uniform vec3 color; 
  27.     uniform sampler2D texture; 
  28.  
  29.     varying vec3 vColor; 
  30.      
  31.     void main() { 
  32.         // 用gl_PointCoord設置紋理,不是UV座標了 
  33.         vec4 outColor = texture2D(texture, gl_PointCoord); 
  34.         // 設定像素顏色 = 紋理顏色 * 頂點顏色 
  35.         gl_FragColor = outColor * vec4(color * vColor.xyz, 1.0); 
  36.  
  37.         // 計算像素世界座標z值 
  38.         float depth = gl_FragCoord.z / gl_FragCoord.w; 
  39.         // 霧顏色:黑 
  40.         const vec3 fogColor = vec3(0.0, 0.0, 0.0); 
  41.         // const vec3 fogColor = vec3(0xff, 0xff, 0xff); 
  42.         // 霧因素:depth<=200時0,>=600時1 
  43.         float fogFactor = smoothstep(200.0, 600.0, depth); 
  44.         // 混合霧的像素顏色 
  45.         gl_FragColor = mix(gl_FragColor, vec4(fogColor, gl_FragColor.w), fogFactor); 
  46.     } 
  47. </script> 
 
3.2)粒子初始化
         瀏覽149-178行,建立了一個幾何物體,初始定義了10000個頂點,至無限遠。當倉庫了,拿出來,用完,再放回去(再至爲無限遠)。
 
4 )initShape()
         221行開始,THREE.Shape()給它整成個心形。以後在365行,render()內,從[0,1]間取出它的位置,並賦值給發射器當前位置,以下:
 
  
  
           
  
  
  1. // 沿形狀路線運行 
  2. timeOnShapePath += 0.01; 
  3. if (timeOnShapePath > 1) timeOnShapePath -= 1; 
  4. var pointOnShape = heartShape.getPointAt(timeOnShapePath); 
  5.  
  6. emitterpos.x = pointOnShape.x * 2 - 50; 
  7. emitterpos.y = -pointOnShape.y * 2 + 100; 
 
5 )initEmitter()
         Sparks.js的使用了,237行。沒有本身的,就只能用用別人的了。還有它好久沒更新了。
 
6 )animate()
         用requestAnimationFrame反覆執行。其中render()處理變換,再渲染。stats.update(),便是左上角那插件的更新了。
 
         render()前一部分用以鼠標旋轉,與鼠標事件關聯。中間便是軌跡移動。還有如下三句,聲明頂點、大小、顏色都要更新。
 
  
  
           
  
  
  1. // 設置須要更新 
  2. group.geometry.verticesNeedUpdate = true// 頂點 
  3. attributes.size.needsUpdate = true// 大小 
  4. attributes.ca.needsUpdate = true// 顏色 
 
         其變化在initEmitter()內,Sparks.js的回調裏作了。但只有這裏聲明瞭須要更新,Three.js纔會更新着色器相應的變量值。
 
         最後句,以重複渲染場景。
 
3、說點啥
         說是有節日==。
相關文章
相關標籤/搜索