WebGL ThreeJS学习总结三

栏目: 编程工具 · 发布时间: 5年前

内容简介:总结三主要是学习ThreeJS框架和一些数学知识等,包括相机、光线、形状、变换、视角控制、焦点控制、矩阵和弧度等;并根据所学知识实现一些稍复杂的效果。在ThreeJS框架中按这么理解

总结三主要是学习ThreeJS框架和一些数学知识等,包括相机、光线、形状、变换、视角控制、焦点控制、矩阵和弧度等;并根据所学知识实现一些稍复杂的效果。

数学相关(math)

常用数据类型和齐次坐标

在ThreeJS框架中 Vector2Vector3Vector4Matrix3Matrix4 是很重要的数据类型,这些对象提供了很多很重要的数学工具;其中 Vector2Vector3Matrix3 很好理解,分别表示二维向量、三维向量、三阶矩阵;

按这么理解 Vector4Matrix4 则是四维向量和四阶矩阵,关键问题在于在三维空间坐标系中为什么要多增加一维呢?

首先来说一说为什么需要有 Vector4

在三维空间中我们可以使用 (x,y,z) 来表示空间中某一点,但是如果这个点在无穷远处,应该怎么表示呢? (∞,∞,∞) 这样子吗?

为了解决这个问题,数学家提出了齐次坐标的概念,用 N+1 个量来表示 N 维坐标;比如点 (x,y,z) 可以表示为 (x*w,y*w,z*w,w)w 即为新增的那个量;

额外新增一个量之后,三维空间中过原点且在向量(x,y,z)方向上无穷远处的点就可以表示为(x,y,z,0)。

接着再来聊一聊 Matrix4

在三维空间中常用的变换有三种 旋转缩放平移

旋转 需要乘以旋转矩阵 R

[x2,y2] = [x1,y1] * R;

缩放 需要乘以缩放矩阵 S

[x2,y2] = [x1,y1] * S;

但是 平移 确是坐标相加:

x2 = x1 + tx;
y2 = y1 + ty;

那能不能把缩放、旋转、平移都统一转换成矩阵乘法的形式呢,这样不管进行多少次变换,都可以表示成矩阵连乘的形式了。

WebGL ThreeJS学习总结三

这也就是 Matrix4 存在的意义了。

齐次坐标表示是计算机图形学的重要手段之一,它既能够用来明确区分向量和点,同时也更易用于进行线性变换。

数学方法 Three.Math

/**
 * 如果value大于等于min且小于等于max则返回value
 * 如果value小于min则返回min
 * 如果value大于max则返回max
 */
clamp ( value, min, max )

核心相关(core)

3D物体 THREE.Object3D

这是ThreeJS类库中大部分对象的基类。

Object3D对象的变换函数基本都是相对于物体自身的坐标系而言的。

几何图形 THREE.Geometry

var geometry = new THREE.Geometry();
//vertices属性中包含该图形的所有顶点位置
geometry.vertices.push(
    new THREE.Vector3( -10,  10, 0 ),
    new THREE.Vector3( -10, -10, 0 ),
    new THREE.Vector3(  10, -10, 0 )
);


/**
 * skinIndices属性指定当前序号顶点被哪些骨骼控制,蒙皮网格中每个顶点最多只能被四个骨骼控制;
 * 下述代码表明第15个顶点被第0、5、9、10个骨骼所控制。
 */
geometry.skinIndices[15] = new THREE.Vector4(   0,   5,   9, 0 );
/**
 * skinWeights属性指定当前序号顶点被指定骨骼控制的权重;
 * 下述代码表明第15个顶点被对应四个骨骼所控制的权重分别是20%、50%、30%、0%。
 */
geometry.skinWeights[15] = new THREE.Vector4( 0.2, 0.5, 0.3, 0 );

对象集合 THREE.Group

网格 THREE.Mesh

线条 THREE.Line

线条集合 THREE.LineSegments

球体 THREE.SphereGeometry

/**
 * 构造函数:
 * radius表示球体半径;
 * widthSegments表示横向划分区域数量;
 * heightSegments表示纵向划分区域数量;
 * 其它不明
 */
var geometry = new THREE.SphereGeometry(radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength);

圆环 THREE.RingGeometry

/**
 * 构造函数:
 * innerRadius表示内圆半径;
 * outerRadius表示外圆半径;
 * thetaSegments表示圆环圆度;
 * phiSegments表示内圆到外圆方向上的细分线段数;
 * thetaStart圆环面的起始角度;
 * thetaLength圆环面圆周弧长;
 */
var geometry = new THREE.RingGeometry(innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength);

缓存数据模型 THREE.BufferGeometry

WebGL渲染器 THREE.WebGLRenderer

/**
 * 构造函数:
 * antialias:true/false 用于设置是否开启反锯齿;
 * precision:highp/mediump/lowp 用于设置着色器精度;
 * alpha:true/false 用于设置背景色是否透明;
 */
var render = new THREE.WebGLRenderer(parameters);

蒙皮网格 THREE.SkinnedMesh

管道 THREE.TubeGeometry

样条曲线 THREE.CatmullRomCurve3

纹理相关(texture)

画布纹理 THREE.CanvasTexture

CanvasTexture 对象继承自 Texture 对象;区别在于 CanvasTexture 对象只能使用 Canvas 元素作为素材且其 needsUpdate 属性默认为 true ,这样才能保证 Canvas 元素内容被完全加载了。

材质相关(material)

基础网孔材质 THREE.MeshBasicMaterial

基础线条材质 THREE.LineBasicMaterial

兰伯特材质 THREE.MeshLambertMaterial

一种非光滑表面材质没有高亮的镜面反射。

/**
 * 简单解释下构造函数里边的参数;
 * color表示漫反射光;
 * emissive表示自发光(可以简单理解为荧光,如果没有设置环境光,物体会表现为其自发光)。
 */
var material = new THREE.MeshLambertMaterial({
    color:0xff00ff,
    emissive:0xdd4422
});

surfaceColor = emissive + ambient + diffuse + specular;

上边公式表明物体表面的颜色是漫反射光(diffuse)、环境反射(ambient)、自发光(emissive)和镜面反射(specular)等光照作用的总和。

自定义着色器材质 THREE.ShaderMaterial

一种自定义着色器材质,直接使用GLSL语言编写,运行在GPU;当ThreeJS没有提供某种材质时或者存在很多单一对象模型性能较低时,可以使用它。

加载器相关(loader)

纹理加载器 THREE.TextureLoader

var loader = new THREE.TextureLoader();
loader.load( 'textures/land_ocean_ice_cloud_2048.jpg', function ( texture ) {
    var geometry = new THREE.SphereGeometry( 100, 20, 20 );
    var material = new THREE.MeshBasicMaterial( { map: texture, overdraw: 0.5 } );
    /**
     * 由于纹理加载属于异步流程,在回调函数把模型加入场景中后需要再次渲染才能显示出来
     */
    var mesh = new THREE.Mesh( geometry, material );
    render();//再次渲染
},function ( xhr ) {
    console.log( (xhr.loaded / xhr.total * 100) + '% loaded' );
},function ( xhr ) {
    console.log( 'An error happened' );
});

加载管理工具 THREE.LoadingManager

光照相关(light)

环境光 THREE.AmbientLight

环境光没有明确的光源位置,在各处形成的亮度也是一致的,光照颜色会添加到整个场景和所有对象的当前颜色上。

AmbientLight( color, intensity )
  • color — 环境光颜色;
  • intensity – 光照强度。

点光源 THREE.PointLight

点光源照到不同物体表面的亮度是线性递减的,因此离点光源距离越远的物体会显得越暗。

PointLight( color, intensity, distance, decay )
  • color — 环境光颜色;
  • intensity – 光照强度;
  • distance – 设置光距离物体的距离;
  • decay – 设置光的衰减量。

聚光灯 THREE.SpotLight

聚光灯是一种特殊的点光源,它能够朝着一个方向投射类似圆锥形的光线;

SpotLight( color, intensity, distance, angle, penumbra, decay )

相比点光源多了两个参数;

  • angle — 聚光灯的张角;
  • exponent – 光强在偏离目标的衰减指数。

所谓的 目标 是指如果想让聚光灯跟着某一物体移动,需要设置该物体为该聚光灯的 目标

方向光 THREE.DirectionalLight

对于任意平行的平面,平行光照射的亮度都是相同的。

//创建光线
var directLight;
function initLight() {
    directLight = new THREE.DirectionalLight(0xffffff);
    /**
     * 方向光的位置和物体的位置共同决定该方向光照射该物体的方向,
     * 也就是说如果物体位置在原点(0,0,0)那么方向光位置在(-1,0,0)或者(-80,0,0)对该物体而言意义一样。
     */
    directLight.position.set(-1,0,0);
    directLight.intensity = 1.5;
    scene.add(directLight);
}

半球光 THREE.HemisphereLight

与环境光类似,但是这种光会从一种颜色渐变到另外一种颜色。

HemisphereLight(  skyColor, groundColor, intensity )
  • skyColor — 场景上方的光的颜色;
  • groundColor – 场景下方的光的颜色;
  • intensity – 光照强度。

光照阴影

有光就应该有阴影,然而在ThreeJS中能形成阴影的光源只有 THREE.DirectionalLightTHREE.SpotLight ;而相对的能表现阴影效果的材质只有 THREE.MeshLambertMaterialTHREE.MeshPhongMaterial

在场景中添加阴影效果,一般步骤如下:

  • 打开渲染器的阴影地图;
renderer.shadowMap.enabled = true;//打开渲染器的阴影地图
  • 使用支持阴影的光源,并设置相关参数;
shadowLight = new THREE.DirectionalLight(0xffffff, .9);
shadowLight.position.set(150,350,350);
shadowLight.castShadow = true;//开启光源投影


//定义可见域的投射阴影
shadowLight.shadow.camera.left = -400;
shadowLight.shadow.camera.right = 400;
shadowLight.shadow.camera.top = 400;
shadowLight.shadow.camera.bottom = -400;
shadowLight.shadow.camera.near = 1;
shadowLight.shadow.camera.far = 1000;


//定义阴影的分辨率;虽然分辨率越高越好,但是需要付出更加昂贵的代价维持高性能的表现
shadowLight.shadow.mapSize.width = 2048;
shadowLight.shadow.mapSize.height = 2048;
  • 对被照的物体启用阴影的产生;
cube.castShadow = true;//开启阴影产生
  • 对投射的物体启用接受阴影。
floor.receiveShadow = true; //接受阴影

相机相关(camera)

透视投影相机 THREE.PerspectiveCamera

/**
 * 构造函数:
 * fov表示可视角度;
 * aspect表示裁剪面宽高比;
 * near表示近端距离;
 * far表示远端距离;
 * 只有离相机的距离大于near值小于far值,且在相机的可视角度之内,才能被相机投影到。
 */
var camera = new THREE.PerspectiveCamera(fov, aspect, near, far);

WebGL ThreeJS学习总结三

正交投影相机 THREE.OrthographicCamera

/**
 * 构造函数:
 * left左侧面
 * right右侧面
 * top上侧面
 * bottom下侧面
 * near近侧面
 * far远侧面
 * 这六个侧面所围成的内部区域就是相机投影的可视区域
 * @type {THREE}
 */
var camera = new THREE.OrthographicCamera( left, right, top, bottom, near, far );

WebGL ThreeJS学习总结三

动画相关(animation)

混合动画播放器 THREE.AnimationMixer

场景中特定物体的动画播放器,如果场景中的多个物体的动画是相互独立的,则每个单独动画都可以使用单独的AnimationMixer对象来处理。

其它(other)

轨道视角控制器 THREE.OrbitControls

顾名思义以该控制器的控制点为原点,相机围绕该控制点做类似卫星轨道的运动且相机焦点始终是该控制器的控制点。

因此有两点需要注意的地方:

轨道很小

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

The Definitive Guide to MongoDB

The Definitive Guide to MongoDB

Peter Membrey、Wouter Thielen / Apress / 2010-08-26 / USD 44.99

MongoDB, a cross-platform NoSQL database, is the fastest-growing new database in the world. MongoDB provides a rich document orientated structure with dynamic queries that you’ll recognize from RDMBS ......一起来看看 《The Definitive Guide to MongoDB》 这本书的介绍吧!

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器