【001】Three.js第一步:认识它的代码结构

在讲解具体代码前,先说明下:一个典型的Three.js程序至少要包括渲染器(Renderer)、场景(Scene)、照相机(Camera),以及你在场景中创建的物体。这里我们先不去创建物体,而是利用外部模型进行演示。目前不要关心3D的绘制方式,只需要了解整个显示流程。


1、源代码

官网例子点击进入源代码点击进入

2、详细代码注释:

<!DOCTYPE html>
<html lang="en">
    <head>
        <title>three.js webgl - loaders - OBJ loader</title>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
        <style>
            body {
                font-family: Monospace;
                background-color: #000;
                color: #fff;
                margin: 0px;
                overflow: hidden;
            }
            #info {
                color: #fff;
                position: absolute;
                top: 10px;
                width: 100%;
                text-align: center;
                z-index: 100;
                display:block;
            }
            #info a, .button { color: #f00; font-weight: bold; text-decoration: underline; cursor: pointer }
        </style>
    </head>

    <body>
        <div id="info">
        <a href="http://threejs.org" target="_blank">three.js</a> - OBJLoader test
        </div>

        <script src="three.js"></script>
        <script src="OBJLoader.js"></script>

        <script>

            var container;

            var camera, scene, renderer;

            var mouseX = 0, mouseY = 0;

            var windowHalfX = window.innerWidth / 2;
            var windowHalfY = window.innerHeight / 2;


            init();
            animate();


            //初始化函数:
            function init() {

                container = document.createElement( 'div' );
                document.body.appendChild( container );

                //创建照相机camera。PerspectiveCamera为透视投影照相机:
                //THREE.PerspectiveCamera(fov, aspect, near, far)
                //fov为视景体竖直方向上的张角。aspect等于width / height,是照相机水平方向和竖直方向长度的比值,通常设为Canvas的横纵比例。
                //near和far分别是照相机到视景体最近、最远的距离,均为正值,且far应大于near。    
                camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 2000 );
                camera.position.z = 250;
                
                

                //创建场景scene
                scene = new THREE.Scene();
                
                
                //创建光照效果。此处设置为环境光AmbientLight。环境光是指场景整体的光照效果,是由于场景内若干光源的多次反射形成的亮度一致的效果,
                //通常用来为整个场景指定一个基础亮度。因此,环境光没有明确的光源位置,在各处形成的亮度也是一致的。
                //在设置环境光时,只需要指定光的颜色:THREE.AmbientLight(hex);其中hex为16进制的RGB颜色。
                var ambient = new THREE.AmbientLight( 0x101030 );
                scene.add( ambient );
                
                //创建光照效果。此处设置的为平行光DirectionalLight(hex,intensity)。对于任意平行的平面,平行光照射的亮度都是相同的,而与平面的位置无关。
                //其中hex为16进制的RGB颜色。intensity为亮度,缺省值为1,表示100%亮度。
                //对于平行光而言,设置光源位置尤为重要,这里的坐标并不是所有的光从这个点出发,而是沿着这个矢量方向传输。
                var directionalLight = new THREE.DirectionalLight( 0xffeedd );
                directionalLight.position.set( 0, 0, 1 );
                scene.add( directionalLight );

                //构造纹理texture。
                var manager = new THREE.LoadingManager();
                manager.onProgress = function ( item, loaded, total ) {

                    console.log( item, loaded, total );

                };
                var texture = new THREE.Texture();
                var onProgress = function ( xhr ) {
                    if ( xhr.lengthComputable ) {
                        var percentComplete = xhr.loaded / xhr.total * 100;
                        console.log( Math.round(percentComplete, 2) + '% downloaded' );
                    }
                };
                var onError = function ( xhr ) {
                };
                var loader = new THREE.ImageLoader( manager );
                loader.load( '2_0.jpg', function ( image ) {

                    texture.image = image;
                    texture.needsUpdate = true;

                } );
                

                /*
                model.这里使用的为:OBJLoader对象,专门针对.obj文件。
                调用了方法:load(URL,onLoad,onProgress,OnError);
                URL为纹理文件路径,onLoad当加载完成后调用。onProgress在加载时会被调用,包含了已加载和全部文件的比特值。
                */
                var loader = new THREE.OBJLoader( manager );
                loader.load( '2.obj', function ( object ) {

                    object.traverse( function ( child ) {
                    /*
                    instanceof 运算符是用来在运行时指出对象是否是特定类的一个实例。
                    instanceof通过返回一个布尔值来指出,这个对象是否是这个特定类或者是它的子类的一个实例。
                    用法:result = object instanceof class
                    参数:Result:布尔类型。Object:必选项。任意对象表达式。Class:必选项。任意已定义的对象类。
                    说明:如果 object 是 class 的一个实例,则 instanceof 运算符返回 true。
                    如果 object 不是指定类的一个实例,或者 object 是 null,则返回 false。
                    */
                        if ( child instanceof THREE.Mesh ) {

                            child.material.map = texture;

                        }

                    } );

                    object.position.y = - 20;
                    scene.add( object );

                }, onProgress, onError );

                //动作效果

                renderer = new THREE.WebGLRenderer();
                renderer.setPixelRatio( window.devicePixelRatio );
                renderer.setSize( window.innerWidth, window.innerHeight );
                container.appendChild( renderer.domElement );

                /*
                添加事件监听器。element.addEventListener(evrnt,function,useCapture);
                event指定事件名称,function指定事件触发时执行的函数,useCapture可选的,指定事件在捕获阶段或者冒泡阶段执行。
                这里的两个函数:onDocumentMouseMove和onWindowResize在后面均有定义。
                */
                document.addEventListener( 'mousemove', onDocumentMouseMove, false );
                window.addEventListener( 'resize', onWindowResize, false );

            }

            function onWindowResize() {

                windowHalfX = window.innerWidth / 2;
                windowHalfY = window.innerHeight / 2;

                camera.aspect = window.innerWidth / window.innerHeight;
                camera.updateProjectionMatrix();

                renderer.setSize( window.innerWidth, window.innerHeight );

            }

            function onDocumentMouseMove( event ) {

                mouseX = ( event.clientX - windowHalfX ) / 2;
                mouseY = ( event.clientY - windowHalfY ) / 2;

            }

            //

            function animate() {

                requestAnimationFrame( animate );
                render();

            }

            function render() {

                camera.position.x += ( mouseX - camera.position.x ) * .05;
                camera.position.y += ( - mouseY - camera.position.y ) * .05;

                camera.lookAt( scene.position );

                renderer.render( scene, camera );

            }

        </script>

    </body>
</html>

3、总结

仔细对代码结构分类,可以大概明白整体流程。了解了具体技术流程后,接下类就学习下技术细节内容吧。建议有时间和英语基础的同学可以直接访问官网文档(文档点击进入)。还有【强烈推荐:Three.js入门指南】


参考来源:

http://www.ituring.com.cn/article/58552

http://www.runoob.com/jsref/met-element-addeventlistener.html

http://blog.csdn.net/liranke/article/details/5574791

转载于:https://my.oschina.net/renguoqing/blog/673377

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值