zoukankan      html  css  js  c++  java
  • three.js基础前置知识

    这一节是纯理论知识,用于介绍three.js的入门概念,也就是开发前需要准备的理论基础。

    一,三剑客

      当然就是scene,camera,renderer这三个基本要素。

      scene是一个用于容纳三维空间的场景,相当于一个容器;

      camera则是一双帮助我们观察3d世界的眼睛;

      而renderer是一个渲染器,它负责把无色无相的三维物体绘制成肉眼可见的物体;

    二,选什么相机

      选透视相机(PerspectiveCamera)。

      简单来说,透视相机有距离感,远的物体看起来小一点,近的物体看起来大一点,符合现实生活中的人眼观感;

      而正交投影相机没有距离感,所有的物体看起来都是在一条直线上;

      

      (左为透视相机,右为正交投影相机)

    三,如何生成一个基础物体?

      基础物体mesh = 几何结构(geometry)+ 贴片材质(material)

      几何结构就像一个骨架,three.js内置了不少几何结构,像常见的球体,正方体,圆环等等;

      而贴片材质则决定这个骨架的样式,可以画上纯色,也可以贴上图片纹理等;

    四,该选什么材质?

      材质主要分为与光照没有任何交集的基础材质(MeshBasicMaterial),以及必须要光照才能看见,可以配合光照产生阴影效果的标准材质(MeshStandardMaterial);

      一般来说,全景图的视角在物体内部,只观察图片纹理,不需要阴影效果,可选用基础材质;

      而像3d物体,给物体打上平行光,显现出物体的影子,可以让画面更真实,因此选用标准材质。但此时环境光要慎用,因为如果物体是纯色材质,视觉上环境光会和物体混色。如:在标准材质下:黄色环境光+蓝色材质物体 = 视觉上物体呈绿色;

    五,初始化透视相机的参数如何设置?

      var camera = new PerspectiveCamera(fov, aspect, near, far)帮助我们初始化一个相机,参数依次为:视野,可观测距离比,最近观测距离,最远观测距离。

      如果你和我一样没什么图形学基础,不太懂透视,可以使用一个通用的参数设定:

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

    六,相机该看哪儿?

      默认情况下,相机处于空间直角坐标系的原点;

      一般的做法是,通过相机的position属性把它摆放到三维空间的某个位置;

      再通过lookAt属性设置一下相机该看向哪里,一般看向物体的正中心(new THREE.Vector3(0, 0, 0));

    七,如何实现实时渲染(循环渲染)?

      结合requestAnimationFrame获得一个合适的帧率,然后递归调用渲染器的render方法就行了,requestAnimationFrame本质上就是一个异步延时函数。

      代码如下所示:

    function animate() {
        renderer.render(scene, camera);
        requestAnimationFrame(animate);
    }
    

      

    八,图片纹理默认贴在几何体外部,如何让其贴在几何体内壁?

      一般做法是将几何体的scale属性的某一个坐标设为负值就行了,如:

    geometry.scale(- 1, 1, 1);
    

      

    九,自由拖动查看全景图,该怎么搞?

      这里的大体思路是这样的:根据拖动事件计算出一个新的经纬度,然后通过某种换算公式将新的经纬度换算为三维空间坐标(x,y,z),然后camera看向这个三维坐标。

      换言之,就是camera被安装在球体内部的球心,然后探头可以转来转去,查看球体内壁的不同区域。

      关于经纬度转三维坐标,如果你并不想去过多了解这个转换函数的具体意义,也可以直接使用,代码如下:

      

    function transCoord(sphereRadius,lon,lat) { // 参数分别表示球体的半径,经度,纬度
    
    			lat = Math.max(-85, Math.min(85, lat));
    			let phi = THREE.Math.degToRad(90 - lat);
    			let theta = THREE.Math.degToRad(lon);
    
    			camera.target.x = sphereRadius * Math.sin(phi) * Math.cos(theta);
    			camera.target.y = sphereRadius * Math.cos(phi);
    			camera.target.z = sphereRadius * Math.sin(phi) * Math.sin(theta);
    
    			camera.lookAt(camera.target);
    		}
    

    十,自由拖动查看3d物体,该怎么弄?

      与全景图相对应,3d物体拖动查看也是很常见的东西;

      它的大体思路可能是这样的:

      (1)先把相机安装在物体外部的某一个点,然后相机探头固定看着物体中心,当我们拖动物体时,实际上就是在令物体围着自身的中心点做各种旋转,相机在外部一动不动,“静静地看着物体装逼”;

      (2)然后相机探头固定看着物体中心,当我们进行拖动时,3d物体不懂,相机在物体外围的空间“飞来飞去”;

      如果你不想考虑这么多坐标换算的东西,不想搞这么多数学,也可以当个api的调用者,three.js官方提供了OrbitControls,用来定于用户对物体的旋转查看行为,其使用十分简单。

      

    十一,鼠标缩放如何比较科学地解决?

      鼠标缩放画面,其实就是在缩放透视相机的视野(fov);

      视野越大,则表示看到的范围越大,离物体也就越远;

      视野越小,则表示看到的范围很小,说明离物体很近,有“一叶障目”之感;

      明白了这一点,我们就可以通过调用内置api来实现这个缩放的功能,内置的api封装了很多细节,也简化了我们的运算,代码如下:

    function mouseWheelHandler(event) {
    
    			let fov = camera.fov + event.deltaY * 0.05;
    
    			camera.fov = THREE.Math.clamp(fov, 10, 75); // 后两个参数表示最小视野,最大视野,也就是缩放范围
    
    			camera.updateProjectionMatrix();
    
    		}
    

      

      以上就是three.js一些比较入门的理论知识,下次找个时间,我们将从一个实际页面出发,动手完成一个可交互的简单3d物体。

      

  • 相关阅读:
    Android底部菜单栏的两种实现方式 附完整源码
    如何创建WebView
    实现 unity MonoBehaviour API5.4 的消息
    linux常用命令2
    Mac 自带的Apache php 狼神的
    高频sql语句汇总。不断更新。。
    4.数据库mysql相关
    Android keystore文件查看应用签名md5
    Java 多线程进阶-并发协作控制
    Java 多线程进阶-并发数据结构
  • 原文地址:https://www.cnblogs.com/zhangnan35/p/10917109.html
Copyright © 2011-2022 走看看