如果您想訂閱本博客內容,每天自動發(fā)到您的郵箱中, 請點這里
    
    
        我們都知道,three.js庫里面內置了很多著色器通道對象供我們渲染場景,本文將對EffectComposer、RenderPass、FilmPass這三個通道進行學習和實現:
    
    
        1.RenderPass這個通道會在當前場景(scene)和攝像機(camera)的基礎上渲染出一個新場景,新建:
    
    
        
        
            - 
                let renderPass = new THREE.RenderPass(scene, camera);  
            
 
        
     
    
        2.FilmPass這個通道通過掃描線和失真模擬電視屏幕效果,實現的效果超有時代感,新建:
    
    
        
        
            - 
                  
            
 
            - 
                let effectFilm = new THREE.FilmPass(0.8, 0.325, 256, false);  
            
 
            - 
                  
            
 
            - 
                effectFilm.renderToScreen = true;  
            
 
        
     
    
        3.EffectComposer可以理解為著色器通道容器,著色器通道按照先后順序添加進來并執(zhí)行,新建:
    
    
        
        
            - 
                  
            
 
            - 
                let composer = new THREE.EffectComposer(renderer);  
            
 
            - 
                composer.addPass(renderPass);  
            
 
            - 
                composer.addPass(effectFilm);  
            
 
        
     
    
        本文實現的demo基于three.js_r86(請自行下載),代碼所用js文件和圖片都在下載的那個包里面,請讀者自行引用。
    
    
        實現效果:
    
    
        
    

    
        代碼:
    
    
        
        
            - 
                <!DOCTYPE html>  
            
 
            - 
                <html lang="en">  
            
 
            - 
                <head>  
            
 
            - 
                    <meta charset="UTF-8">  
            
 
            - 
                    <title>shader_2_earth</title>  
            
 
            - 
                    <style>  
            
 
            - 
                        body{  
            
 
            - 
                            margin: 0;  
            
 
            - 
                            overflow: hidden;  
            
 
            - 
                        }  
            
 
            - 
                    </style>  
            
 
            - 
                </head>  
            
 
            - 
                <body>  
            
 
            - 
                <script src="build/three.js"></script>  
            
 
            - 
                <script src="js/libs/stats.min.js"></script>  
            
 
            - 
                <script src="js/libs/dat.gui.min.js"></script>  
            
 
            - 
                <script src="js/controls/OrbitControls.js"></script>  
            
 
            - 
                <script src="js/Detector.js"></script>  
            
 
            - 
                  
            
 
            - 
                <script src="js/postprocessing/EffectComposer.js"></script>  
            
 
            - 
                <script src="js/postprocessing/ShaderPass.js"></script>  
            
 
            - 
                <script src="js/postprocessing/MaskPass.js"></script>  
            
 
            - 
                <script src="js/postprocessing/FilmPass.js"></script>  
            
 
            - 
                <script src="js/postprocessing/BloomPass.js"></script>  
            
 
            - 
                <script src="js/postprocessing/RenderPass.js"></script>  
            
 
            - 
                  
            
 
            - 
                <script src="js/shaders/CopyShader.js"></script>  
            
 
            - 
                <script src="js/shaders/FilmShader.js"></script>  
            
 
            - 
                  
            
 
            - 
                <div id="stats"></div>  
            
 
            - 
                <div id="container"></div>  
            
 
            - 
                <script>  
            
 
            - 
                    //檢測webgl的兼容性  
            
 
            - 
                   if(!Detector.webgl) Detector.addGetWebGLMessage();  
            
 
            - 
                  
            
 
            - 
                   let scene;  
            
 
            - 
                   let camera, renderer, sphere, controls, stats;  
            
 
            - 
                   let ambientLight, spotLight;  
            
 
            - 
                   let composer;  
            
 
            - 
                   let clock;  
            
 
            - 
                  
            
 
            - 
                   main();  
            
 
            - 
                   render();  
            
 
            - 
                  
            
 
            - 
                   function main() {  
            
 
            - 
                       scene = new THREE.Scene();  
            
 
            - 
                  
            
 
            - 
                       camera = new THREE.PerspectiveCamera(45, window.innerWidth/window.innerHeight, 0.1, 1000);  
            
 
            - 
                       camera.position.set(-10, 15, 25);  
            
 
            - 
                       camera.lookAt(new THREE.Vector3(0, 0, 0));  
            
 
            - 
                  
            
 
            - 
                       renderer = new THREE.WebGLRenderer({antialias:true});  
            
 
            - 
                       renderer.setClearColor(new THREE.Color(0,0,0));  
            
 
            - 
                       renderer.setSize(window.innerWidth, window.innerHeight);  
            
 
            - 
                       renderer.shadowMapEnabled = true;  
            
 
            - 
                  
            
 
            - 
                       controls = new THREE.OrbitControls(camera);  
            
 
            - 
                       controls.autoRotate = false;  
            
 
            - 
                  
            
 
            - 
                       clock = new THREE.Clock();  
            
 
            - 
                  
            
 
            - 
                       ambientLight = new THREE.AmbientLight(0x181818);  
            
 
            - 
                       scene.add(ambientLight);  
            
 
            - 
                  
            
 
            - 
                       spotLight = new THREE.SpotLight(0xffffff);  
            
 
            - 
                       spotLight.position.set(550, 100, 550);  
            
 
            - 
                       spotLight.intensity = 0.6;  
            
 
            - 
                       scene.add(spotLight);  
            
 
            - 
                  
            
 
            - 
                       //創(chuàng)建地球  
            
 
            - 
                       sphere = createMesh(new THREE.SphereGeometry(10, 60, 60));  
            
 
            - 
                       scene.add(sphere);  
            
 
            - 
                  
            
 
            - 
                       document.getElementById("container").appendChild(renderer.domElement);  
            
 
            - 
                  
            
 
            - 
                       /**  
            
 
            - 
                        * 添加渲染通道  
            
 
            - 
                        */  
            
 
            - 
                       //在當前場景和攝像機的基礎上渲染一個新場景  
            
 
            - 
                       let renderPass = new THREE.RenderPass(scene, camera);  
            
 
            - 
                       //通過掃描線和失真來實現模擬電視屏幕的效果  
            
 
            - 
                       let effectFilm = new THREE.FilmPass(0.8, 0.325, 256, false);  
            
 
            - 
                       //將渲染結果輸出到屏幕  
            
 
            - 
                       effectFilm.renderToScreen = true;  
            
 
            - 
                  
            
 
            - 
                       //渲染效果組合器,每個通道都按照傳入的順序執(zhí)行  
            
 
            - 
                       composer = new THREE.EffectComposer(renderer);  
            
 
            - 
                       composer.addPass(renderPass);  
            
 
            - 
                       composer.addPass(effectFilm);  
            
 
            - 
                  
            
 
            - 
                       //菜單欄元素  
            
 
            - 
                       let guiFields = {  
            
 
            - 
                           "掃描線數量": 256,  
            
 
            - 
                           "灰度圖像": false,  
            
 
            - 
                           "掃描線強度": 0.3,  
            
 
            - 
                           "粗糙程度": 0.8,  
            
 
            - 
                           "updateEffectFilm": function () {  
            
 
            - 
                               effectFilm.uniforms.grayscale.value = guiFields.灰度圖像;  
            
 
            - 
                               effectFilm.uniforms.nIntensity.value = guiFields.粗糙程度;  
            
 
            - 
                               effectFilm.uniforms.sIntensity.value = guiFields.掃描線強度;  
            
 
            - 
                               effectFilm.uniforms.sCount.value = guiFields.掃描線數量;  
            
 
            - 
                           }  
            
 
            - 
                       };  
            
 
            - 
                  
            
 
            - 
                       //新建一個菜單欄  
            
 
            - 
                       let gui = new dat.GUI();  
            
 
            - 
                       gui.add(guiFields, "掃描線數量", 0, 2048).onChange(guiFields.updateEffectFilm);  
            
 
            - 
                       gui.add(guiFields, "掃描線強度", 0, 1).onChange(guiFields.updateEffectFilm);  
            
 
            - 
                       gui.add(guiFields, "粗糙程度", 0, 3).onChange(guiFields.updateEffectFilm);  
            
 
            - 
                       gui.add(guiFields, "灰度圖像").onChange(guiFields.updateEffectFilm);  
            
 
            - 
                  
            
 
            - 
                       stats = initStats();  
            
 
            - 
                   }  
            
 
            - 
                  
            
 
            - 
                   //創(chuàng)建一個Mesh  
            
 
            - 
                   function createMesh(geometry) {  
            
 
            - 
                  
            
 
            - 
                       //初始化紋理加載器  
            
 
            - 
                       let textureLoader = new THREE.TextureLoader();  
            
 
            - 
                       //加載圖片  
            
 
            - 
                       let uniforms = {  
            
 
            - 
                           planetTexture:{value:textureLoader.load("textures/planets/earth_atmos_2048.jpg")},  
            
 
            - 
                           specularTexture:{value:textureLoader.load("textures/planets/earth_specular_2048.jpg")},  
            
 
            - 
                           normalTexture:{value:textureLoader.load("textures/planets/earth_normal_2048.jpg")}  
            
 
            - 
                       };  
            
 
            - 
                  
            
 
            - 
                       //創(chuàng)建phong材料,并進行相應圖片的貼圖  
            
 
            - 
                       let planetMaterial = new THREE.MeshPhongMaterial();  
            
 
            - 
                       planetMaterial.specularMap = uniforms.specularTexture.value;  
            
 
            - 
                       planetMaterial.specular = new THREE.Color(0x4444aa);  
            
 
            - 
                  
            
 
            - 
                       planetMaterial.normalMap = uniforms.normalTexture.value;  
            
 
            - 
                       planetMaterial.map = uniforms.planetTexture.value;  
            
 
            - 
                  
            
 
            - 
                       //新建一個mesh  
            
 
            - 
                       let mesh = new THREE.SceneUtils.createMultiMaterialObject(geometry, [planetMaterial]);  
            
 
            - 
                  
            
 
            - 
                       return mesh;  
            
 
            - 
                   }  
            
 
            - 
                  
            
 
            - 
                   //渲染更新場景  
            
 
            - 
                  
            
 
            - 
                   function render() {  
            
 
            - 
                       stats.update();  
            
 
            - 
                       let delta = clock.getDelta();  
            
 
            - 
                       controls.update(delta);  
            
 
            - 
                       sphere.rotation.y += 0.002;  
            
 
            - 
                       requestAnimationFrame(render);  
            
 
            - 
                  
            
 
            - 
                       //沒有著色器通道系統(tǒng)默認為WebGLRenderer.render  
            
 
            - 
                       //使用著色器通道后,應使用使用composer.render  
            
 
            - 
                       composer.render(delta);  
            
 
            - 
                   }  
            
 
            - 
                  
            
 
            - 
                   //左上角幀顯示  
            
 
            - 
                   function initStats() {  
            
 
            - 
                       let stats = new Stats();  
            
 
            - 
                       stats.setMode(0);  
            
 
            - 
                       stats.domElement.style.position = 'absolute';  
            
 
            - 
                       stats.domElement.style.left = '0px';  
            
 
            - 
                       stats.domElement.style.top = '0px';  
            
 
            - 
                       document.getElementById("stats").appendChild(stats.domElement);  
            
 
            - 
                  
            
 
            - 
                       return stats;  
            
 
            - 
                   }  
            
 
            - 
                </script>  
            
 
            - 
                </body>  
            
 
            - 
                </html>  
            
 
        
     
藍藍設計( www.ynkmey.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業(yè)提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務