threejs学习随记(一)

     搞浏览器3D绘图的应该都或多多少接触过threejs,其之于webGL,如jquery之于js。有了webGL,开发者仅通过遵循其提供的api和js就能在html网页中进行3d绘图。而直接使用原生的webGL API 进行3d绘图十分繁琐,所以一个优秀的webGL框架——threeJs应运而生,其包装了很多复杂的细节,使3d绘图变得轻松了起来。

    

     在Three.js中,要渲染物体到网页中,我们必须构建场景(scene)、相机(camera)和渲染器(renderer)。有了这三样东西,才能将物体渲染到网页中去。

ThreeJS绘图的核心:

  1. 设置渲染器renderer
  2. 设置场景 scene
  3. 设置相机 camera
  4. 设置光源 light
  5. 设置物体 object

1)  渲染器

     渲染器的作用就是将相机所拍摄到的场景内容渲染到2d的画布上,从而在浏览器中展示。Threejs中的渲染器主要是WebGLRender。创建一个渲染器的方式就是new一个WebGLRender实例。

代码示例如下:

var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
      创建渲染器实例后,需要设置其画布大小,渲染器renderer的domElement元素,表示渲染器中的画布,所有的渲染都是画在domElement上的。画布需要append进页面的某个元素中(这里是body)才能在浏览器中得以显示。

2)  场景

    场景就是物体所处的环境,其作用就是一个容器。用来放置物体,灯光和相机。换句话说,开发时创建的物体,灯光和相机都需要将其添加进场景中,只有这样才能进行正确渲染。Ps:经过测试,相机其实可以不用添加进场景。创建一个场景的方式就是new一个scene实例。

代码示例如下:

var scene = new THREE.Scene(); // 场景

3)  相机

     相机就如同人的眼睛,人站在不同角度看同一个静态事物,会看到不同的景象。因此,相机设置在不同的位置,浏览器中呈现的物体形态和位置也会有所不同。Ps:Threejs中默认相机处于三维空间原点,而创建的物体也默认中心在原点,因此在开发时,注意改变相机位置。

Threejs中的相机有以下几种类型:

  • CubeCamera 立方体相机,会创建6个摄像头。
  • OrthographicCamera 使用正摄投影原理的相机,及被渲染物体的尺寸与相机距离无关。详细了解参考官网示例。
  • PerspectiveCamera 使用透射投影原理的相机,该相机在3d渲染中使用最为普遍。特点是:离相机远呈现更小,近则更大。符合人体对事物的实际观察规律。
  • StereoCamera 立体声相机,暂不了解

代码示例如下:

var camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000);

其构造器如下:

 

4)  光源

    OpenGL(WebGL)的三维空间中,存在“点光源”和“聚光灯”两种类型。 而且,作为点光源的一种特例还存在平行光源(无线远光源)。另外,作为光源的参数还可以进行 [环境光] 等设置。

  Threejs中的光源有以下几种类型:

  • Ambient Light 环境光,特点:同等地照亮场景中的所有物体,没有方向。
  • Direction Light 平行光,特点:定向,距离远,普遍模拟太阳光。使用正摄投影原理的相机,及被渲染物体的尺寸与相机距离无关。详细了解参考官网示例。
  • HemisphereLight 半球光,特点:位于场景正上方。
  • PointLight 电光源,特点:模拟灯泡。
  • RectAreaLight 矩形区域光源,特点:在整个面上均匀地发射出一个矩形平面。可以用来模拟像明亮的窗户或带状照明的东西。
  • SpotLight 聚光灯,特点:能投射锥形阴影区域的点光源

   和OpenGL一样,在一个场景中可以设置多个光源。 基本上,都是环境光和其他几种光源进行组合。 如果不设置环境光,那么光线照射不到的面会变得过于黑暗。

5)  物体

    待渲染于画布上的3D图形,其创建后必须包含在场景中才能被正确渲染,最常用的一种方法是使用网格(Mesh)进行绘制。网格是由一个或多个多边形组成的物体,各个顶点的坐标(x, y, z)定义了多变在3D空间中的位置。网格中的多边形通常是三角形(包含三个顶点)和四边形(包含四个顶点)。3D网格通常也被称为模型(model)。

    Threejs中内置了许多不同形状的几何体,常见的有:BoxGeometry(立方体),SphereGeometry(球体),CylinderGeometry(圆柱体),PlaneGeometry(平面)等,其余可查询官网API。

     一个完整3D图形应该由两部分组成:网格,网格表面的材质(material),其中材质主要体现物体的外观,通常依赖于一个或多个光源来呈现出外观效果。Threejs中有多种类型的材质,常用的如下:

  • MeshBasicMaterial:一个以简单着色(平面或线框)方式来绘制几何形状的材料。最主要是其不受光照影响,Ps:经测试,使用此材质的几何体即便不设置光源也
  • MeshLambertMaterial:无光泽的表面材质,无镜面高光。Ps:物体颜色的最终呈现会受光照的影响。
  • MeshPhongMaterial:用于表面有光泽的材料,可以模拟具有镜面高光的光泽表面。
  • MeshNormalMaterial:可以是物体表面呈现彩虹色的材质。Ps:经测试,使用此材质的几何体即便不设置光源也可见。

     以创建简单的立方体为例,代码如下:

     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);//添加到场景中(重要)

 6)渲染

    以上,我们进行了渲染器,场景,相机,光源,物体的创建,最后一步就是渲染。实现这个功能的函数是:

    renderer.render(scene, camera);

渲染函数的原型:render( scene, camera, renderTarget, forceClear )

  • scene:前面定义的场景
  • camera:前面定义的相机
  • renderTarget:渲染的目标,默认是渲染到前面定义的render变量中
  • forceClear:为true时,每次绘制之前都将画布的内容给清除,即使自动清除标志autoClear为false,也会清除。

7)循环渲染

   就是不停的对画面进行渲染,即使画面中什么也没有改变,也需要重新渲染。当制作物体的动画效果时就需要循环渲染,只有这样才能将物体位置或形态的变化及时渲染在画布上。下面就是一个渲染循环:

  function render() {   
       cube.rotation.x += 0.1; 
       cube.rotation.y += 0.1;   
       renderer.render(scene, camera); //加入之前创建的场景和相机。  
       requestAnimationFrame(render); 

      以上面创建的立方体为例,使立方体一直绕着x、y轴旋转,每次改变其旋转角度后会重新调用render函数进行渲染,最终呈现的状态就是一个不断在旋转的立方体。其中一个重要的函数是requestAnimationFrame,该函数功能如同setIntervl(),不过其性能更好。

简单完整示例




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




   
   
   
<script type="text/javascript"> var scene,camera,render,geometry,material,mesh,light; var container = document.getElementById("container"); render = new THREE.WebGLRenderer(); render.setSize(container.offsetWidth,container.offsetHeight); container.appendChild(render.domElement); render.setClearColor(0xFFFFFF, 0.5) scene = new THREE.Scene(); camera = new THREE.PerspectiveCamera(45,container.offsetWidth/container.offsetHeight,1,5000); camera.position.set(0,0,10); // scene.add(camera); light = new THREE.DirectionalLight(0xff0000, 1.0);//设置平行光源 light.position.set( 200, 200, 200 );//设置光源向量 scene.add(light);// 追加光源到场景(重要!) geometry = new THREE.BoxGeometry(1,1,1); material = new THREE.MeshBasicMaterial({color: 0x00ff00}); mesh = new THREE.Mesh(geometry,material); scene.add(mesh); renderer(); function renderer() { mesh.rotation.x += 0.1; mesh.rotation.y += 0.1; render.render(scene,camera); window.requestAnimationFrame(renderer); } </script>

效果图如下(实际是动图):


参考链接:

1.  WebGL中文网

2. threejs官方文档


 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值