-Three.js開發指南---用three.js創建你的第一個三維場景(第一章)


本章主要做了下面的工作

  1 生成一個簡單的場景,該場景的物體只有平面和坐標軸

  2 在第一個demo的基礎上添加光源和方塊物體,並生成陰影

  3 在第二個demo的基礎上,增加動畫,使得方塊進行旋轉

  4 在第三個demo的基礎上,增加圖形操作界面,改變方塊旋轉的速度

  5 在第四個demo的基礎上,我們使用ascII效果(這個沒有做出來,不知道為什么asciieffect沒有定義)

在下面的demo中,

  1 生成了場景,相機,渲染器,幾何體(平面),材質(幾何體和材質進行組合,組成物體),坐標軸,

  2 將相機,渲染器,物體都添加到場景中,

  3 然后再對場景和相機進行渲染

<!DOCTYPE html>

<html>

<head>
    <title>1</title>
    <script type="text/javascript" src="three.js"></script>
    <style>
        body {
            /* set margin to 0 and overflow to hidden, to go fullscreen */
            margin: 0;
            overflow: hidden;
        }
    </style>
</head>
<body>

<!-- Div which will hold the Output -->
<div id="WebGL-output">
</div>

<!-- Javascript code that runs our Three.js examples -->
<script type="text/javascript">

   function init() {
        var scene=new THREE.Scene();//生成一個場景
        //生成一個相機
        var camera=new THREE.PerspectiveCamera(45,window.innerWidth/window.innerHeight,0.1,1000);//視場,長寬比,近面,遠面
        camera.position.x=-20;
        camera.position.y=40;
        camera.position.z=30;
        camera.lookAt(scene.position);
        //生成一個渲染器
        var render=new THREE.WebGLRenderer();
        render.setClearColorHex(0xEEEEEE);
        render.setSize(window.innerWidth,window.innerHeight);
        //生成一個坐標軸,輔助線,坐標軸的參數
        var axes=new THREE.AxisHelper(20);
        //生成一個平面
        var planeGeometry=new THREE.PlaneGeometry(60,20,10,10);//注意參數
        //生成一個材質,設置材質的顏色,同時顯示線框
        var planeMaterial=new THREE.MeshBasicMaterial({color:0xcccccc,wireframe:true});
        //生成一個網格,將平面和材質放在一個網格中,組合在一起,組成一個物體
        var plane=new THREE.Mesh(planeGeometry,planeMaterial);
        plane.rotation.x=-0.5*Math.PI;
        plane.position.x=15;
        plane.position.y=0;
        plane.position.z=0;
        
        //將相機,渲染器,坐標軸,平面都追加到場景中,然后對場景和相機進行渲染
        scene.add(camera);
        scene.add(render);
        scene.add(axes);
        scene.add(plane);
        render.render(scene,camera);
        document.getElementById("WebGL-output").append(render.domElement);
    };
    window.onload = init;

</script>
</body>
</html>

 在下面的demo中,我們添加光源和設置物體陰影

  1 three.js中有兩種材質可以對光源產生反應,MeshLambertMaterialMeshPhongMaterial,所以我們將上面demo中的MeshBasicMaterial替換為另外一個材質MeshLambertMaterial

  2 我們設置點光源SpotLight

  3 由於陰影需要大量的計算資源,所以three.js默認是不生成陰影的,需要進行設置

    首先是渲染器,render.shadowMapEnabled=true

    其次是允許物體投射陰影,cube.castShadow=true;

    再其次是允許某些物體接受陰影,plane.receiveShadow=true

    最后是光源也要投射陰影,spot.castShadow=true

 

 
         
<!DOCTYPE html> <html> <head> <title>1</title> <script type="text/javascript" src="three.js"></script> <style> body { /* set margin to 0 and overflow to hidden, to go fullscreen */ margin: 0; overflow: hidden; } </style> </head> <body> <!-- Div which will hold the Output --> <div id="WebGL-output"> </div> <!-- Javascript code that runs our Three.js examples --> <script type="text/javascript"> function init() { var scene=new THREE.Scene();//生成一個場景 //生成一個相機 var camera=new THREE.PerspectiveCamera(45,window.innerWidth/window.innerHeight,0.1,1000);//視場,長寬比,近面,遠面  camera.position.x=-20; camera.position.y=40; camera.position.z=30; camera.lookAt(scene.position); //生成一個渲染器 var render=new THREE.WebGLRenderer(); render.setClearColorHex(0xEEEEEE); render.setSize(window.innerWidth,window.innerHeight); render.shadowMapEnabled=true;//允許陰影映射,渲染陰影需要大量的資源,因此我們需要告訴渲染器我們需要陰影 //生成一個坐標軸,輔助線 var axes=new THREE.AxisHelper(20); //生成一個平面 var planeGeometry=new THREE.PlaneGeometry(60,20,10,10);//平面 //生成一個材質 var planeMaterial=new THREE.MeshLambertMaterial({color:0xffffff}); //生成一個網格,將平面和材質放在一個網格中,組合在一起,組成一個物體 var plane=new THREE.Mesh(planeGeometry,planeMaterial); plane.rotation.x=-0.5*Math.PI;//將平面沿着x軸進行旋轉  plane.position.x=0; plane.position.y=0; plane.position.z=0; plane.receiveShadow=true;//平面進行接受陰影 var cubeGeometry=new THREE.CubeGeometry(10,10,10); var planeMaterial1=new THREE.MeshLambertMaterial({color:0xff0000}); var cube=new THREE.Mesh(cubeGeometry,planeMaterial1); //plane1.rotation.x=-0.5*Math.PI;//將平面沿着x軸進行旋轉 cube.position.x=-4; cube.position.y=3; cube.position.z=0; cube.castShadow=true;//需要陰影,方塊進行投射陰影 var spotLight=new THREE.SpotLight(0xffffff); spotLight.position.set(-40,60,-10); spotLight.castShadow=true; //將相機,渲染器,坐標軸,平面都追加到場景中,然后對場景和相機進行渲染 scene.add(camera); scene.add(render); scene.add(axes); scene.add(plane); scene.add(cube); scene.add(spotLight); render.render(scene,camera); document.getElementById("WebGL-output").append(render.domElement); }; window.onload = init; </script> </body> </html>
 

在下面demo中,我們引入動畫

  讓場景每隔一段時間進行一次渲染,setInterval方法會指定時間進行一次函數調用,

  但是該方法並不考慮瀏覽器發生的事情,即使你正在瀏覽其他頁面,該方法仍然會每隔固定的時間進行一次調用,

  另外該方法並沒有跟顯示器的重新繪制同步,這將導致較高的cpu使用率

  現在的瀏覽器有了requestAnimationFrame方法

<!DOCTYPE html>

<html>

<head>
    <title>1</title>
    <script type="text/javascript" src="three.js"></script>
    <style>
        body {
            /* set margin to 0 and overflow to hidden, to go fullscreen */
            margin: 0;
            overflow: hidden;
        }
    </style>
</head>
<body>

<!-- Div which will hold the Output -->
<div id="WebGL-output">
</div>

<!-- Javascript code that runs our Three.js examples -->
<script type="text/javascript">

   function init() {
        var scene=new THREE.Scene();//生成一個場景
        //生成一個相機
        var camera=new THREE.PerspectiveCamera(45,window.innerWidth/window.innerHeight,0.1,1000);//視場,長寬比,近面,遠面
        camera.position.x=-20;
        camera.position.y=40;
        camera.position.z=30;
        camera.lookAt(scene.position);
        //生成一個渲染器
        var render=new THREE.WebGLRenderer();
        render.setClearColorHex(0xEEEEEE);
        render.setSize(window.innerWidth,window.innerHeight);
        render.shadowMapEnabled=true;//允許陰影映射,渲染陰影需要大量的資源,因此我們需要告訴渲染器我們需要陰影
        
        
        //生成一個坐標軸,輔助線
        var axes=new THREE.AxisHelper(20);
        //生成一個平面
        var planeGeometry=new THREE.PlaneGeometry(60,20,10,10);//平面
        //生成一個材質
        var planeMaterial=new THREE.MeshLambertMaterial({color:0xffffff});
        //生成一個網格,將平面和材質放在一個網格中,組合在一起,組成一個物體
        var plane=new THREE.Mesh(planeGeometry,planeMaterial);
        plane.rotation.x=-0.5*Math.PI;//將平面沿着x軸進行旋轉
        plane.position.x=0;
        plane.position.y=0;
        plane.position.z=0;
        plane.receiveShadow=true;//平面進行接受陰影
        
        var cubeGeometry=new THREE.CubeGeometry(10,10,10);
        var planeMaterial1=new THREE.MeshLambertMaterial({color:0xff0000});
        var cube=new THREE.Mesh(cubeGeometry,planeMaterial1);
        //plane1.rotation.x=-0.5*Math.PI;//將平面沿着x軸進行旋轉
        cube.position.x=-4;
        cube.position.y=3;
        cube.position.z=0;
        cube.castShadow=true;//需要陰影,方塊進行投射陰影
        
        
        var spotLight=new THREE.SpotLight(0xffffff);
        spotLight.position.set(-40,60,-10);
        spotLight.castShadow=true;
        //將相機,渲染器,坐標軸,平面都追加到場景中,然后對場景和相機進行渲染
        scene.add(camera);
        scene.add(render);
        scene.add(axes);
        scene.add(plane);
        scene.add(cube);
        scene.add(spotLight);
        
        document.getElementById("WebGL-output").append(render.domElement);
         renderScene();

        function renderScene(){
            cube.rotation.x+=0.02;
            cube.rotation.y+=0.02;
            cube.rotation.z+=0.02;
            requestAnimationFrame(renderScene);
            render.render(scene,camera);
        }
        
        
    }
    window.onload = init;

</script>
</body>
</html>

 

 

我們使用google創建的dat.GUI庫創建一個簡單的界面,來控制方塊旋轉的速度

   1 首先引入google的dat.gui.js文件

  2 生成一個gui對象

  3 定義一個js對象controls,然后再將controls對象傳遞給dat.gui對象

<!DOCTYPE html>

<html>

<head>
    <title>1</title>
    <script type="text/javascript" src="three.js"></script>
    <script type="text/javascript" src="dat.gui.js"></script>
    <style>
        body {
            /* set margin to 0 and overflow to hidden, to go fullscreen */
            margin: 0;
            overflow: hidden;
        }
    </style>
</head>
<body>

<!-- Div which will hold the Output -->
<div id="WebGL-output">
</div>

<!-- Javascript code that runs our Three.js examples -->
<script type="text/javascript">

   function init() {
        var scene=new THREE.Scene();//生成一個場景
        //生成一個相機
        var camera=new THREE.PerspectiveCamera(45,window.innerWidth/window.innerHeight,0.1,1000);//視場,長寬比,近面,遠面
        camera.position.x=-20;
        camera.position.y=40;
        camera.position.z=30;
        camera.lookAt(scene.position);
        //生成一個渲染器
        var render=new THREE.WebGLRenderer();
        render.setClearColorHex(0xEEEEEE);
        render.setSize(window.innerWidth,window.innerHeight);
        render.shadowMapEnabled=true;//允許陰影映射,渲染陰影需要大量的資源,因此我們需要告訴渲染器我們需要陰影
        
        
        //生成一個坐標軸,輔助線
        var axes=new THREE.AxisHelper(20);
        //生成一個平面
        var planeGeometry=new THREE.PlaneGeometry(60,20,10,10);//平面
        //生成一個材質
        var planeMaterial=new THREE.MeshLambertMaterial({color:0xffffff});
        //生成一個網格,將平面和材質放在一個網格中,組合在一起,組成一個物體
        var plane=new THREE.Mesh(planeGeometry,planeMaterial);
        plane.rotation.x=-0.5*Math.PI;//將平面沿着x軸進行旋轉
        plane.position.x=0;
        plane.position.y=0;
        plane.position.z=0;
        plane.receiveShadow=true;//平面進行接受陰影
        
        var cubeGeometry=new THREE.CubeGeometry(10,10,10);
        var planeMaterial1=new THREE.MeshLambertMaterial({color:0xff0000});
        var cube=new THREE.Mesh(cubeGeometry,planeMaterial1);
        //plane1.rotation.x=-0.5*Math.PI;//將平面沿着x軸進行旋轉
        cube.position.x=-4;
        cube.position.y=3;
        cube.position.z=0;
        cube.castShadow=true;//需要陰影,方塊進行投射陰影
        
        
        var spotLight=new THREE.SpotLight(0xffffff);
        spotLight.position.set(-40,60,-10);
        spotLight.castShadow=true;
        //將相機,渲染器,坐標軸,平面都追加到場景中,然后對場景和相機進行渲染
        scene.add(camera);
        scene.add(render);
        scene.add(axes);
        scene.add(plane);
        scene.add(cube);
        scene.add(spotLight);
        
        document.getElementById("WebGL-output").append(render.domElement);
        renderScene();
        
        function renderScene(){
            cube.rotation.x+=controls.rotationSpeed;
            cube.rotation.y+=controls.rotationSpeed;
            cube.rotation.z+=controls.rotationSpeed;
            requestAnimationFrame(renderScene);
            render.render(scene,camera);
        }
    }
    var controls=new function(){ this.rotationSpeed=0.02; }; var gui=new dat.GUI(); gui.add(controls,"rotationSpeed",0,0.5); window.onload = init; </script>
</body>
</html>

 

 

 

 

 ASCII效果

  1 引入AsciiEffect.js

  2 生成一個ascii效果

  3 頁面追加的domElement由渲染器的domElement改成ascii效果的domelement

  4 render的話就使用effect的render進行渲染

<!DOCTYPE html>

<html>

<head>
    <title>1</title>
    <script type="text/javascript" src="three.js"></script>
    <script type="text/javascript" src="dat.gui.js"></script>
    <script type="text/javascript" src="AsciiEffect.js"></script>
    <style>
        body {
            /* set margin to 0 and overflow to hidden, to go fullscreen */
            margin: 0;
            overflow: hidden;
        }
    </style>
</head>
<body>

<!-- Div which will hold the Output -->
<div id="WebGL-output">
</div>

<!-- Javascript code that runs our Three.js examples -->
<script type="text/javascript">

   function init() {
        var scene=new THREE.Scene();//生成一個場景
        //生成一個相機
        var camera=new THREE.PerspectiveCamera(45,window.innerWidth/window.innerHeight,0.1,1000);//視場,長寬比,近面,遠面
        camera.position.x=-20;
        camera.position.y=40;
        camera.position.z=30;
        camera.lookAt(scene.position);
        //生成一個渲染器
        var render=new THREE.WebGLRenderer();
        render.setClearColorHex(0xEEEEEE);
        render.setSize(window.innerWidth,window.innerHeight);
        render.shadowMapEnabled=true;//允許陰影映射,渲染陰影需要大量的資源,因此我們需要告訴渲染器我們需要陰影
        
        
        //生成一個坐標軸,輔助線
        var axes=new THREE.AxisHelper(20);
        //生成一個平面
        var planeGeometry=new THREE.PlaneGeometry(60,20,10,10);//平面
        //生成一個材質
        var planeMaterial=new THREE.MeshLambertMaterial({color:0xffffff});
        //生成一個網格,將平面和材質放在一個網格中,組合在一起,組成一個物體
        var plane=new THREE.Mesh(planeGeometry,planeMaterial);
        plane.rotation.x=-0.5*Math.PI;//將平面沿着x軸進行旋轉
        plane.position.x=0;
        plane.position.y=0;
        plane.position.z=0;
        plane.receiveShadow=true;//平面進行接受陰影
        
        var cubeGeometry=new THREE.CubeGeometry(10,10,10);
        var planeMaterial1=new THREE.MeshLambertMaterial({color:0xff0000});
        var cube=new THREE.Mesh(cubeGeometry,planeMaterial1);
        //plane1.rotation.x=-0.5*Math.PI;//將平面沿着x軸進行旋轉
        cube.position.x=-4;
        cube.position.y=3;
        cube.position.z=0;
        cube.castShadow=true;//需要陰影,方塊進行投射陰影
        
        
        var spotLight=new THREE.SpotLight(0xffffff);
        spotLight.position.set(-40,60,-10);
        spotLight.castShadow=true;
        //將相機,渲染器,坐標軸,平面都追加到場景中,然后對場景和相機進行渲染
        scene.add(camera);
        scene.add(render);
        scene.add(axes);
        scene.add(plane);
        scene.add(cube);
        scene.add(spotLight);
        var effect=new THREE.AsciiEffect(render); effect.setSize(window.innerWidth,window.innerHeight); document.getElementById("WebGL-output").append(effect.domElement);
        renderScene();
        
        function renderScene(){
            cube.rotation.x+=controls.rotationSpeed;
            cube.rotation.y+=controls.rotationSpeed;
            cube.rotation.z+=controls.rotationSpeed;
            requestAnimationFrame(renderScene);
            effect.render(scene,camera);
        }
        
        
    }
    var controls=new function(){
            this.rotationSpeed=0.02;
    };
    var gui=new dat.GUI();
    gui.add(controls,"rotationSpeed",0,0.5);
    window.onload = init;

</script>
</body>
</html>

 

 

 

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM