zoukankan      html  css  js  c++  java
  • 关于如何使用three.js的小教程<一>

    昨天看了看three.js这个东西,身为一个3D引擎,他还是非常强大的。官网上有个tutorial讲的不甚具体。http://aerotwist.com/tutorials/getting-started-with-three-js/

    扯淡的内容比較多,有个人做了翻译在这里http://blog.csdn.net/webgl_/article/details/6424749

    有一个外国人的教程系列是这个http://www.smashinglabs.pl/three-js-tetris-tutorial粗略看了一下是好像做一个俄罗斯方块,代码比較多。

    有一个中国人写的教程在这里http://www.html5china.com/HTML5features/WebGL/20111129_2989.html代码比較少,只是有非常多经典的图。


    在github上面能够获取到three.js的源代码,直接下载ZIP即可了https://github.com/mrdoob/three.js/

    眼下google chrome是不支持xp的webGL的,opera近期推出了一个实验版支持xp下的webGL,使用xp的用户能够搜一下。

    文件夹大概是这个样子,build中装的是压缩好的js代码,使用Three.js的时候仅仅须要包括./build/Three.js就能够了。./build/custom 之中应该提供了一些供你自己定义使用的脚本。

    ./docs 下提供了一个很简陋的API文档,只是能够将就着看。

    ./examples 里面有许多的样例,这个很好。当中比較多的是webGL开头的和Canvas开头的文件,大概是提供了,两种技术实现的比較,webGL比Canvas快100倍(非官方统计),毕竟webGL使用了硬件加速嘛,比較明显的看canvas_geometry_hierarchy.ht和webgl_geometry_hierarchy.html这两个样例。./examples 的子目录以下是一些 元素的脚本 比方 ./js/ShaderExtra.js 就是一些现成的shader代码,能够直接拿来用,或者一些字体和统计FPS的脚本,three.js里面用的是./js/stats.js这个脚本来做一些统计工作。还有就是一些models什么的。

    ./src 里面放的就是源代码了

    ./gui 里面应该是一些图形化的东西,没有细致研究。

    ./utils 里面是一些工具,应该是一些编译连接的脚本什么的。


    three.js的使用比較简单,一个基本的camera ,一个基本的 scene ,一个render(这个东西翻译成渲染器,就是Canvas,WebGL,SVG什么的),其他的light , materials,object,虾米的都是为了好看用的。

    先说这个Camera ,three.js的camera有非常多种,最简单的叫做这个perspectiveCamera透视相机,或者这个远景相机,这样来新建一个实例。

    var camera, scene, renderer;
    var windowHalfX = window.innerWidth / 2;
    var windowHalfY = window.innerHeight / 2;
    camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 100, 10000 );
    camera.position.z = 1000;
    

    四个属性各自是,摄像机的视锥角度,视口的长宽比,摄像机的近切面(Front Clipping Plane)和远切面(Back Clipping Plane),这样就确定了摄像机的视锥。

    position.z是垂直于屏幕,也就是近切面远切面的距离。

    当然还能够通过camera.lookAt来调整camera的朝向,只是在这里不是必需。


    以地球举例,如果地球垂直摆放,视锥角度非常小时,仅仅能看到赤道周围的图像,近切面远切面相距过近时仅仅能看到东半球或西半球,这个说也说不太清楚,自己改改參数试一试,即可。


    scene的创建非常easy,直接new一下就好,然后就是把各种东西add到sence里面即可了,就像这样。

    var camera, scene, renderer;
    scene = new THREE.Scene();
    scene.add( camera );

    接下来就是加入一些object,这里我们使用一个叫做mesh的东西,使用这个网格模型,比較easy建立简单的几何体,球体啊,柱体啊,什么的,当然非常炫的modal还须要maya之类的专业工具。

    mesh的结构是这种


    var mesh;
    mesh = new THREE.Mesh( new THREE.SphereGeometry( 200, 20, 20 ), new THREE.MeshBasicMaterial( { map: THREE.ImageUtils.loadTexture( './land_ocean_ice_cloud_2048.jpg' ), overdraw: true } ) );
    scene.add( mesh );

    创建一个球体的函数是这样

    THERE.SphereGeomrtry(radius, segments, rings) 第一个參数是半径,后两个能够理解成球体的精细程度,数值越高球体就越圆,能够吧后两个參数调低自己体会一下。

    THERE.MeshBasicMaterial() 就是材质了,假设想要一个单色材质的话能够这样

    var sphereMaterial = new THREE.MeshLambertMaterial(
    {
        color: 0xCC0000
    });
    使用自己定义图片的话是这样,overdraw是过度渲染的一个开关如今还不重要。

     
    var sphereMaterial = new THREE.MeshBasicMaterial( 
    { 
        map: THREE.ImageUtils.loadTexture( './land_ocean_ice_cloud_2048.jpg' ), overdraw: true 
    } ) );

    最后设置一下mesh的位置,把它增加到scene中就能够了

    mesh.position.y = - 250;
    mesh.rotation.x = - 90 * Math.PI / 180;
    scene.add( mesh );


    渲染器的创建也非常easy,这里使用的是一个CanvasRenderer,最后须要把render的dom加到container的最后,简单点说就是,通过渲染器吧3D图像输出到页面上。

    至于dom结构的介绍在这里http://www.w3school.com.cn/htmldom/是一个树形结构,appendChild方法,是把參数里的dom加入到指定节点,的最后一个节点。

    var container = document.getElementById( 'container' );
    renderer = new THREE.CanvasRenderer();
    renderer.setSize( window.innerWidth, window.innerHeight );
    container.appendChild( renderer.domElement );

    循环渲染,实现3D图形的动态须要不断改变camera的位置,通过不断的渲染来达成动画的效果

    render方法实现视角的转换,

    animate方法实现循环渲染,

    原理是无限递归调用,requestAnimationFrame这个函数非常牛逼,有兴趣能够看看源代码。

    stats.update();是更新FPS的不用管。

    function animate() {
    		requestAnimationFrame( animate );
    		render();
    		stats.update();
    
    	}
    
    function render() {
    		camera.position.x += ( mouseX - camera.position.x ) * 0.05;
    		camera.position.y += ( - mouseY - camera.position.y ) * 0.05;
    		camera.lookAt( scene.position );
    		mesh.rotation.y -= 0.005;
    		renderer.render( scene, camera );
    
    			}



    最后把代码整合起来是这种,实现了一个,转动的地球。代码中用到的两张图片在exmples/textures中能够找到

    <!doctype html>
    <html lang="en">
    	<head>
    		<title>three.js canvas - geometry - earth</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 {
    				color: #808080;
    				font-family:Monospace;
    				font-size:13px;
    				text-align:center;
    
    				background-color: #ffffff;
    				margin: 0px;
    				overflow: hidden;
    			}
    
    			#info {
    				position: absolute;
    				top: 0px;  100%;
    				padding: 5px;
    			}
    
    			a {
    
    				color: #0080ff;
    			}
    
    		</style>
    	</head>
    	<body>
    
    		
    		<div id="info"><a href="http://github.com/mrdoob/three.js" target="_blank">three.js</a> - earth demo</div>
    		<div id="container"></div>          //存放场景的块
    		<script src="./Three.js"></script>    //直接把Three.js放在相同文件夹下就能够了
    		<script src="./Stats.js"></script>	//这个是统计FPS的,没什么用,认为麻烦的话能够吧与Stats有关的代码删掉
    
    		<script>
    
    			var container, stats;
    			var camera, scene, renderer;
    			var mesh;
    			var mouseX = 0, mouseY = 0;
    
    			var windowHalfX = window.innerWidth / 2;
    			var windowHalfY = window.innerHeight / 2;
    
    			init();         //初始化
    			animate();      //循环渲染
    
    			function init() {
    
    				container = document.getElementById( 'container' );
    
    				scene = new THREE.Scene();
    
    				camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 100, 10000 );
    				camera.position.z = 1000;
    				scene.add( camera );
                                   //创建球体
    				mesh = new THREE.Mesh( new THREE.PlaneGeometry( 300, 300, 3, 3 ), new THREE.MeshBasicMaterial( { map: THREE.ImageUtils.loadTexture( './shadow.png' ), overdraw: true } ) );
    				mesh.position.y = - 250;
    				mesh.rotation.x = - 90 * Math.PI / 180;
    				scene.add( mesh );
                                    //创建阴影
    				mesh = new THREE.Mesh( new THREE.SphereGeometry( 200, 20, 20 ), new THREE.MeshBasicMaterial( { map: THREE.ImageUtils.loadTexture( './land_ocean_ice_cloud_2048.jpg' ), overdraw: true } ) );
    				scene.add( mesh );
    
    				renderer = new THREE.CanvasRenderer();
    				renderer.setSize( window.innerWidth, window.innerHeight );
    
    				container.appendChild( renderer.domElement );
    
    				stats = new Stats();
    				stats.domElement.style.position = 'absolute';
    				stats.domElement.style.top = '0px';
    				container.appendChild( stats.domElement );
    
    			}
    
    			function animate() {
    
    				requestAnimationFrame( animate );
    
    				render();
    				stats.update();
    
    			}
    
    			function render() {
    
    				camera.position.x += ( mouseX - camera.position.x ) * 0.05;
    				camera.position.y += ( - mouseY - camera.position.y ) * 0.05;
    				camera.lookAt( scene.position );
    
    				mesh.rotation.y -= 0.005;
    
    				renderer.render( scene, camera );
    
    			}
    
    
    		</script>
    
    	</body>
    </html>
    
    
    

    Deom的打包资源,能够在我的上传资源中下载。

    http://download.csdn.net/detail/wangyi_lin/4164117

  • 相关阅读:
    自定义View的ToolBar布局报错Error:(2) No resource identifier found for attribute 'context' in package 'c
    在学git之主分支 branch
    获取发布版SHA1
    关于开启线程与UI的操作
    播放音频和视频(VideoView控件)
    通知栏Notification的应用
    Android 真机调式 Installation failed with message 远程主机强迫关闭了一个现有的连接。. It is possible that this issue is resolved by uninstalling an existing version of the apk if it is present, and then re-installing. WA
    运行程序申请危险权限
    mysql乐观锁总结和实践
    Nginx配置文件nginx.conf中文详解
  • 原文地址:https://www.cnblogs.com/zfyouxi/p/4065102.html
Copyright © 2011-2022 走看看