zoukankan      html  css  js  c++  java
  • -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>

      

  • 相关阅读:
    JAVA过滤器(Filter)与拦截器(Interceptor)区别及关系
    原创:shiro 入门配置三步骤
    Shiro笔记(三)----Shiro配置文件ini详解
    搭建用Selenium模拟chrome浏览器运行环境,为模拟登陆做准备
    IDEA编译时,idea java: 找不到符号
    mybatis分页插件 pageHelper 在dao、 service , 各模块单元测试及Web层配置使用
    CF 336494 B. Divisor Subtraction
    【动态规划】DP状态机(UP20210815)
    DP数字三角形变形——方格取数
    hold sb at bay
  • 原文地址:https://www.cnblogs.com/amy2011/p/6145209.html
Copyright © 2011-2022 走看看