4、对正投影相机以及透视相机的使用,以及对场景通过鼠标控制大小以及旋转

<pre name="code" class="javascript"><!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>canvas_camera_orthographinc</title>
    <style>
        body {
            font-family:'宋体';//设置body区域显示的字体
        background-color: #f0f0f0;//设置body的背景颜色
        margin: 0px;//设置body的边距
        overflow: hidden;//overflow表示溢出元素需要做的处理,hidden表示内容会被修剪,并且其余内容是不可见的。
        }
    </style>
</head>
<body>
<script src="three.js-master/build/three.js"></script>
<script src="three.js-master/build/renderers/Projector.js"></script>
<script src="three.js-master/build/renderers/CanvasRenderer.js"></script>
<script src="three.js-master/build/controls/OrbitControls.js"></script>

<script>
    var rendererCanvas,scene,camera,light;
    function initRenderer()
    {
        rendererCanvas=new THREE.CanvasRenderer();                      //创建一个基于canvas的渲染器
        rendererCanvas.setSize( window.innerWidth, window.innerHeight );//设置渲染器的大小
        document.body.appendChild(rendererCanvas.domElement);           //将渲染器添加到body区域
        rendererCanvas.setClearColor(0xffffff);                         //设置渲染器的背景颜色为白色
    }
    function initScene()
    {
        scene=new THREE.Scene();//创建一个场景
    }
    function initCamera()
    {
        //创建一个正投影相机照相机
        camera = new THREE.OrthographicCamera( window.innerWidth / - 2, window.innerWidth / 2, window.innerHeight / 2, window.innerHeight / - 2, - 500, 1000 );
        //camera=new THREE.PerspectiveCamera(70,window.innerWidth/window.innerHeight,1,1000);//创建透视照相机
        camera.position.x = 200;
        camera.position.y = 100;
        camera.position.z = 200;//设置相机的位置
        camera.lookAt(scene.position);//将相机固定在scene.position所指向的位置
        scene.add(camera);//将相机加到场景中去
    }
    function initLight()
    {
        var ambientLight = new THREE.AmbientLight(0x0000FF);//创建一个环境光,光为蓝色
        scene.add( ambientLight );
    }
    function initGeometry()
    {
        var geometry=new THREE.Geometry();
        /*
        在画网格时,需要提供四个坐标点,然后使用LineBasicMaterial根据坐标点画线段,如:
        1、(-500,0,500)在空间坐标系中,该坐标点在第四象限
        2、(500,0,500)在空间坐标系中,该坐标点在第一象限
        3、(500,0,500)与第二个点坐标相同
        4、(500,0,-500)在空间坐标系中,该坐标点在第二象限
        如:
                              (-500,0,-500)    (-300,0,-500)  (-100,0,-500)    (100,0,-500)    (300,0,-500)    (500,0,-500)
                       (-500,0,-500)/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/(500,0,-500)
                      (-500,0,-450)/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/(500,0,-450)
                     (-500,0,-400)/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/(500,0,-400)
                    (-500,0,-350)/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/(500,0,-350)
                   (-500,0,-300)/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/(500,0,-300)
                  (-500,0,-250)/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/(500,0,-250)
                 (-500,0,-200)/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/(500,0,-200)
                (-500,0,-150)/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/(500,0,-150)
               (-500,0,-100)/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/(500,0,-100)
              (-500,0, -50)/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/(500,0,-50)
             (-500,0,   0)/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/(500,0,0)
             (-500,0, 50)/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/(500,0,50)
            (-500,0,100)/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/(500,0,100)
           (-500,0,150)/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/(500,0,150)
          (-500,0,200)/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/(500,0,200)
         (-500,0,250)/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/(500,0,250)
        (-500,0,300)/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/(500,0,300)
       (-500,0,350)/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/(500,0,350)
      (-500,0,400)/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/(500,0,400)
     (-500,0,450)/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/(500,0,450)
    (-500,0,500)/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/(500,0,500)
          (-500,0,500)(-350,0,500)(-200,0,500)(-50,0,500)  (100,0,500) (250,0,500) (400,0,500)(500,0,500)                                                 
        */
        var size=500,step=50;
        for(var i=-size;i<=size;i+=step)
        {
            geometry.vertices.push(new THREE.Vector3(-size,0,-i));
            geometry.vertices.push(new THREE.Vector3(size,0,-i));
            geometry.vertices.push(new THREE.Vector3(-i,0,size));
            geometry.vertices.push(new THREE.Vector3(-i,0,-size));
        }
        var material=new THREE.LineBasicMaterial({color:0x000000,opacity:0.5});//创建一个颜色为黑色,线条透明度为0.5
        var line=new THREE.LineSegments(geometry,material);
        scene.add(line);

        var geometry1 = new THREE.BoxGeometry( 50, 50, 50 );//创建一个立方体
        var material1 = new THREE.MeshLambertMaterial( { color: 0xffffff, overdraw:0.1 } );//材质颜色为白色,0.5是否在立方体上线条的显示程度,越小显示越明显
        for ( var i = 0; i < 100; i ++ ) {
            var cube = new THREE.Mesh( geometry1, material1 );//绘制立方体
            //以下是设置立方体的位置
            cube.position.x = Math.floor( ( Math.random() * 1000 - 500 ) / 50 ) * 50 + 25;
            cube.position.y = ( cube.scale.y * 50 ) / 2;
            cube.position.z = Math.floor( ( Math.random() * 1000 - 500 ) / 50 ) * 50 + 25;
            scene.add( cube );
        }
    }
    function render()
    {
        rendererCanvas.render(scene,camera);
    }
    function initStart()
    {
        initRenderer();
        initScene();
        initCamera();
        initLight();
        initGeometry();
        render();
        var control=new THREE.OrbitControls(camera);//添加控制动作,参数camera是相机,说明控制的是相机
        control.addEventListener('change',render);//当场景交换时重绘场景
    }
    initStart();
    /*
     基本步骤:
     1、创建一个渲染器,并设置其大小,将其添加到div或body区域中
         (1) 声明全局render对象;
         (2) 获取画布的高和宽;
         (2) 生成渲染器对象
         (3) 指定渲染器的高宽(一般跟画布框大小一致);
         (4) 追加canvas元素到canvas3d元素中;
         (5) 设置渲染器的清除色。
     2、创建一个照相机,并设置照相机的中心位置,即z轴
         (1) 声明全局的变量(对象);
         (2) 设置透视投影的相机;
         (3) 设置相机的位置坐标;
         (4) 设置相机的上为「z」轴方向;
         (5) 设置视野的中心坐标。
     3、创建一个场景
     4、创建灯光
         (1) 声明全局变量(对象)
         (2) 设置平行光源
         (3) 设置光源向量
         (4) 追加光源到场景
     5、创建物体或加载模型,创建贴图对象,并将贴图转换成材质,并将材质贴到物体上,最后添加到场景中
     6、开始渲染
     */
</script>
</body>
</html>


 

运行效果图如下:


对以上代码进行分析:

1、首先声明全局变量

var rendererCanvas,scene,camera,light;
其中包括渲染器变量,场景变量,相机变量以及环境光变量。

2、初始化渲染器函数,如下代码所示:

function initRenderer()
    {
        rendererCanvas=new THREE.CanvasRenderer();                      //创建一个基于canvas的渲染器
        rendererCanvas.setSize( window.innerWidth, window.innerHeight );//设置渲染器的大小
        document.body.appendChild(rendererCanvas.domElement);           //将渲染器添加到body区域
        rendererCanvas.setClearColor(0xffffff);                         //设置渲染器的背景颜色为白色
    }

3、初始化场景函数,如下代码所示:

function initScene()
    {
        scene=new THREE.Scene();//创建一个场景
    }
4、初始化相机函数,并将相机固定在某个位置,如下代码所示:

function initCamera()
    {
        //创建一个正投影相机照相机
        //camera = new THREE.OrthographicCamera( window.innerWidth / - 2, window.innerWidth / 2, window.innerHeight / 2, window.innerHeight / - 2, - 500, 1000 );
        camera=new THREE.PerspectiveCamera(70,window.innerWidth/window.innerHeight,1,1000);//创建透视照相机
        camera.position.x = 200;
        camera.position.y = 100;
        camera.position.z = 200;//设置相机的位置
        camera.lookAt(scene.position);//将相机固定在scene.position所指向的位置
        scene.add(camera);//将相机加到场景中去
    }
5、初始化环境光函数,如下代码所示:

function initLight()
    {
        var ambientLight = new THREE.AmbientLight(0x0000FF);//创建一个环境光,光为蓝色
        scene.add( ambientLight );
    }
6、初始化Geometry函数,在此函数中,首先创建的是网格,然后在创建各个小立方体,创建网格的方法是通过先设置4个顶点,然后在通过LineSegments函数将四个点画一条线出来,比如:有四个顶点a、b、c、d对应的坐标是(-500,0,500)、(500,0,500)、(500,0,500)、(500,0,-500),那么执行这个动作则是从a画一条线到b,然后在从c画一条线到d,由于b和c的坐标相同,所以看起来就是向连接的,如下所示:




那么映射到屏幕上的效果是透视相机的效果,刚开始时比较大,所以要缩小才能看到,如下图所示:










以下是正交相机的效果,如下图所示:


相对应的代码如下所示:

function initGeometry()
    {
        var geometry=new THREE.Geometry();
        geometry.vertices.push(new THREE.Vector3(-500,0,500));
        geometry.vertices.push(new THREE.Vector3(500,0,500));
        geometry.vertices.push(new THREE.Vector3(500,0,500));
        geometry.vertices.push(new THREE.Vector3(500,0,-500));
        var material=new THREE.LineBasicMaterial({color:0x000000,opacity:0.5});
        var line=new THREE.LineSegments(geometry,material);
        scene.add(line);
}
那么要画成一个网格,那必须有一个循环来保存这些顶点,如下代码所示:

function initGeometry()
    {
        var geometry=new THREE.Geometry();
        var size=500,step=50;
        for(var i=-size;i<=size;i+=step)
        {
            geometry.vertices.push(new THREE.Vector3(-size,0,-i));
            geometry.vertices.push(new THREE.Vector3(size,0,-i));
            geometry.vertices.push(new THREE.Vector3(-i,0,size));
            geometry.vertices.push(new THREE.Vector3(-i,0,-size));
        }
        var material=new THREE.LineBasicMaterial({color:0x000000,opacity:0.5});//创建一个颜色为黑色,线条透明度为0.5
        var line=new THREE.LineSegments(geometry,material);
        scene.add(line);
}
运行效果图(透视相机)如下所示:

运行效果图(正交相机)如下所示:


网格画好了,在上边画小的立方体,那么首先创建一个立方体,然后在材质绑定,如下代码所示:

var geometry1 = new THREE.BoxGeometry( 50, 50, 50 );//创建一个立方体
var material1 = new THREE.MeshLambertMaterial( { color: 0xffffff, overdraw:0.5 } );//材质颜色为白色,0.5是否在立方体上线条的显示程度,越小显示越明显
for ( var i = 0; i < 100; i ++ ) {
     var cube = new THREE.Mesh( geometry1, material1 );//绘制立方体
     //以下是设置立方体的位置
     cube.position.x = Math.floor( ( Math.random() * 1000 - 500 ) / 50 ) * 50 + 25;
     cube.position.y = ( cube.scale.y * 50 ) / 2;
     cube.position.z = Math.floor( ( Math.random() * 1000 - 500 ) / 50 ) * 50 + 25;
     scene.add( cube );
}
如下overdraw:0.5的效果图:


如下overdraw:0.1的效果图,可以观察到有细小的白色线条:



整个函数的代码如下所示:

    function initGeometry()
    {
        var geometry=new THREE.Geometry();
        /*
        在画网格时,需要提供四个坐标点,然后使用LineBasicMaterial根据坐标点画线段,如:
        1、(-500,0,500)在空间坐标系中,该坐标点在第四象限
        2、(500,0,500)在空间坐标系中,该坐标点在第一象限
        3、(500,0,500)与第二个点坐标相同
        4、(500,0,-500)在空间坐标系中,该坐标点在第二象限
        如:
                              (-500,0,-500)    (-300,0,-500)  (-100,0,-500)    (100,0,-500)    (300,0,-500)    (500,0,-500)
                       (-500,0,-500)/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/(500,0,-500)
                      (-500,0,-450)/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/(500,0,-450)
                     (-500,0,-400)/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/(500,0,-400)
                    (-500,0,-350)/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/(500,0,-350)
                   (-500,0,-300)/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/(500,0,-300)
                  (-500,0,-250)/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/(500,0,-250)
                 (-500,0,-200)/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/(500,0,-200)
                (-500,0,-150)/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/(500,0,-150)
               (-500,0,-100)/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/(500,0,-100)
              (-500,0, -50)/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/(500,0,-50)
             (-500,0,   0)/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/(500,0,0)
             (-500,0, 50)/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/(500,0,50)
            (-500,0,100)/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/(500,0,100)
           (-500,0,150)/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/(500,0,150)
          (-500,0,200)/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/(500,0,200)
         (-500,0,250)/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/(500,0,250)
        (-500,0,300)/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/(500,0,300)
       (-500,0,350)/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/(500,0,350)
      (-500,0,400)/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/(500,0,400)
     (-500,0,450)/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/(500,0,450)
    (-500,0,500)/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/___/(500,0,500)
          (-500,0,500)(-350,0,500)(-200,0,500)(-50,0,500)  (100,0,500) (250,0,500) (400,0,500)(500,0,500)                                                 
        */
        var size=500,step=50;
        for(var i=-size;i<=size;i+=step)
        {
            geometry.vertices.push(new THREE.Vector3(-size,0,-i));
            geometry.vertices.push(new THREE.Vector3(size,0,-i));
            geometry.vertices.push(new THREE.Vector3(-i,0,size));
            geometry.vertices.push(new THREE.Vector3(-i,0,-size));
        }
        var material=new THREE.LineBasicMaterial({color:0x000000,opacity:0.5});//创建一个颜色为黑色,线条透明度为0.5
        var line=new THREE.LineSegments(geometry,material);
        scene.add(line);

        var geometry1 = new THREE.BoxGeometry( 50, 50, 50 );//创建一个立方体
        var material1 = new THREE.MeshLambertMaterial( { color: 0xffffff, overdraw:0.1 } );//材质颜色为白色,0.5是否在立方体上线条的显示程度,越小显示越明显
        for ( var i = 0; i < 100; i ++ ) {
            var cube = new THREE.Mesh( geometry1, material1 );//绘制立方体
            //以下是设置立方体的位置
            cube.position.x = Math.floor( ( Math.random() * 1000 - 500 ) / 50 ) * 50 + 25;
            cube.position.y = ( cube.scale.y * 50 ) / 2;
            cube.position.z = Math.floor( ( Math.random() * 1000 - 500 ) / 50 ) * 50 + 25;
            scene.add( cube );
        }
    }
7、对场景进行渲染函数,如下所示:

function render()
    {
        rendererCanvas.render(scene,camera);
    }
8、最后对所有的函数进行统一初始化,如下代码所示:

    function initStart()
    {
        initRenderer();
        initScene();
        initCamera();
        initLight();
        initGeometry();
        render();
        var control=new THREE.OrbitControls(camera);//添加控制动作,参数camera是相机,说明控制的是相机
        control.addEventListener('change',render);//当场景交换时重绘场景
    }
最后只需要调用initStart()即可完成所有的工作

9、对场景添加控制,比如说按鼠标滚轮可以扩大或缩小,按着鼠标左键可以在原点进行旋转等等,首先要引入OrbitControls.js文件,然后通过

var control=new THREE.OrbitControls(camera);//添加控制动作,参数camera是相机,说明控制的是相机
来创建一个控制变量,参数是照相机则说明是对照相机的控制,最后在添加监听函数,就是当照相机改变时就调用对场景的重新渲染,如下代码:

control.addEventListener('change',render);//当场景交换时重绘场景

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值