首頁 default.html 參考了一個自己寫的 javascript 檔 Three.js,這是顯示背景銀河系並且讓地球轉動的主程式。網頁程式設計師應該已經很習慣將 javascript 鑲嵌到網頁之中,最常見的有在刪除資料前會有一個視窗提醒使用者是否要刪除,要使用者按確定鍵才開始作業,避免使用者誤按而刪錯資料。只是早期的 javascript 都很短,所以很自然的就會鑲嵌在 html 網頁中。但是到 Three.js 時,javascript 程式就很長,以 ThreeEarth.js 為例,共有 84 行,比首頁 default.html 的 41 行大很多,所以將之獨立出來。另外,javascript 與 html 語法並不相同,拆開之後比較不容易搞混。
讓我們來解析 ThreeEarth.js 程式:
第 2 行 function init() 對應首頁default.html呼叫的函數進入點。
第 3 行 var sceneEarth = new THREE.Scene(); 建立地球場景,javascript 和 C 一樣,大小寫有分,並且以分號 ; 結尾。
第 4 行 var sceneBG = new THREE.Scene(); 建立背景銀河系場景,本程式共有二個場景。
第 6行 var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);建立透視相機可以看見立體景象,用來看主體:地球,視角:45、長寬比: window.innerWidth /
window.innerHeight、近端:0.1、遠端:1000。
第 7 行 var cameraBG = new THREE.OrthographicCamera(-window.innerWidth, window.innerWidth, window.innerHeight, -window.innerHeight, -10000, 10000); 建立正攝相機所看到的是平面,用來看背景銀河,左邊界:-window.innerWidth、右邊界:window.innerWidth、上邊界:window.innerHeight 、下邊界:-window.innerHeight 、近端:10000、遠端:10000。
第 8 行 cameraBG.position.z = 50; 背景相機的z軸位置為 50。 Three.js 是使用右手作標系,背景相機是放在銀河系圖片的前方。
第 10 行 var webGLRenderer = new THREE.WebGLRenderer(); 。建立渲染器,用以繪製場景。
第 11 行 webGLRenderer.setClearColor(new THREE.Color(0x000, 1.0)); 設定背景為黑色,背景色透明度為不透明。
第 12 行 webGLRenderer.setSize(window.innerWidth, window.innerHeight); 設定為全螢幕。
第 13 行 webGLRenderer.shadowMapEnabled = true; 設定會產生陰影。
第 15 行 var sphere = createEarthMesh(new THREE.SphereGeometry(9, 80, 80)); 呼叫createEarthMesh 函數產生一個球體。半徑:9、垂直段:40、水平段:40,垂直段與水平段數字逾大鋸齒逾小。
第 16 行 sceneEarth.add(sphere); 將球體加入地球場景。
第 18~20 行 camera.position.x = -9;。。。 設定透視相機之位置。
第 22 行 camera.lookAt(new
THREE.Vector3(0, 0, 0)); 設定透視相機之觀看角度。
第 24 行 var orbitControls = new THREE.OrbitControls(camera); 建立orbitControls,這是讓地球可以用滑鼠或手指3D操控的關鍵。其實orbitControls是控制相機來提供視角變化,就像我們自己繞著物件,以不同的距離與角度看地球。
第 25 行 orbitControls.autoRotate = false; orbitControls設定為不自動旋轉,我們自己讓地球轉動。
第 27 行 var clock = new THREE.Clock(); 建立時鐘,為地球自轉鋪路。
第 29 行 var ambiLight = new THREE.AmbientLight(0x181818); 建立環境光用以照亮整個地球。
第 30 行 sceneEarth.add(ambiLight); 將環境光加入地球場景。
第 32 行 var sunLight = new THREE.DirectionalLight(0xffffff); 建立方向光模擬太陽照射地球。
第 33 行 sunLight.position.set(550, 100, 550); 設定方向光的位置為x:550、y:100、z:550。
第 34 行 sunLight.intensity = 1.0; 方向光的強度為 1.0。
第 35 行 sceneEarth.add(sunLight); 將方向光加入地球場景。
第 37~40 行 var materialBG = 。。。 建立背景材料,為銀河系圖片。
第 41 行 var bgPlane = new THREE.Mesh(new THREE.PlaneGeometry(1, 1), materialBG); 建立背景平面,寬:1、高:1,材料為背景材料。
第 42 行 bgPlane.position.z = -100; 背景平面的z軸位置為 -100。
第 43 行 bgPlane.scale.set(window.innerWidth * 2, window.innerHeight * 2, 1); 設定背景平面的大小。
第 44 行 sceneBG.add(bgPlane); 將背景平面加到背景場景。
第 46 行 document.getElementById("WebGL-output").appendChild(webGLRenderer.domElement);
將結果輸出到首頁 default.html 之WebGL-output
Tag 上。
第 48~49 行 var bgPass = new THREE.RenderPass(sceneBG, cameraBG); 。。。建立RenderPass透過這個通道渲染場景,但不會將結果直接輸出到螢幕。
第 50 行 renderPass.clear = false; 將環境光加入地球場景。
第 52 行 var shaderPass = new THREE.ShaderPass(THREE.CopyShader); 建立ShaderPass自定義著色器傳入了CopyShader著色器,用於拷貝渲染結果。
第 53 行 shaderPass.renderToScreen = true; 設定設置輸出到螢幕上。
第 55~58 行 var composer = new THREE.EffectComposer(webGLRenderer); 。。。建立效果組合器,將相關設定一一加到其中。
第 60 行 render(); 呼叫第 75 行 render()函數。
第 62~73 行 function createEarthMesh(geom) 。。。 本函數將三張地球圖紋理貼圖到球體,然後將結果回傳。
第 75 行 function render()。。。 建立render()函數。
第 76 行 webGLRenderer.autoClear = false; 設定不會自動清除畫面。
第 77 行 var delta = clock.getDelta(); 調用此次與上次的時間間隔。
第 78 行 orbitControls.update(delta); 更新照相機的位置。
第 79 行 sphere.rotation.y += 0.002; 讓地球自轉。
第 80 行 requestAnimationFrame(render); 定期調用 render函數,以產生動畫。
第 81 行 composer.render(delta); 用效果組合器來渲染螢幕。
沒有留言:
張貼留言