three.js 订阅
three.js是JavaScript编写的WebGL第三方库。提供了非常多的3D显示功能。 展开全文
three.js是JavaScript编写的WebGL第三方库。提供了非常多的3D显示功能。
信息
提    供
3D显示功能
编    写
JavaScript
中文名
three.js
属    性
3D 引擎
scanf函数原型
Three.js 是一款运行在浏览器中的 3D 引擎,你可以用它创建各种三维场景,包括了摄影机、光影、材质等各种对象。你可以在它的主页上看到许多精彩的演示。不过,这款引擎还处在比较不成熟的开发阶段,其不够丰富的 API 以及匮乏的文档增加了初学者的学习难度(尤其是文档的匮乏)three.js的代码托管在github上面。
收起全文
精华内容
参与话题
问答
  • 利用three.js 实际开发的一个实例

    万次阅读 多人点赞 2018-07-30 11:12:05
    首个threejs项目-前端填坑指南 第一次使用threejs到实际项目中,开始的时候心情有点小激动,毕竟是第一次嘛,然而做着做着就感受到这玩意水好深,满满的都是坑,填都填不过来。经过老板20天惨无人道的摧残,终于小...

    我的网站:https://yuansu.space

    首个threejs项目-前端填坑指南


    第一次使用threejs到实际项目中,开始的时候心情有点小激动,毕竟是第一次嘛,然而做着做着就感受到这玩意水好深,满满的都是坑,填都填不过来。经过老板20天惨无人道的摧残,终于小有成就。

    因为第一次搞这玩意,相对的遇到的问题也是大把的,让我来一一诉说一路上遇到的各种问题。

    开发使用: C4D、Blender2.75、[threejs-r72](http://threejs.org/)

    万事开头难,第一个问题就是怎么才能把3d软件中做好的模型显示在浏览器中。

    一、模型在软件中的导入与导出。

    这个项目中涉及到单个模型和动画模型,而不同模型的导入导出有差异,下面就告诉大家我是如何将坑填平的。

    1、单个模型: 

    因为自己不会使用3D软件建模,只能求助公司大神设计师来一起搞。刚开始的想法是直接用3d软件建模然后直接导出obj格式来用,然后设计师用C4D做好了一个测试模型,发现模型数量少的话网页的大小还可以接受,但是由于项目的模型数量比较多,然后粗算了一下模型总的大小,发现超出了预想,所以得另寻它法。

    接着在网上搜索发现Blender这玩意,由于设计师对C4D情有独钟不会Blender软件,所以决定用C4D做好模型然后导出obj格式接着再导入到Blender里面,再经由Blender导出需要的格式。

    因为是第一次倒腾这个软件,所以并不会导出。然后就在网上搜素了怎么用Blender导出的json、js文件。经过测试js文件导出比较大,最后果断选择json。

    在软件中如何导入导出如图所示:

    图一 (左边为导入obj,右边导出json)


    2、动画模型:

    由于设计师出一个动画模型也没有这么快,就没法进行导出测试。于是看到threejs官网里有demo中使用的动画模型,我就拿过来进行测试,发现动画模型跟单个模型导出选择有差异然后发现更单个模型的导出有出入,经过反复的测试,得到导动画模型需要注意的几点,

          (1)选择好动画的帧数,如果没选择,导出的json文件会有空帧。并且文件也会相对增大。

           (2)选择好导出选项中Animation,一般就选择Morph Animation、Embed Animation选项。

    单个模型以及动画模型导出选项如下图所示:


    图二 (左边为导出单个模型,右边导出动画模型)



    注:导出单个带材质模型需要在导出选项的时候需要在shading选项中选择Face Materials。

    拿着设计师做好的动画模型导出json格式后碰到了一些问题,虽然json格式的大小相比obj格式的要小一点,不过项目中有人物的动画模型导出的json格式大小还是太大。然后为了解决这个问题,跟设计师进行讨论,然后得到以下解决方案:

         (1)将模型的面和顶点在不影响正常显示的情况下进行删减

          (2)对动画模型的帧数、面、顶点也进行删减

    经过反复的修改和测试终于将动画模型控制在500-1000KB左右,单个模型控制在100K左右。

    模型的导出问题解决了然后是对模型进行导入到页面中去。

    二、模型加载到页面

    在threejs官网上看到利用obj格式加载的demo比较多,所以就直接使用的是obj的格式模型进行加载,根据demo利用THREE.OBJLoader()、THREE.OBJMTLLoader()进行加载。然后设计大神给了我一个带材质的模型让我进行测试,发现两问题:

         (1)模型材质丢失

         (2)模型的大小太大(模型量少大小还可以接受,考虑到此次项目中的模型量多,估算了一下大概有70-80M左右)

    由于模型大小太大所以放弃。所以改选用THREE.JSONLoader()进行加载。

    在这一步由于是直接导出带材质的json格式,材质对应到模型的各个面是一个问题。然后在官网的demo上看到THREE.MeshFaceMaterial()方法,查看了一下文档,然后迅速解决这个了这个问题。

    另外threejs提供了各种模型的加载方法具体可去threejs.org查询。

    虽然解决了模型加载和面的问题,但是模型在网页的表现与软件中渲染的差别太大。刚开始以为是模型方面以及导入导出的方式不对,于是和设计师进行各种修改然后反复的测试,发现没什么变化。然后求助stackoverflow找到了答案。是由于模型的shading的原因造成的,然后根据网上提供的解决方案在材质中加上materials.shading = THREE.FlatShading来解决。不过有些Android手机上会出现材质无法解析的错误。而且在r72的版本中MeshLambertMaterial已经移除了shading这个属性。

    下图就是在网页中渲染的结果对比。


    图三 (左边为未加shading,右边加了shading)


    静态模型的导入没有问题了,然后是动画模型的导入,参考官网demo,直接套用基本的动画没有太大问题,只是项目中有一个人物运球的动画模型比较难折腾,刚开始的时候直接是按照动画模型的导出直接导,然后同步到页面中发现只能导出一个动画,另外一个丢失了,定位了一下问题好像是Blender不能同时导出多个动画(具体是不是待研究)。最后想了一个办法就是采取分开导出再创建一个obj包裹两个动画,操作这个obj。来解决多个动画问题(如有更好的办法求大神指导)。

    至此将模型放到页面中的准备工作都做完了。接着就是模型上的事件与动画,模型上的各种事件整的头都大了,然而到现在我还是有一些东西没有弄清楚原理还得继续研究。

    三、模型的圆周运动

    刚开始项目中有个需求就是进入页面中模型需要做一个圆周运动,圆周运动以前在数学中学过,但是一直没用所以就忘了,然后就在网上找有关圆周运动计算的方法。这里不做过多的解释,用下面一张图来完整解释怎么来计算圆周运动。

    图四 (圆周运动计算)

    在页面中测试的结果如下图所示:


    图五 (圆周运动测试结果)


    功能代码如下:

             var clock = new THREE.Clock(); //时间跟踪
             //圆周运动
             var time = clock.getElapsedTime() * 1;
             loadMesh.position.x = Math.cos( time ) * 10;
             loadMesh.position.y = Math.sin( time ) * 10;

    老板看了一下,然后脑补一下整个页面的效果说还是不要这样子,很多模型都这样运动的话画面太乱了,最后决定的是简单点直接把所有模型摆放成一个球体形状,然后模型不单独运动,而是整体绕中心转,这个实现起来比较简单思路是直接设置外层模型y轴旋转就可以了。

    四、所有模型在空间里的位置


    整体的运动效果描绘出来了,接着就是开始实施了。接着遇到了一个算是比较坑的问题。那就是模型在空间位置的确认了,由于对3D场景的不熟悉,将所有模型摆出一个球体就有点困难了。只能求助设计大神了,然后他在C4D中将所有模型摆成一个球体之后,然后像操作模型一样导了一份obj给我。然后我利用Blender打开(如下图六所示),然后我看了下,每个模型在软件中都存在一个x,y,z值,我抱着侥幸的心里把所有模型的x,y,z记录下来然后填到页面中。最后发现球体的形状出来了,只是距离有点差异,接着想了个投机取巧的办法把所有的x,y,z进行等比的放大缩小,改完效果还不错。最后就是拉着设计师疯狂调整细节方面的问题。效果如下图七所示。


    图六 (球体模型)

    图七 (页面中渲染效果)


    页面的基本样子出来了,剩下的就是页面的交互了,整个难点基本都在这里了。

    项目需求:在页面中选中模型,然后选择模型现在在屏幕中间,然后用手指进行360度滑动,点击关闭按钮回到原型原有的位置。

    思路:选中模型-->移动某个东西-->绑定旋转事件-->回位。

    可以说项目大部分的时间都花在实现这个操作过程中。下面就简单说一下我是怎么去填这些坑的。

    五、在页面中选中模型

    之后的所有操作都要基于这个模型去做,所有第一步就需要选中这个模型。这个跟以前做的完全不同,然后在官网demo和stackoverflow游荡,因为涉及到屏幕坐标和世界坐标这个概念有种完全懵逼的感觉。还好官网上有demo的支持,参考了demo之后发现,首先获取屏幕坐标的x,y然后想办法转换成向量,接着标准化向量,通过raycaster.intersectObjects的检测来获取选中的模型。功能代码如下:

             

     

            mouse.x = ( e.clientX / window.innerWidth ) * 2 - 1; //鼠标的x到屏幕y轴的距离与屏幕宽的一半的比值 绝对值不超过1
            mouse.y = - ( e.clientY / window.innerHeight ) * 2 + 1; //鼠标的y到屏幕x轴的距离与屏幕宽的一半的比值 绝对值不超过1
    
            //新建一个三维变换半单位向量 假设z方向就是0.5,这样左右移的时候,还会有前后移的效果
            //屏幕和场景转换工具根据照相机,把这个向量从屏幕转化为场景中的向量
            var vector = new THREE.Vector3( mouse.x, mouse.y, 0.5 ).unproject( camera ); 
            
            //变换过后的向量vector减去相机的位置向量后标准化
            var raycaster = new THREE.Raycaster( camera.position, vector.sub( camera.position ).normalize() );
            
            //新建一条从相机的位置到vector向量的一道光线
            var intersects = raycaster.intersectObjects( objects );
            
            if ( intersects.length > 0 ) {
          
                //把选中的对象放到全局变量SELECTED中
                SELECTED = intersects[ 0 ].object;
            }

     

     

    参考: http://threejs.org/examples/webgl_octree_raycasting.html

    模型选中之后然后开始下一步。

    六、相机的移动

    因为要让选中的模型显示在屏幕中间,于是想了两种方案:

        (1)改变选中物体的x,y,z值


               经过反复的测试发现改变x,y,z值,模型会在空间中乱窜,把握不好位置。于是就思考其它的方案。


         (2)移动相机

                 移动相机这一块被坑了无数次,因为刚开始对这个相机的原理不是很清楚,就随意试了几个值(可以利用threejs提供的相机辅助线来操作具体参考:http://threejs.org/docs/index.html#Reference/Extras.Helpers/CameraHelper),来证明自己的方向是正确的,发现模型确实出现在不同的位置了,然后就继续往下深挖。首先在google中寻找有关threejs中相机的原理,具体参考:http://www.flowers1225.com/lessons/2015/12/08/1,对原理有一定了解之后,然后就想怎么让相机出现在自己想要的位置上。

    首先获取到选中模型的世界坐标,然后再根据当前的坐标值改变相机的x,y,z让相机直接照在当前模型上。测试了一下发现选中模型出现在屏幕中间,不过根据模型的不同位置上有偏差,这个后来设置了默认值来修正偏差。效果下图所示:


    图八 (相机移动)


    功能实现了,然后发现选择之后出现的太突然了,没有体现相机移动的效果,然后就想到使用TweenMax这个动画库来实现平滑过渡的动画。代码如下:

     

        TweenMax.to(camera.position, 1, {
             x: x,
             y: y,
             z: z,
             ease:Expo.easeInOut,
             onComplete: function (){}
        })

     

    加上之后效果如下图所示:



    图九 (相机平滑移动)  
     

    模型已经放大显示在屏幕中,然后点击关闭按钮让模型回到原位这个就直接用TweenMax将相机的position值设置为初始值就可以了。

    接下来就是开发用手指操作模型旋转的功能了。


    七、操作模型旋转

    这个功能我卡了好久,里面涉及到数学中的矩阵、四元数、欧拉角、向量乘积、轴-角啥的,完全都忘了。在二维中旋转可以通过角度来控制,而在三维空间中需要通过四元数或者矩阵来实现,万般无奈只能求助万能的google来了解怎么在三维空间中对物体进行旋转操作。 通过了解在3D中表现旋转有三种方法,矩阵、欧拉角、四元组。 最后选用四元组来实现旋转的方法,简单点说原因就是四元组的是围绕一个轴来做旋转,而且在threejs中也提供了THREE.Quaternion()方法,然后在threejs的包中找到了一些写好的鼠标控制的类(TrackballControls.js、OrbitControls.js等),然后参考着源码,将方法虽然写出来了,但是有时候操作起来会有意向不到的bug,所以里面的细节还有待深挖。下面简述一下旋转的思路。

    首先四元数控制旋转需要的是一个旋转轴和一个旋转弧度,直接上图清楚明了


    图十 


    然后就想办法得到这个两个东西,接着开始想怎么弄到旋转弧度,首先获取到点击开始和结束的x,y值,然后得到两个向量之间的夹角,得到一个弧度,然后在设置一个默认的旋转系数,两者相乘得到弧度。接着通过开始和结束的向量乘积得到旋转轴,最后通过setFromAxisAngle(axis, angle)得到旋转四元数。

    核心代码如下:

     

          function rotateMatrix(rotateStart, rotateEnd){
                var axis = new THREE.Vector3(),
                    quaternion = new THREE.Quaternion();
                    
                //得到开始和结束向量间的夹角    
                var angle = Math.acos(rotateStart.dot(rotateEnd) / rotateStart.length() / rotateEnd.length());
    
                if (angle){  //如果夹角等于0, 说明物体没有旋转
                    axis.crossVectors(rotateStart, rotateEnd).normalize();  //rotateStart,rotateEnd向量乘积 标准化 得到旋转轴
                    angle *= _that.rotationSpeed; //rotationSpeed旋转系数 得到旋转弧度
                    quaternion.setFromAxisAngle(axis, angle);  //从一个旋转轴和旋转弧度得到四元组, 如果要让物体相反方向旋转 设置angle为负
                }
                return quaternion; //返回一个旋转的四元数
            }
    
         this.handleRotation = function(object){
                _that.rotateEndPoint = _that.projectOnTrackball(_that.deltaX, _that.deltaY);
                var rotateQuaternion = rotateMatrix(_that.rotateStartPoint, _that.rotateEndPoint);
                var curQuaternion = object.quaternion;
                curQuaternion.multiplyQuaternions(rotateQuaternion, curQuaternion); //设置四元组 a x b
                curQuaternion.normalize();
                object.setRotationFromQuaternion(curQuaternion);  //方法通过规范化的旋转四元数直接应用旋转  参数必须normalize()
           };

     

     

    在这里有个小坑,就是所有模型的外观大小不同,当旋转的时候,可能会出现误操作,然后用了一个小技巧就是用一个透明的方体包裹模型,这样做就相当于旋转一个cube了,而且设置方体有网格时对排除bug有帮助。如下图所示:


    图十一 (外层包裹框)


    虽然旋转的效果做出来了,但是旋转里面涉及的东西还有一些理解的不是很清楚,还需要继续深入研究,等我研究透彻了再重新整理一下(还望大神指点一下)。

    参考:四元数旋转cube旋转、TrackballControls.js源码

    八、 灯光

    最后就是灯光的控制,因为NBA的主色调是红蓝色,设计大神就想模型在页面中有红蓝光打在模型上的感觉,于是照着这个方向,他开始在软件中调试灯光,调整好之后我按照设计师在软件中调整好的位置摆放灯光,发现跟预想的有点差异,页面中的颜色显的太深了,于是在整个空间中加上了一个白色的全局光来提亮整体的亮度,然后对灯光进行反复的调整,就到了现在页面中呈现的样子了。灯光调整的过程如图所示:


    图十二 (灯光调整过程)

    注: threejs提供很多种灯光具体可以在threejs文档中查看http://threejs.org/docs/index.html#Reference/Lights,而灯光调整可以借助threejs提供的辅助线来调整,THREE.PointLightHelper()、THREE.SpotLightHelper()等。这样有助于迅速定位到问题。

    最后就是手机兼容性的测试了(因为是微信的活动页,所以其它浏览器未测试)。在iPhone下整体体验较好,在Android下使用r71版本发现模型会出现菱角不分明的情况如图三所示,之后改用r72版本,用高版本的Android测试发现问题解决了,然后拿我自己的mx2测试时出现另外一个问题,直接卡在加载页面进不去页面,然后通过调试工具发现在控制台中有方法报错(小米2也是同等情况),倒腾了好久,然而并没有什么卵用,因为是threejs内部报错,无奈只能放大招,做一个Android版本来解决这个问题。

    最后附上体验地址(页面中意想不到的bug肯定是还有的):


    扫码体验


    第一次在实战中使用threejs开发,还有很多的不足需要弥补,希望下一次能做的更好。自己也继续的在webgl的坑中挣扎,挣扎,挣扎(重要的要说三遍),还望有大神指点迷津!!

    附上公司大神设计师的站酷:http://www.zcool.com.cn/u/738186

    另外附上一些自己在填坑中找到的对3D学习有帮助的网站、博客、书籍:

    各种计算  http://www.euclideanspace.com/maths/index.htm
    许多有趣的东西  http://www.natural-science.or.jp/article/laboratory/cat467/
    大叔很厉害的 http://learningthreejs.com/
    threejs源码注释 https://github.com/omni360/three.js.sourcecode 

    关于threejs的书籍只有英文原版的:

    《Three.Js Essentials》、《threejs-cookbook》、《Learning Three.js》

    -------------------------------------------------------------------------------------------------------------------------------------------------------------------------

    本文是我转载过来的,原文地址在这:https://www.cnblogs.com/pursues/p/5226807.html

    展开全文
  • Three.js入门教程——教不会算我输

    万次阅读 多人点赞 2019-06-09 17:56:27
    javascript中使用Three.js设计并且实现3D场景是一个很有意思的事情,因为在浏览器中就能够渲染出3D场景,非常简单和轻便。接下来就总结以下我学习Three.js过程中的心得。 1 建立基本场景 在Three.js中有三要素:...

    在javascript中使用Three.js设计并且实现3D场景是一个很有意思的事情,因为在浏览器中就能够渲染出3D场景,非常简单和轻便。接下来就总结以下我学习Three.js过程中的心得。

    1 建立基本场景

    在Three.js中有三要素:场景、摄像机和渲染器,只有以上三者结合才能渲染出可见的内容。当然在这之前你需要先下载Three.js文件,直接百度搜索Three.js到官网下载即可,下载完成之后新建一个html文件并且引入Three.js即可。一个最基本的使用Three.js的html文件应该是这样子的:

    <!DOCTYPE html>
    <html>
    <head>
    	<title>Wonanut 3D</title>
    	<style type="text/css">
    		body { margin: 0; }
    		canvas { width: 100%; height: 100%; }
    	</style>
    </head>
    <body>
    	<script type="text/javascript" src="js/three.js"></script>
    	<script type="text/javascript">
    		// 场景
    		var scene = new THREE.Scene();
    
    		// 摄像机
    		var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
    		camera.position.z = 5;
    		
    		// 渲染器
    		var renderer = new THREE.WebGLRenderer();
    		renderer.setSize( window.innerWidth, window.innerHeight );
    		document.body.appendChild( renderer.domElement );
    		// 渲染器 end
    		
    		// 物体
    		var geometry = new THREE.BoxGeometry(1, 1, 1);
    		var material = new THREE.MeshBasicMaterial( { color: 0x00ff00} );
    		var cube = new THREE.Mesh( geometry, material );
    		scene.add( cube );
    		// 物体 end
    
    	</script>
    </body>
    </html>

    我们打开浏览器看一下:

    哦天哪,发生了什么,浏览器上黑乎乎一片什么都没有啊。

    别急,这是因为我们只是设置了三要素,但并没有渲染,只有使用渲染器scene和camera进行渲染之后才能看到内容,在scene.add( cube ); 后面添加一句:

    renderer.render(scene, camera);

    再试试效果如何:

    快看,现在屏幕中出现了一个正方形,这正是我们所期待的!

    但是,我们使用的Three.js不应该是三维场景吗,为什么现在只有平面效果?不急,接下来我们使用requestAnimationFrame让画面动起来! 

     

    2 让画面动起来

    将上一步中最后一句代码:

    renderer.render(scene, camera);

    替换为:

    // 动画
    function animate() {
    
        cube.rotation.x += 0.01;
        cube.rotation.y += 0.01;
        renderer.render( scene, camera );
    
        requestAnimationFrame( animate );
    }
    animate();

    再到浏览器看看效果,如果没有什么问题的话,现在你所看到的画面应该是一个旋转的立方体:

    不过我对这个效果还是不满意,它看起来像是一个 正方体,但缺少了阴影灯光效果,接下来我们添加灯光效果。

     

    3 添加光效

    使用点光源THREE.SpotLight,代码如下:

    // 光源
    var spotLight = new THREE.SpotLight( 0xffffff );
    spotLight.position.set( -40, 60, -10 );
    scene.add( spotLight );
    // 光源 end

    同时将cube的材质从MeshBasicMaterial换为MeshLamberMaterial,因为最基本的MeshBasicMaterial材质对光源不会有任何反应。

    // 物体
    var geometry = new THREE.BoxGeometry(1, 1, 1);
    var material = new THREE.MeshLambertMaterial( { color: 0x00ff00} );
    var cube = new THREE.Mesh( geometry, material );
    scene.add( cube );
    // 物体 end

     

     

    4 添加阴影效果

    为了渲染阴影效果,需要对代码做如下修改:

    renderer.setClearColor(new THREE.Color(0x000000, 1.0));
    renderer.shadowMap.enabled = true;

    同时要给立方体设置投射阴影:

    cube.castShadow = true;

    设置地面接受阴影:

    plane.receiveShadow = true;

    设置spotLight投射阴影:

    spotLight.castShadow = true;

    为了添加阴影效果,我们需要设置一个平面来接受阴影,因此重新创建一个场景,源码如下:

    <!DOCTYPE html>
    <html>
    <head>
    	<title>Wonanut 3D</title>
    	<style type="text/css">
    		body { margin: 0; }
    		canvas { width: 100%; height: 100%; }
    	</style>
    </head>
    <body>
    	<script type="text/javascript" src="js/three.js"></script>
    	<script type="text/javascript" src="js/stats.js"></script>
    	<script type="text/javascript">
    		 场景-----------------------
    		var scene = new THREE.Scene();
    		 --------------------------
    
    		 摄像机---------------------
    		var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
    		camera.position.x = -30;
    		camera.position.y = 40;
    		camera.position.z = 30
    		camera.lookAt(scene.position);
    		 --------------------------
    		
    		 渲染器--------------------
    		var renderer = new THREE.WebGLRenderer();
    		renderer.setSize( window.innerWidth, window.innerHeight );
    		document.body.appendChild( renderer.domElement );
    		
    		// 设置渲染器渲染阴影效果
    		renderer.setClearColor(new THREE.Color(0x000000));
    		renderer.setSize(window.innerWidth, window.innerHeight);
    		renderer.shadowMap.enabled = true;
    		 渲染器 end----------------
    
    		 坐标轴--------------------
    		var axes = new THREE.AxesHelper(20);
    		scene.add(axes);
    		 -------------------------
    
    		 平面---------------------
    		var planeGeometry = new THREE.PlaneGeometry(60, 20, 1, 1);
    		var planeMaterial = new THREE.MeshLambertMaterial({color: 0xcccccc});
    		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(plane);
    
    		// 设置投影
    		plane.receiveShadow = true;
    		 --------------------------
    		
    		 物体----------------------
    		var geometry = new THREE.BoxGeometry(4, 4, 4);
    		var material = new THREE.MeshLambertMaterial( { color: 0x00ff00} );
    		var cube = new THREE.Mesh( geometry, material );
    		cube.position.x = 0;
    		cube.position.y = 2;
    		cube.position.z = 0;
    
    		// 设置投影
    		cube.castShadow = true;
    		scene.add( cube );
    		 物体 end ------------------
    
    		 光源-----------------------
    		var spotLight = new THREE.SpotLight( 0xffffff );
    		spotLight.position.set( -40, 60, -10 );
    		scene.add( spotLight );
    
    		// 设置投影
    		spotLight.castShadow = true;
    		 光源 end -------------------
    
    		 状态监视器-------------------
    		var stats = new Stats();
    		stats.showPanel( 0 );
    		document.body.appendChild( stats.dom );
    		 状态监视器 end --------------
    		
    		renderer.render( scene, camera );
    		
    	</script>
    </body>
    </html>

    渲染结果如下图:

    阴影是有了,但总觉得阴影不太对劲,比较模糊。通过查阅资料,我找到了答案:

    光源的位置一定要距离合适,否则容易引起阴影模糊粗糙的像打马赛克一样

     所以嘛,这个东西还是要自己去调的(其实具体原因我也不清楚,反正我没调好)

    展开全文
  • Three.js太阳系案例

    2020-06-03 20:03:16
    通过一个太阳系小案例对three.js进一步进行学习,适用于初次接触three.js引擎的开发者。
  • Three.js 零基础新手入门实战

    千人学习 2019-11-25 14:06:32
    面对这种情况,Three.js 应运而生,它不但对 WebGL 进行了封装,将复杂的接口简单化,而且基于面向对象思维,将数据结构对象化,非常方便我们开发。Three.js 的发展十分迅速,但是目前入门的相关资料比较少,文档又...
  • 使用three.js开发3d地图初探

    万次阅读 多人点赞 2018-05-15 16:28:10
    公司要做智慧消防楼层可视化,需要用到web3d,开源的引擎中先研究了cesium三维地球,但cesium做楼层感觉是大材小用,而且体验也不好,最终选用的是功能强大、更适合小型场景的threethree是图形引擎,而web二维三...

    公司要做智慧消防楼层可视化,需要用到web3d,开源的引擎中先研究了cesium三维地球,但cesium做楼层感觉是大材小用,而且体验也不好,最终选用的是功能强大、更适合小型场景的three。

    three是图形引擎,而web二维三维地图都是基于图形引擎的,所以拿three来开发需求简单的三维地图应用是没什么问题的。

    在线展示

    1.坐标转换

          实际地理坐标为经度、纬度、高度,而three.js使用的是右手坐标系x、y、z,本来考虑的是将经纬度坐标转换成墨卡托,再去和three的坐标系对应。而实际项目中,经纬度转墨卡托后,墨卡托的值太大,对应到three坐标系中,坐标距离原点太远,用户交互后,会有精度损失,于是先定义一个中间点,然后将墨卡托的结果减去这个中间点的值。(我自己是经度对应z轴,纬度对应x轴,高度对应y轴)

    function lonlatToMercator(lon,lat,height){
        var z = height ? height:0;
        var x = (lon / 180.0) * 20037508.3427892;
        var y = (Math.PI / 180.0) * lat;
        var tmp = Math.PI / 4.0 + y / 2.0;
        y = 20037508.3427892 * Math.log(Math.tan(tmp)) / Math.PI;
        return {x: x,y: y,z: z};
    }
    var center = lonlatToMercator(lonVal,latVal,heightVal);
    function lonlatToThree(lon,lat,height){
        var z = height? height:0;
        var x = (lon / 180.0) * 20037508.3427892;
        var y = (Math.PI / 180.0) * lat;
        var tmp = Math.PI / 4.0 + y / 2.0;
        y = 20037508.3427892 * Math.log(Math.tan(tmp)) / Math.PI;
        var result = {
            x: x - center.x,
            y: y - center.y,
            z: z -center.z
        };
        return result;
    }

     

    2.加载模型

     

        three.js支持多种模型加载,我是用草图大师建的模型,于是直接转成collada模型,然后使用three的collada模型加载器加载模型。因为要和three.js对应,而模型默认位于x-z轴上,所以要进行模型翻转等操作。

    3.创建标注

        three中,创建始终朝向相机的POI标注可以使用Sprite类,也可以使用canvas创建图标+文字类型的图形作为Sprite的纹理。sprite默认是有一个固定的3d长度,相机距离sprite越近,sprite在屏幕上越大,反之越小,过大或者过小都会导致sprite的canvas失真模糊,解决方案是计算出该点的屏幕像素与3d坐标长度的比值,然后将sprite缩放到一个合适的3d长度。

    var position = sprite.position;
    var canvas = sprite.material.map.image;
    if(canvas){
    	var poiRect = {w:canvas.width,h:canvas.height};
    	var scale = getPoiScale(position,poiRect);
    	sprite.scale.set(scale[0],scale[1],1.0);
    }
    
    function getPoiScale(position,poiRect){
        if(!position) return;
        var distance = camera.position.distanceTo(position);
        var top = Math.tan(camera.fov / 2 * Math.PI / 180)*distance;    //camera.fov 相机的拍摄角度
        var meterPerPixel = 2*top/container.clientHeight;
        var scaleX = poiRect.w * meterPerPixel;
        var scaleY = poiRect.h * meterPerPixel;
        return [scaleX,scaleY,1.0];
    }

     

    4.标注碰撞

     

          创建标注之后,放缩时难免会出现标注相互遮盖的情况,这样既影响美观也会遮盖住地图信息,这里需要检测标注间的遮盖,显示和不显示一些标注。

            这里主要是将标注点3d坐标转成屏幕坐标,再根据sprite中canvas的长度和高度,就可以知道sprite在屏幕的矩形范围。接下来就是计算各个标注点sprite的矩形相交了。

     var sprite1 = {x:x1,y:y1,w:w1,h:h1};	//sprite1左下角x,y,宽度、高度
        var sprite2 = {x:x2,y:y2,w:w2,h:h2};	//sprite2左下角x,y,宽度、高度
      //检测两个标注sprite是否碰撞
        function isPOIRect(sprite1,sprite2){
        	var x1 = sprite1.x,y1=sprite1.y,w1=sprite1.w,h1=sprite1.h;
        	var x2 = sprite2.x,y2=sprite2.y,w1=sprite2.w,h1=sprite2.h;
            if (x1 >= x2 && x1 >= x2 + w2) {
                return false;
            } else if (x1 <= x2 && x1 + w1 <= x2) {
                return false;
            } else if (y1 >= y2 && y1 >= y2 + h2) {
                return false;
            } else if (y1 <= y2 && y1 + h1 <= y2) {
                return false;
            }else{
                return true;
            }
        }

     

    5.加载设备

     

          创建设备,我同样使用的是Sprite类,跟创建标注类似,放缩之后,sprite在屏幕上的大小保持不变。

    6.设备点击

        raycaster类用于在3d中被鼠标选中的物体,这同样可以选中sprite对象,于是用此方法模拟设备的点击。其中deviceGroup是保存所有设备sprite的object3d对象。

     function onDocumentMouseDown(e) {
            e.preventDefault();
            mouse.x = (e.clientX / window.innerWidth) * 2 - 1;
            mouse.y = -(e.clientY / window.innerHeight) * 2 + 1;
            //新建一个三维单位向量 假设z方向就是0.5
            //根据照相机,把这个向量转换到视点坐标系
            var vector = new THREE.Vector3(mouse.x, mouse.y,0.5).unproject(camera);
            //在视点坐标系中形成射线,射线的起点向量是照相机, 射线的方向向量是照相机到点击的点,这个向量应该归一标准化。
            var raycaster = new THREE.Raycaster(camera.position, vector.sub(camera.position).normalize());
            //射线和模型求交,选中一系列直线
            var intersects = raycaster.intersectObjects([deviceGroup],true);          
            if (intersects.length > 0) {
                var intersected = intersects[0].object;
                if(intersected instanceof THREE.Sprite){
                	//点击到设备图标
                }  
            }
        }

    7.弹出框

           设备点击之后,一般都会以弹出框形式展示设备的具体信息,这里需要先定义弹出框的样式,然后将弹出点设备的三维坐标转换成屏幕坐标,设置一定的偏移量,再将弹出框放到偏移后的屏幕位置上。然后每次更改相机,重新计算弹出框的位置。

    //three世界坐标转为屏幕坐标
    function threeToScreen(position,camera){
        var worldVector = new THREE.Vector3(
                position.x,
                position.y,
                position.z
        );
        var standardVector = worldVector.project(camera);//世界坐标转标准设备坐标
        var a = window.innerWidth / 2;
        var b = window.innerHeight / 2;
        var x = Math.round(standardVector.x * a + a);//标准设备坐标转屏幕坐标
        var y = Math.round(-standardVector.y * b + b);//标准设备坐标转屏幕坐标
        return {
            x: x,
            y: y
        };
    }

    8.设备动画

            简单设备动画可以通过更改设备的材质、大小、位置来实现,比如通过定时更改设备的材质来实现设备图标的闪烁。

            项目中要模拟火情,因此花了些时间网上参考并用粒子系统做了个火焰动画,这里先用一个循环通过THREE.Vector3对象创建构成火焰的全部的点,放到THREE.Geometry对象的vertices中;再使用canvas创建火焰的纹理图形,传给THREE.PointsMaterial对象(并设置材质透明transparent:true和加法混合THREE.AddictiveBlending),最后以前面的THREE.Geometry和THREE.PointsMaterial创建THREE.Points对象,完成该火焰粒子系统的初始化。

            每个粒子都有单独的坐标,最后用一定的规律驱动粒子的移动达到动画的效果。

    9.鼠标绘制

            在3d中,鼠标的位置对应到三维坐标中是一条射线,因此需要添加绘制平面,点击时获取鼠标和绘制平面的交点,作为绘制点。绘制时监听鼠标的单击和移动事件。

            绘制线时,鼠标点击和移动时,直接更改线的geometry中的vertices;绘制面时,不仅仅要更改vertices还要计算所有顶点组合的三角面(我使用的是Earcut.js),作为geometry的faces,最后创建一个以这个geometry为几何形状的多边形mesh。

    //positions 三维坐标数组[[x,y,z],[x,y,z],...]
    function createPolygon(positions){
    	var shapePositons = [];
         for(var i=0;i<positions.length;i++){
    	    var position = positions[i];
    	    shapePositons.push(new THREE.Vector3(position[0],position[1],position[2]));
        }
    	var data = [];
    	for(var i=0;i<positions.length;i++){
    	    var position = positions[i];
    	    data.push(position[0],position[1]);
        }
    	var faces = [];
    	var triangles = Earcut.triangulate(data);
    	if(triangles && triangles.length != 0){
    		for(var i=0;i<triangles.length;i++){
    			var length = triangles.length;
    			if(i%3==0 && i < length-2){
    				faces.push(new THREE.Face3(triangles[i],triangles[i+1],triangles[i+2]));
    			}
    		}
    	}
        var geometry = new THREE.BufferGeometry();
        geometry.vertices = shapePositons;
        geometry.faces = faces;
        
        var mesh = new THREE.Mesh(geometry,material);
        return mesh;
    }

     

    10.未完

    买了一本three的书,打算要好好学习一下。

        

    展开全文
  • 相对于Flash,Flex,Silverlight等富客户端技术,WebGL之ThreeJS:通过OpenGL ES 2.0,WebGL可以为HTML5 Canvas提供硬件3D加速渲染,这样Web开发人员就可以借助系统显卡来在浏览器里更流畅地展示3D场景和模型了,还能...
  • threejs官网:https://threejs.org/ github各个版本:https://github.com/mrdoob/three.js/tags 版本更迭很快,我用的时候还是r90秒秒钟r91出来了 刚入门的时候可以看看这个教程:...

    前言

    threejs官网:https://threejs.org/
    github各个版本:https://github.com/mrdoob/three.js/tags
    版本更迭很快,我用的时候还是r90秒秒钟r91出来了

    刚入门的时候可以看看这个教程:http://www.hewebgl.com/article/articledir/1
    初级教程是免费的,中高级是收费的,写的不是很枯燥,也不用跟着敲代码,有个相机,渲染器,场景,光源的概念就可以了。它适配的版本是比较旧的,我当时用新版本跟着写有些demo无法完成,新手更谈不上根据版本之间的差别找到问题,慢慢就失去兴趣了。

    我的这个教程用的是r90版本,它有个比较好的地方是,当你使用高版本的threejs却使用低版本的语法时,浏览器console会有警告告诉你新的写法是什么样的。

    我的DEMO下载

    演示地址: 太穷了,带宽很小,加载卡顿请谅解(哭泣)
    相机转动做的比较仓促没有考虑细节,导致鼠标拖拽或是放大缩小卡顿,emmm小问题暂时不想改了
    https://www.hugeoyzy.top/threejs/src/demo1.html
    https://www.hugeoyzy.top/threejs/src/demo2.html
    下载:https://download.csdn.net/download/u010588262/10288776

    开发工具

    因为我主要是做java开发,所以就用idea了,因为idea写js也是有提示的,所以还挺方便,就建个Static Web项目就可以了:
    这里写图片描述

    我的项目结构是这样的:
    这里写图片描述

    调试需要做两点配置:
    1. 浏览器路径:
    这里写图片描述

    1. 浏览器启动参数,因为threejs要加载本地的图片文件,obj文件之类的,看网上教程都说是不允许的,要部署在apache和tomcat之类的,我没试,看到说可以加启动参数就加了,调试没问题
      –allow-file-access-from-files
      这里写图片描述

    调试的时候就在html文件上鼠标移到右上角,点击相应的浏览器图标就可以了
    这里写图片描述
    如果修改了html的话直接保存文件在浏览器刷新就能看到效果了,但是修改了js的话就要关闭页面重新点击浏览器图标。

    官方DEMO(肥肠重要)

    我入门最快的时候就是找到了官方DEMO之后

    一个是:http://stemkoski.github.io/Three.js/#hello-world
    这里的demo很入门,很好理解,页面最上方有github地址,可以去下载。唯一不好的是使用的版本很老。r60版本的,不过对于初学者一开始最重要的是理解大概的使用,不用纠结于最新版本。

    还有一个是:https://threejs.org/examples/#webgl_animation_cloth
    这里的demo相比第一个是比较高大上的,源代码就在你下载的threejs包里的examples目录下

    代码讲解

    这一块针对初学者中的初学者了,只要看过前言中的初级教程之后再看我的demo应该没问题了,demo的代码也比较整洁。

    demo中的css,fonts,images和objs基本都是从官方demo中搞过来的,页面上引用的js分别是什么作用也做了注释了:
    这里写图片描述

    util.js是我把公用的东西放在一起了,要看懂util.js需要对threejs基本的组件有一些了解。

    threejs的三围坐标是这样的,比如你现在对着电脑屏幕吧,把你屏幕的左下角想象成二维坐标原点,那往右就是x正方向,网上就是y正方向,从屏幕往外直盖脸的就是z正方向了。

    最上面的src()是用来初始化场景,相机和渲染器的,最开始的textureLoader = new THREE.TextureLoader();是用来加载图片材质的,在大多数教程里用的都是ImageUtils来加载的,这个是新版本的改动,我说一下我对这仨玩意儿的理解吧

    场景:就是一个黑盒子呗,把你要展示的东西全往里面装,地板啊,天花板啊,盒子啊,球啊,货架啊,三D字体啊全塞进去。为什么是黑盒子?因为你看不见它,也不看不见塞进去的东西。场景的初始化很简答就一句话scene = new THREE.Scene();

    相机:相机可以在任意的位置,任意的角度”拍摄”黑盒子里的场景,相机的初始化稍微复杂一些。

        var SCREEN_WIDTH = window.innerWidth;
        var SCREEN_HEIGHT = window.innerHeight;
        var VIEW_ANGLE = 45, ASPECT = SCREEN_WIDTH / SCREEN_HEIGHT, NEAR = 0.1, FAR = 20000;
        camera = new THREE.PerspectiveCamera(VIEW_ANGLE, ASPECT, NEAR, FAR);
        scene.add(camera);
        camera.position.set(0, 600, 1000);
        cameraRadius = Math.sqrt(camera.position.x * camera.position.x + camera.position.z * camera.position.z);
        camera.up.set(0, 1, 0);
        camera.lookAt(new THREE.Vector3(0, 0, 0));

    关于相机比较难理解的是position,up和lookAt的关系。你可看看这个视频http://www.hewebgl.com/video/2,虽然我看完了也没怎么看懂。
    尝试解释一下吧。
    现在,把你的手机打开摄像头,正对着屏幕,想象它就像单反一样上面右边有个快门,这就是threejs中相机的初始方向,就是从z轴正方向看向z轴负方向。position是什么意思呢,现在把手机往右平移,意思是position.x在增加。lookAt也很容易,就是相机往哪儿拍呗。比较难理解的是up,好现在把手机位置固定,只能旋转哦,也就是说position固定了,好了现在把手机旋转镜头对着屏幕左下角,也就是咱们的三维坐标原点,也就是说lookAt也固定了。up的作用就是你现在可以旋转手机了,保持镜头对着屏幕左下角的方向,手机的中心点位置不要变,旋转手机,拍出来的画面就会是正的,或者斜着的,或者上下倒过来的。随着你旋转手机快门的朝向也在变是吧,默认快门是对着Y轴正方向的,也就是(0,1,0)如果把手机颠倒,up就变成了(0,-1,0),拍出来的画面也就是上下颠倒的,因为你虽然可以倒着手机拍,但是看照片的时候得把手机正过来看,画面也就是反的咯。

    渲染器
    可以看到相机的初始化过程中没有与场景绑定,他们俩就像在两个平行世界一样,看似在一起,其实没在一起,需要用渲染器把他们俩关联起来,这样,相机就拍到了场景里的东西,再通过渲染器展示在浏览器上被我们看到了。Decetor是通过Detector.js引入进来的东西,用于判断浏览器兼容性的。

        if (Detector.webgl)
            renderer = new THREE.WebGLRenderer({antialias: true});
        else
            renderer = new THREE.CanvasRenderer();
        renderer.setSize(SCREEN_WIDTH, SCREEN_HEIGHT);
        container = document.getElementById('ThreeJS');
        container.appendChild(renderer.domElement);

    以地板为例怎么搞一个东西放在场景里,CSDN的代码注释没有这么详细,写博客的时候加的,对不住只下资源不看文章的朋友。PlaneGeometry就是一个平面,SphereGeometry就是一个球,CubeGeometry就是一个立方体…….感兴趣的可以百度多了解一下其他组件。材质就是各种Material,也有很多种,有受光照影响的,有不受光照影响的。把组件和材质组合起来就是一个完整的物体啦,就是THREE.Mesh这个方法把他们组合起来,第一个参数是组件,第二个参数是材质,材质还可以传入一个数组,你可能觉得设置多个有啥意义啊一个盖住一个的,材质是可以设置透明度的,明白了吧。

    function addfloor() {
        // 加载图片作为地板材质
        var floorTexture = textureLoader.load('images/checkerboard.jpg');
        // 沿x方向和Y方向都重复填充
        floorTexture.wrapS = floorTexture.wrapT = THREE.RepeatWrapping;
        // x方向和y方向各重复几次,不理解的话改改这个值看看效果就知道了
        floorTexture.repeat.set(4, 4);
        // 将材质包装成表面材料,设置正反两面都要铺上
        var floorMaterial = new THREE.MeshBasicMaterial({map: floorTexture, side: THREE.DoubleSide});
        // 平面对象
        var floorGeometry = new THREE.PlaneGeometry(1000, 1000, 1, 1);
        // 把对象和材料包装成Mesh
        floor = new THREE.Mesh(floorGeometry, floorMaterial);
        // 设置位置放入场景啦
        floor.position.y = -0.5;
        floor.rotation.x = Math.PI / 2;
        scene.add(floor);
    }

    others()方法里是一些可有可无的辅助,看注释就明白了。
    animate()就是开始持续渲染,渲染就是通过renderer.render(scene, camera);把渲染器搞到的东西放在浏览器上给你看,持续渲染就是通过重复调用方法本身可以实现动画的效果requestAnimationFrame(animate);,除了这两个东西还调用了update();方法,update方法里就是慢慢的移动组件或者刷新其他需要更新得组件。requestAnimationFrame方法是比较平滑的动画,我之前想用Tween.js实现相机转动的效果,很卡顿,不流畅。

    woodycube()就是封装了获得木箱,因为两个demo里都用到了木头箱子。

    后面有空再说一下demo中的代码

    2018年3月16日
    更新了一下util.js中的代码,把鼠标点击选中事件和getMeshed方法从demo2中移到util里面了
    点击事件

    document.addEventListener("mousedown", onDocumentMouseDown, false);
    function onDocumentMouseDown(e) {
        e.preventDefault();
        // 点击页面时停止相机旋转,因为相机旋转的时候无法选中物体,这个问题没有解决,有点麻烦
        rotate = false;
        //将鼠标点击位置的屏幕坐标转成threejs中的标准坐标,具体解释见代码释义
        var mouse = {};
        mouse.x = (e.clientX / window.innerWidth) * 2 - 1;
        mouse.y = -(e.clientY / window.innerHeight) * 2 + 1;
        //新建一个三维单位向量 假设z方向就是0.5
        //根据照相机,把这个向量转换到视点坐标系
        var vector = new THREE.Vector3(mouse.x, mouse.y, 0.5).unproject(camera);
        var sub = vector.sub(camera.position);=
        var param2 = sub.normalize();
        var raycaster = new THREE.Raycaster(camera.position, param2);
    
        //射线和模型求交,选中一系列直线,getMeshs方法用于获得场景中可以被选中的所有Mesh
        var intersects = raycaster.intersectObjects(getMeshs());
    
        if (intersects.length > 0) {
            // outlineMesh是物体边框组件,每次只会有一个物体被选中,就把这个东西定义为全局的
            // 每次选中另一个物体之前先删除,相当于取消前一个物体的选中
            scene.remove(outlineMesh);
            //选中第一个射线相交的物体
            var SELECTED = intersects[0].object;
            var outlineMaterial2 = new THREE.MeshBasicMaterial({color: 0x00ff00, side: THREE.BackSide});
            outlineMesh = new THREE.Mesh(SELECTED.geometry.clone(), outlineMaterial2);
            outlineMesh.position.set(SELECTED.position.x, SELECTED.position.y, SELECTED.position.z);
            outlineMesh.scale.multiplyScalar(1.05);
            scene.add(outlineMesh);
        }
    }
    展开全文
  • three.js 文件

    2018-07-14 14:58:24
    three.js 文件
  • threejs入门

    万次阅读 2019-03-07 20:26:54
    今年刚刚接触threejs。这玩意封装得挺不错。为了使大家感观上能够了解threejs.这里直接分享一段代码。看完就知道threejs的套路了。所有的学习资料,源代码,从github上已经足够。5000多的源码分享,天啊。。。 ...
  • Threejs 快速入门

    万次阅读 2017-05-24 17:23:33
    刚好最近在做一个活动时,就遇到了需要播放3D全景视频的需求,顺便就研究了一下Threejs,一个用于在浏览器中绘制3D图像的JS库(https://github.com/mrdoob/three.js),这篇文章算是做个笔记,也希望能帮助到那些想...
  • Three.js 基础入门

    万次阅读 多人点赞 2018-07-01 03:45:55
    课程介绍 近些年,浏览器的功能越来越强大,渐渐得成为了...面对这种情况,Three.js 应运而生,它不但对 WebGL 进行了封装,将复杂的接口简单化,而且基于面向对象思维,将数据结构对象化,非常方便我们开发。Thre...
  • Threejs 官网 - Three.js 的图形用户界面工具(GUI Tools with Three.js)
  • Three.js 中文文档和在线演示实例

    万次阅读 多人点赞 2016-06-16 19:40:24
    Three.js是当下最流行的网页3D渲染JS引擎,其主要是对WebGL编程以面向对象方式进行的封装。 踏得网专注于HTML5技术生态链的资源开发,鉴于网络上Three.js方面的资料比较散乱,且良莠不齐, 因此我们把Three.js的官方...
  • Three.js和其它webgl框架

    万次阅读 多人点赞 2018-08-24 11:23:08
    WebGL (Web图形库) 是一种JavaScript API,用于在任何兼容的Web浏览器中呈现交互式3D和2D图形,而无需使用插件。WebGL通过引入一个与OpenGL ES 2.0紧密相符合的API,可以在HTML5 元素中使用。(MDN简介) 在我的...
  • 初识three.js,搭建three.js+vue.js项目

    千次阅读 2018-09-22 06:37:04
    简介:WebGL(全写Web Graphics Library)是一种3D绘图协议,这种绘图技术标准允许把JavaScript和OpenGL ES 2.0(OpenGL for Embedded Systems,OpenGL嵌入式版本,针对手机、游戏机等设备相对较轻量级的版本)结合...
  • 58 Three.js 通过THREE.Raycaster给模型绑定点击事件

    万次阅读 热门讨论 2018-01-14 02:59:03
    由于浏览器是一个2d视口,而在里面显示three.js的内容是3d场景,所以,现在有一个问题就是如何将2d视口的x和y坐标转换成three.js场景中的3d坐标。好在three.js已经有了解决相关问题的方案,那就是THREE.Raycaster...
  • Three.js编辑器editor使用详解

    万次阅读 2020-08-03 15:34:14
    Three.js编辑器editor使用详解官网下载Three.js压缩包其他的文件内容如下:了解过文件内容之后下一步: 官网下载Three.js压缩包 github官网源码包 解压后文件目录如下图: 其他的文件内容如下: Build目录:包含两...
  • Three.js】五、three.js中的材质——Material一、 three.js中的材质就是几何体表面的材料。 一、
  • threejs-inspector, 用于调试 three.js的Chrome devtool扩展 Three.js-检查器three.js 检查器是 Chrome devtool的扩展名。 它允许你在网页中查看 Three.js 场景。 你可以从 Chrome 网上商店安装 Three.js Inspector ...
  • Three.js fbx文件导入

    万次阅读 热门讨论 2018-03-08 16:39:57
    源码 下载 https://download.csdn.net/download/qq_34206863/10361429 其实可以先看看官方案例 你想要的东西 官方里面都有,就看你找不找得到了。。。。 话不多说 我们先看看这个例子吧 ...am
  • Three.jsthree.js之几何体与网格
  • 38 Three.js高级材质THREE.ShaderMaterial

    千次阅读 2017-12-06 22:36:06
    注意 看这一篇文章最好有webgl基础的同学看,如果没有webgl原生基础,你会看...着色器可以将Three.js中的JavaScript网格转换为屏幕上的像素。通过这些自定义的着色器,可以明确地指定对象如何渲染,以及如何覆盖或...
  • 简介 这种材质可以用来创建暗淡的并不光亮的表面。 无光泽表面的材质,无镜面高光。 这可以很好地模拟一些表面(如未经处理的木材或石头),但不能用镜面高光(如上漆木材)模拟光泽表面。 该材质非常易用,而且会...
  • Three.js+tween.js 基础(一)

    千次阅读 2019-01-26 11:08:36
    Three.js 简介 Three.js是众多WebGL三维引擎框架其中之一,源自github的一个开源项目,项目地址:https://github.com/mrdoob/three.js 。可以利用three.js进行网页上的三维场景(机械、建筑、游戏等)创建,能写出...
  • three.js 绘制地板Every developer has their favorite tools, languages, and technologies to work with. Sometimes it derives from another passion such as solving mathematical problems, white-hat hacking,...
  • 简介 上一节我们介绍了一下THREE.PointCloud。THREE.PointCloud构造函数接收两个属性:...如果我们基于THREE.BoxGeometry对象创建THREE.PointCloud对象,即使不添加顶点,我们也将会得到八个粒子,立方体一个角上...
  • 33 Three.js的材质THREE.MeshBasicMaterial

    万次阅读 2017-09-03 20:53:12
    简介 MeshBasicMaterial是一种非常简单的...Three.js除了可以设置共有的属性外,还可以设置以下属性: 名称 描述 color(颜色) 设置材质的颜色 wireframe(线框) 设置这个属性的可以将材质渲染...
  • Three.js】一、第一个Three.js项目

    千次阅读 2019-08-29 08:45:42
    Three.js】一、第一个Three.js项目一、Three.js下载 一、Three.js下载 Three.js github:https://github.com/mrdoob/three.js
  • Three.js】十一、three.js使用Tween.js tween.js是一个轻量级js库,可用来实现一些动画效果。github地址:https://github.com/tweenjs/tween.js/. cnpm安装方式:cnpm install @tweenjs/tween.js -S 使用方法...
  • 44 Three.js拉伸几何体THREE.ExtrudeGeometry

    千次阅读 2017-12-19 00:21:05
    例如,如果我们拉伸THREE.CircleGeometry,就会得到一个类似圆柱体的图形;如果我们拉伸THREE.PlaneGeometry,就会得到一个立方体。下面我们介绍一下常用的THREE.ExtrudeGeometry THREE.ExtrudeGeometry简介 ...

空空如也

1 2 3 4 5 ... 20
收藏数 62,594
精华内容 25,037
关键字:

three.js