<address id="ttjl9"></address>

      <noframes id="ttjl9"><address id="ttjl9"><nobr id="ttjl9"></nobr></address>
      <form id="ttjl9"></form>
        <em id="ttjl9"><span id="ttjl9"></span></em>
        <address id="ttjl9"></address>

          <noframes id="ttjl9"><form id="ttjl9"></form>

          使用three.js的著色器通道渲染地球模型

          2018-5-11    seo達人

          如果您想訂閱本博客內容,每天自動發到您的郵箱中, 請點這里

          我們都知道,three.js庫里面內置了很多著色器通道對象供我們渲染場景,本文將對EffectComposer、RenderPass、FilmPass這三個通道進行學習和實現:

          1.RenderPass這個通道會在當前場景(scene)和攝像機(camera)的基礎上渲染出一個新場景,新建:

          [javascript] view plain copy
          1. let renderPass = new THREE.RenderPass(scene, camera);  

          2.FilmPass這個通道通過掃描線和失真模擬電視屏幕效果,實現的效果超有時代感,新建:

          [javascript] view plain copy
          1. /*四個參數分別為粗糙程度,掃描線強度,掃描線數量,是否轉換為灰度圖*/  
          2. let effectFilm = new THREE.FilmPass(0.8, 0.325, 256, false);  
          3. //將渲染結果輸出到屏幕  
          4. effectFilm.renderToScreen = true;  

          3.EffectComposer可以理解為著色器通道容器,著色器通道按照先后順序添加進來并執行,新建:

          [javascript] view plain copy
          1. /*渲染效果組合器,每個通道都按照傳入的順序執行*/  
          2. let composer = new THREE.EffectComposer(renderer);  
          3. composer.addPass(renderPass);  
          4. composer.addPass(effectFilm);  

          本文實現的demo基于three.js_r86(請自行下載),代碼所用js文件和圖片都在下載的那個包里面,請讀者自行引用。

          實現效果:



          代碼:

          [html] view plain copy
          1. <!DOCTYPE html>  
          2. <html lang="en">  
          3. <head>  
          4.     <meta charset="UTF-8">  
          5.     <title>shader_2_earth</title>  
          6.     <style>  
          7.         body{  
          8.             margin: 0;  
          9.             overflow: hidden;  
          10.         }  
          11.     </style>  
          12. </head>  
          13. <body>  
          14. <script src="build/three.js"></script>  
          15. <script src="js/libs/stats.min.js"></script>  
          16. <script src="js/libs/dat.gui.min.js"></script>  
          17. <script src="js/controls/OrbitControls.js"></script>  
          18. <script src="js/Detector.js"></script>  
          19.   
          20. <script src="js/postprocessing/EffectComposer.js"></script>  
          21. <script src="js/postprocessing/ShaderPass.js"></script>  
          22. <script src="js/postprocessing/MaskPass.js"></script>  
          23. <script src="js/postprocessing/FilmPass.js"></script>  
          24. <script src="js/postprocessing/BloomPass.js"></script>  
          25. <script src="js/postprocessing/RenderPass.js"></script>  
          26.   
          27. <script src="js/shaders/CopyShader.js"></script>  
          28. <script src="js/shaders/FilmShader.js"></script>  
          29.   
          30. <div id="stats"></div>  
          31. <div id="container"></div>  
          32. <script>  
          33.     //檢測webgl的兼容性  
          34.    if(!Detector.webgl) Detector.addGetWebGLMessage();  
          35.   
          36.    let scene;  
          37.    let camera, renderer, sphere, controls, stats;  
          38.    let ambientLight, spotLight;  
          39.    let composer;  
          40.    let clock;  
          41.   
          42.    main();  
          43.    render();  
          44.   
          45.    function main() {  
          46.        scene = new THREE.Scene();  
          47.   
          48.        camera = new THREE.PerspectiveCamera(45, window.innerWidth/window.innerHeight, 0.1, 1000);  
          49.        camera.position.set(-10, 15, 25);  
          50.        camera.lookAt(new THREE.Vector3(0, 0, 0));  
          51.   
          52.        renderer = new THREE.WebGLRenderer({antialias:true});  
          53.        renderer.setClearColor(new THREE.Color(0,0,0));  
          54.        renderer.setSize(window.innerWidth, window.innerHeight);  
          55.        renderer.shadowMapEnabled = true;  
          56.   
          57.        controls = new THREE.OrbitControls(camera);  
          58.        controls.autoRotate = false;  
          59.   
          60.        clock = new THREE.Clock();  
          61.   
          62.        ambientLight = new THREE.AmbientLight(0x181818);  
          63.        scene.add(ambientLight);  
          64.   
          65.        spotLight = new THREE.SpotLight(0xffffff);  
          66.        spotLight.position.set(550, 100, 550);  
          67.        spotLight.intensity = 0.6;  
          68.        scene.add(spotLight);  
          69.   
          70.        //創建地球  
          71.        sphere = createMesh(new THREE.SphereGeometry(10, 60, 60));  
          72.        scene.add(sphere);  
          73.   
          74.        document.getElementById("container").appendChild(renderer.domElement);  
          75.   
          76.        /**  
          77.         * 添加渲染通道  
          78.         */  
          79.        //在當前場景和攝像機的基礎上渲染一個新場景  
          80.        let renderPass = new THREE.RenderPass(scene, camera);  
          81.        //通過掃描線和失真來實現模擬電視屏幕的效果  
          82.        let effectFilm = new THREE.FilmPass(0.8, 0.325, 256, false);  
          83.        //將渲染結果輸出到屏幕  
          84.        effectFilm.renderToScreen = true;  
          85.   
          86.        //渲染效果組合器,每個通道都按照傳入的順序執行  
          87.        composer = new THREE.EffectComposer(renderer);  
          88.        composer.addPass(renderPass);  
          89.        composer.addPass(effectFilm);  
          90.   
          91.        //菜單欄元素  
          92.        let guiFields = {  
          93.            "掃描線數量": 256,  
          94.            "灰度圖像": false,  
          95.            "掃描線強度": 0.3,  
          96.            "粗糙程度": 0.8,  
          97.            "updateEffectFilm": function () {  
          98.                effectFilm.uniforms.grayscale.value = guiFields.灰度圖像;  
          99.                effectFilm.uniforms.nIntensity.value = guiFields.粗糙程度;  
          100.                effectFilm.uniforms.sIntensity.value = guiFields.掃描線強度;  
          101.                effectFilm.uniforms.sCount.value = guiFields.掃描線數量;  
          102.            }  
          103.        };  
          104.   
          105.        //新建一個菜單欄  
          106.        let gui = new dat.GUI();  
          107.        gui.add(guiFields, "掃描線數量", 0, 2048).onChange(guiFields.updateEffectFilm);  
          108.        gui.add(guiFields, "掃描線強度", 0, 1).onChange(guiFields.updateEffectFilm);  
          109.        gui.add(guiFields, "粗糙程度", 0, 3).onChange(guiFields.updateEffectFilm);  
          110.        gui.add(guiFields, "灰度圖像").onChange(guiFields.updateEffectFilm);  
          111.   
          112.        stats = initStats();  
          113.    }  
          114.   
          115.    //創建一個Mesh  
          116.    function createMesh(geometry) {  
          117.   
          118.        //初始化紋理加載器  
          119.        let textureLoader = new THREE.TextureLoader();  
          120.        //加載圖片  
          121.        let uniforms = {  
          122.            planetTexture:{value:textureLoader.load("textures/planets/earth_atmos_2048.jpg")},  
          123.            specularTexture:{value:textureLoader.load("textures/planets/earth_specular_2048.jpg")},  
          124.            normalTexture:{value:textureLoader.load("textures/planets/earth_normal_2048.jpg")}  
          125.        };  
          126.   
          127.        //創建phong材料,并進行相應圖片的貼圖  
          128.        let planetMaterial = new THREE.MeshPhongMaterial();  
          129.        planetMaterial.specularMap = uniforms.specularTexture.value;  
          130.        planetMaterial.specular = new THREE.Color(0x4444aa);  
          131.   
          132.        planetMaterial.normalMap = uniforms.normalTexture.value;  
          133.        planetMaterial.map = uniforms.planetTexture.value;  
          134.   
          135.        //新建一個mesh  
          136.        let mesh = new THREE.SceneUtils.createMultiMaterialObject(geometry, [planetMaterial]);  
          137.   
          138.        return mesh;  
          139.    }  
          140.   
          141.    //渲染更新場景  
          142.   
          143.    function render() {  
          144.        stats.update();  
          145.        let delta = clock.getDelta();  
          146.        controls.update(delta);  
          147.        sphere.rotation.y += 0.002;  
          148.        requestAnimationFrame(render);  
          149.   
          150.        //沒有著色器通道系統默認為WebGLRenderer.render  
          151.        //使用著色器通道后,應使用使用composer.render  
          152.        composer.render(delta);  
          153.    }  
          154.   
          155.    //左上角幀顯示  
          156.    function initStats() {  
          157.        let stats = new Stats();  
          158.        stats.setMode(0);  
          159.        stats.domElement.style.position = 'absolute';  
          160.        stats.domElement.style.left = '0px';  
          161.        stats.domElement.style.top = '0px';  
          162.        document.getElementById("stats").appendChild(stats.domElement);  
          163.   
          164.        return stats;  
          165.    }  
          166. </script>  
          167. </body>  
          168. </html>  
          藍藍設計www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 平面設計服務

          日歷

          鏈接

          個人資料

          藍藍設計的小編 http://www.syprn.cn

          存檔

          亚洲va欧美va天堂v国产综合