Three.js 快速开发 da 1

这不是完整教程,更像笔记

参考 Three.js Essentials这本书,有很多地方直接复制翻译的内容

Three.js 的函数有有用到异步加载,当制作复杂的3d视图有加载本地图片及其他文件时应该建立本地服务器,否则直接运行html文件时浏览器会提示加载错误:
XMLHttpRequest cannot load file:///F:/phptools/Apache2.2/htdocs/threejs/data/wpi.csv. Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https.

我使用的是Apache,但是对于Three.js本地调试,不需要太复杂的网络服务器环境,可以使用Python搭建

使用Python运行Web服务器
最简单的方法 检查您是否安装了Python,只需python在命令行中键入即可。如果你看到如下输出,你就有了安装了Python,您可以使用它来运行简单的Web服务器:

复制

> python
Python 2.7.3 (default, Apr 10 2013, 05:09:49)
[GCC 4.7.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>>

键入以下代码:

> python -m SimpleHTTPServer

输出将如下面的代码片段所示:

Serving HTTP on 0.0.0.0 port 8000...

这将启动端口8000上的Web服务器,它允许您从运行此命令的目录访问所有文件。
还可以安装其他Node.js以及便携网络服务器Mongoose

如果无法安装本地Web服务器,则会有最终的替代方案。可以直接从浏览器打开文件(或在浏览器窗口中拖放文件)。对于很多例子,这将直接工作; 但是,一旦需要加载外部资源的纹理或其他功能,由于浏览器的安全设置,这种方法将停止工作。可以更改此安全策略,以便使用这些功能的示例也可以正常工作。有关如何做到这一点的一个很好的解释,请参见Three.js网站:https://github.com/mrdoob/three.js/wiki/How-to-run-things-locally。

现在创建Three.js Web应用程序
在script标签中做的第一件事就是设置了一些全局变量。

// 全局变量
var renderer;
var scene;
var camera;
var control;
var cube;

使用init()初始化

function init() {
    // Three.js 初始化代码
}

window.onload = init();

使用该window.onload功能,告诉浏览器在加载文档完成时调用init()该功能。、

该完整init():

function init() {
    addscene();//添加场景
    addcube();//添加立方体
    addplane();//添加地面
    addlight();//添加光线
    initgui();//初始化dat.gui控件
    addStatsObject();//添加帧率显示控件
    render();//启动渲染
    console.log('Log statement from the init function');//控制台调试可以省略,加上可以在浏览器的控制台看到cube的具体信息
    console.log(cube);
}

初始化函数

function addscene(){
    scene = new THREE.Scene();

    renderer = new THREE.WebGLRenderer();
    renderer.setClearColor(0x000000, 1.0);
    renderer.setSize(window.innerWidth, window.innerHeight);
    renderer.shadowMapEnabled = true;

    camera = new THREE.PerspectiveCamera(
        45, window.innerWidth / window.innerHeight, 0.1, 1000);
    camera.position.x = 20;
    camera.position.y = 20;
    camera.position.z = 20;
    camera.lookAt(scene.position);

    document.body.appendChild(renderer.domElement);

}   

在前面的代码片段中,我们创建了三个基本的Three.js对象。首先,我们创建了一个THREE.Scene对象。这个对象是容纳所有要渲染的对象的容器。接下来,我们创建了一个THREE.WebGLRenderer对象。这是我们将用于渲染创建的THREE.Scene对象的Three.js 对象。最后,THREE.PerspectiveCamera对象决定了我们看到的内容。init()函数的最后一个调用是调用render()函数,如下面的代码所示:

function addcube(){
    var cubeGeometry = new THREE.CubeGeometry(6, 4, 6);
    var cubeMaterial = new THREE.MeshLambertMaterial({
      color: "red"
    });//需要光
    //cubeMaterial = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
    cubeMaterial.transparent = true;//设置为ture来改变透明度,默认1
    cube = new THREE.Mesh(cubeGeometry, cubeMaterial);

    cube.castShadow = true;
    scene.add(cube);
}

添加了立方cube 材质为THREE.MeshLambertMaterial这种材质需要光照才会显示
cube.castShadow = true; 设置ture来呈现阴影

function addplane(){//plane ground
    var planeGeometry = new THREE.PlaneGeometry(30, 20);
    var planeMaterial = new THREE.MeshLambertMaterial({
      color: 0xcccccc
    });
    var plane = new THREE.Mesh(planeGeometry, planeMaterial);
    plane.receiveShadow = true;

    plane.rotation.x = -0.5 * Math.PI;
    plane.position.y = -2;
    plane.position.z = 0;


    scene.add(plane);
}

function addlight(){
    //shadow
    var spotLight = new THREE.SpotLight(0xffffff);
    spotLight.position.set(10, 20, 20);
    spotLight.castShadow = true;
    scene.add(spotLight);
}

添加地面以及光照 光照使用点光源spotLight.castShadow = true; 阴影

 function render() {
   // render using requestAnimationFrame
   cube.material.opacity = control.opacity;
   cube.material.opacity = control.opacity;

   stats.update();
   renderer.render(scene, camera);
   requestAnimationFrame(render);
}

使用renderer.render()功能可视化场景。使用requestAnimationFrame函数来设置一个渲染循环。通过requestAnimationFrame功能,在浏览器最好情况下调用附带的函数(render在这种情况下是函数)。这提供了更平滑的体验和更好的表现。当循环执行时,就可以动态的改变cub的属性cube.material.opacity = control.opacity;cube.material.opacity = control.opacity;然后进行新的渲染,这里的值来自dat.gui控件的值

function initgui(){
    control = new function() {
        this.rotationSpeed = 0.005;
        this.opacity = 0.6;
        this.color = cube.material.color.getHex();
    };
    addControlGui(control);

}
function addControlGui(controlObject) {
    var gui = new dat.GUI();
    gui.add(controlObject, 'rotationSpeed', -0.01, 0.01);
    gui.add(controlObject, 'opacity', 0.1, 1);
    gui.addColor(controlObject, 'color');
}

这里的control为全局变量,更改后值实时的传递到render()函数中,这样实现使用控件动态改变cube的属性

以下完整html代码

<!DOCTYPE html>
<html>
<head>
    <title>simple 3d</title>
    <style>
        body { 
          margin: 0; 
          width: 100%;
          height: 100%;
          overflow: hidden;
        }/*无边框*/

        canvas { 
          width: 100%; 
          height: 100%;
        }/*布满屏幕*/
    </style>
</head>
<body>

</body>
<script src="../js/three.js"></script>
<!--three.js主要的文件-->
<script src="../js/dat.gui.min.js"></script>
<!--dat.gui.js控件,用于调整属性-->
<script src="../js/stats.min.js"></script>
<!--stats.js显示帧率及其他信息-->

<!--以下代码创建场景物体摄像机-->
<script>
    var renderer;
    var scene;
    var camera;
    var control;
    var cube;

    function init() {
        addscene();
        addcube();
        addplane();
        addlight();
        initgui();
        addStatsObject();
        render();
        console.log('Log statement from the init function');
        console.log(cube);
    }

    function addscene(){
        scene = new THREE.Scene();

        renderer = new THREE.WebGLRenderer();
        renderer.setClearColor(0x000000, 1.0);
        renderer.setSize(window.innerWidth, window.innerHeight);
        renderer.shadowMapEnabled = true;

        camera = new THREE.PerspectiveCamera(
            45, window.innerWidth / window.innerHeight, 0.1, 1000);
        camera.position.x = 20;
        camera.position.y = 20;
        camera.position.z = 20;
        camera.lookAt(scene.position);

        document.body.appendChild(renderer.domElement);

    }   

    function addcube(){
        var cubeGeometry = new THREE.CubeGeometry(6, 4, 6);
        var cubeMaterial = new THREE.MeshLambertMaterial({
          color: "red"
        });//need light
        //cubeMaterial = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
        cubeMaterial.transparent = true;//when you want to chang opacity ,you should set this ture.
        cube = new THREE.Mesh(cubeGeometry, cubeMaterial);

        cube.castShadow = true;
        scene.add(cube);
    }

    function addplane(){//plane ground
        var planeGeometry = new THREE.PlaneGeometry(30, 20);
        var planeMaterial = new THREE.MeshLambertMaterial({
          color: 0xcccccc
        });
        var plane = new THREE.Mesh(planeGeometry, planeMaterial);
        plane.receiveShadow = true;

        plane.rotation.x = -0.5 * Math.PI;
        plane.position.y = -2;
        plane.position.z = 0;


        scene.add(plane);
    }

    function addlight(){
        //shadow
        var spotLight = new THREE.SpotLight(0xffffff);
        spotLight.position.set(10, 20, 20);
        spotLight.castShadow = true;
        scene.add(spotLight);
    }

    function render() {
        // render using requestAnimationFrame
        cube.material.opacity = control.opacity;
        cube.material.color = new THREE.Color(control.color);
        document.getElementById('otherinfo').innerHTML = ""+"::"+"";

        stats.update();
        renderer.render(scene, camera);
        requestAnimationFrame(render);
    }


    window.onload = init();

    function initgui(){
        control = new function() {
            this.rotationSpeed = 0.005;
            this.opacity = 0.6;
            this.color = cube.material.color.getHex();
        };
        addControlGui(control);

    }


    function addControlGui(controlObject) {
        var gui = new dat.GUI();
        gui.add(controlObject, 'rotationSpeed', -0.01, 0.01);
        gui.add(controlObject, 'opacity', 0.1, 1);
        gui.addColor(controlObject, 'color');
    }

    function addStatsObject() {
        var stats = new Stats();
        stats.setMode(0);
        stats.domElement.style.position = 'absolute';
        stats.domElement.style.left = '0px';
        stats.domElement.style.top = '0px';
        document.body.appendChild( stats.domElement );
    }



</script>
</html>

这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值