three.js中文文档|Three.js绘制一个静态的3D球体教程

更新时间:2020-02-23    来源:jquery    手机版     字体:

【www.bbyears.com--jquery】

Three.js其实是一个3D的JS引擎,其中的强大之处就在于这个JS框架并不是依托于JQUERY来写的。那么,我们在写这一篇绘制3D球体的文章的时候,应该注意哪些地方呢?下面我就来一一列举

1.场景。

  场景是什么,说得简单一点,场景就是一个canvas ,我们就是要在Canvas上面实现3D效果的画面而已。场景和容器,相机是息息相关的,我们就拿拍戏来说,假如我们需要演一个古装剧的撕逼场景,那么,我们需要的道具其中之一就是一个相机。

2.容器

  就是承载球体的DIV,比如我们要演戏,那么演戏的场地,比如某个山清水秀的地方。

3.相机

  简单一点说,就是你从屏幕里面看这个球体的样子,说得不太明白?其实很简单,你想一下你在玩生化危机的时候的,是不是第一人称?那么你看到的不同的怪物,以不同的视角去看的话,那么得到的结果,就会有差异,这个就是相机的作用。

4.演员(这里指的是球体)

  这个就太容易了,不过以后我提到的可不一定是球体哦,也许是正方体,也许是一个复杂的形状都有可能,THREE.JS提供了很多的“库”,这些库可以绘制出不同的形状的物体,对于初学者来说,理解这些就足够了。

代码

  代码不是特别的复杂,大家理解的话可以按照层级关系来理解,比如场景里面添加相机什么的,反正就是一层一层的套,英语的话有一些专有词汇,

 
<script>
    //设置场景的大小
    var width = 400;
    var height = 300;
 
    //设置相机的一些参数。
    var view_angle = 45;
    aspect = width / height;
    near = 0.1;
    far = 10000;
 
    //设置容器
    var $container = $("#container");
 
    //新建一个WebGL 渲染,以及相机
    var renderer = new THREE.WebGLRenderer();
    var camera =
        new THREE.PerspectiveCamera(
        view_angle, aspect, near, far
        );
    var scene = new THREE.Scene();
 
    //把相机添加到场景里面
    scene.add(camera);
 
    camera.position.z = 300;
 
    renderer.setSize(width, height);
 
    //附加DOM元素
    $container.append(renderer.domElement);
 
    //设置球体的值
    var radius = 50, segemnt = 16, rings = 16;
 
    var sphereMaterial = new THREE.MeshLambertMaterial({ color: 0xCC0000 });
 
    var sphere = new THREE.Mesh(
        new THREE.SphereGeometry(radius,segemnt,rings),
        sphereMaterial
        );
 
    sphere.geometry.verticesNeedUpdate = true;
    sphere.geometry.normalsNeedUpdate = true;
 
    scene.add(sphere);
 
    var pointLight = new THREE.PointLight(0XFFFFFF);
 
    pointLight.position.x = 10;
    pointLight.position.y = 50;
    pointLight.position.z = 150;
 
    scene.add(pointLight);
 
     
    //画图
    renderer.render(scene, camera);
 
</script>


  
最终效果

由于我也是初学者,所以给大家的帮助也很有限,不过我会努力的,经常把自己学习Three.js的一些心得分享出来,共勉之!





关于怎样使用three.js的小教程

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

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

在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的创建很简单,直接new一下就好,然后就是把各种东西add到sence里面就行了,就像这样。

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


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

mesh的结构是这样的

http://img.dnbcw.info/2012323/3899031.gif


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 );


渲染器的创建也很简单,这里使用的是一个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中可以找到



    
        three.js canvas - geometry - earth
        
        
        
    
    
        
        three.js - earth demo
                  //存放场景的块
        <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>
    


本文来源:http://www.bbyears.com/wangyezhizuo/85405.html