当前位置:网站首页>Three. Introduction to js

Three. Introduction to js

2022-07-31 17:54:00 Programmers run forward

Threejs是一款WebGL三维引擎,在所有WebGL引擎中,Three.js是国内文资料最多、使用最广泛的三维引擎.

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>My first three.js app</title>
		<style>
			body {
     margin: 0; }
		</style>
	</head>
	<body>
		  <script src="http://www.yanhuangxueyuan.com/versions/threejsR92/build/three.js"></script>

		<script>
			const scene = new THREE.Scene();
			const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );

			const renderer = new THREE.WebGLRenderer();
			renderer.setSize( window.innerWidth, window.innerHeight );
			document.body.appendChild( renderer.domElement );

			const geometry = new THREE.BoxGeometry( 1, 1, 1 );
			const material = new THREE.MeshBasicMaterial( {
     color: 0x00ff00 } );
			const cube = new THREE.Mesh( geometry, material );
			scene.add( cube );

			camera.position.z = 5;

			function animate() {
    
				requestAnimationFrame( animate );

				cube.rotation.x += 0.01;
				cube.rotation.y += 0.01;

				renderer.render( scene, camera );
			};

			animate();
		</script>
	</body>
</html>

在这里插入图片描述
three.js中文文档

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title></title>
  <style>
    body {
    
      margin: 0;
      overflow: hidden;
      /* 隐藏body窗口区域滚动条 */
    }
  </style>
  <!--引入three.js三维引擎-->
  <script src="http://www.yanhuangxueyuan.com/versions/threejsR92/build/three.js"></script>
</head>
<body>
  <script>
    /** * 创建场景对象Scene */
    var scene = new THREE.Scene();
    /** * 创建网格模型 */
    var geometry = new THREE.BoxGeometry(100, 100, 100); //创建一个立方体几何对象Geometry
    var material = new THREE.MeshLambertMaterial({
    
      color: 0x0000ff
    }); //材质对象Material
    var mesh = new THREE.Mesh(geometry, material); //网格模型对象Mesh
    scene.add(mesh); //网格模型添加到场景中
    /** * 光源设置 */
    //点光源
    var point = new THREE.PointLight(0xffffff);
    point.position.set(400, 200, 300); //点光源位置
    scene.add(point); //点光源添加到场景中
    //环境光
    var ambient = new THREE.AmbientLight(0x444444);
    scene.add(ambient);
    /** * 相机设置 */
    var width = window.innerWidth; 
    var height = window.innerHeight; 
    var k = width / height; 
    var s = 200; 
    //创建相机对象
    var camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 1000);
    camera.position.set(200, 300, 200);
    camera.lookAt(scene.position);
    /** * 创建渲染器对象 */
    var renderer = new THREE.WebGLRenderer();
    renderer.setSize(width, height);//设置渲染区域尺寸
    renderer.setClearColor(0xb9d3ff, 1); //设置背景颜色
    document.body.appendChild(renderer.domElement); //body元素中插入canvas对象

    // 渲染函数
    function render() {
    
        renderer.render(scene,camera);//执行渲染操作
        mesh.rotateY(0.01);//每次绕y轴旋转0.01弧度
        requestAnimationFrame(render);//请求再次执行渲染函数render,渲染下一帧
    }
    render();

  </script>
<div class="" style="position:absolute;top:0px;left:0px;background: rgba(0, 0, 0, 0.5);padding:10px 20px;"><a href="http://www.yanhuangxueyuan.com/Three.js/" target="_blank" style="color:#fff;text-decoration: none;">The case corresponds to the e-book address</a></div>
</body>
</html>

three.js-master
└───build——srcThe result of packaging each code module in the directory
│───three.js——开发的时候.htmlfile to be importedthreejs引擎库,和引入jquery一样,Can assist browser debugging
│───three.min.js——three.jsThe compressed structure file is smaller in size,When the project can be deployed.html中引入.

└───docs——Three.js API文档文件
│───index.html——Open the file for offline viewingthreejs API文档

└───editor——Three.js的可视化编辑器,可以编辑3D场景
│───index.html——打开应用程序

└───docs——Three.js API文档文件
│───index.html——Open the file for offline viewingthreejs API文档

└───examples——里面有大量的threejs案例,Usually, you can find a certain globally by editing the codeAPI、method or property to locate a case

└───src——Three.jsThe various modules of the engine,It can be deeply understood by reading the source codethreejs引擎
│───index.html——Open the file for offline viewingthreejs API文档

└───utils——一些辅助工具
│───\utils\exporters\blender——blender导出threejs文件的插件

<!--httpAbsolute address remote loading-->
<script src="http://www.yanhuangxueyuan.com/3D/example/three.js"></script>
<!-- 压缩版本 -->
<script src="http://www.yanhuangxueyuan.com/3D/example/three.min.js"></script>

Nodejs本地静态服务器
使用NodejsSetting up a local static server is easy,The first is that you have to first BaiduNodejsInstallation related articles,Install it on your computer firstNodejs,熟悉下NPM的使用,然后使用npm执行npm install -g live-server安装live-server模块,If you want to pass the installed oklive-serverThe module starts a static server,打开命令行,进入threejsThe file directory where the case is located,然后执行live-server命令就可以.

通过浏览器访问http://localhost:8080或http://127.0.0.1:8080地址,找到threejs案例的.htmlThe file can be directly opened to see the rendering effect of the 3D scene.

几何体Geometry

//创建一个立方体几何对象Geometry
var geometry = new THREE.BoxGeometry(100, 100, 100);

代码var box=new THREE.BoxGeometry(100,100,100);通过构造函数THREE.BoxGeometry()创建了一个长宽高都是100的立方体,通过构造函数名字BoxGeometry也能猜出这个构造函数的意义,利用new关键字操作构造函数可以创建一个对象, 这都是Javascript语言的基本知识,至于THREE.BoxGeometry()构造函数具体是什么可以不用关心, 就像你使用前端使用JQuery库一样查找官方文档就可以,你可以把代码THREE.BoxGeometry(100,100,100)中的第一个参数更改为为50,刷新浏览器查看数据更改后长方体的效果图,可以看到已经不是长宽高一样的立方体, 而是普通的长方体.

你也可以用下面一段代码代替上面的长方体代码,你会发现会渲染出来一个球体效果.

//创建一个球体几何对象
var geometry = new THREE.SphereGeometry(60, 40, 40);

Title materialMaterial

代码var material=new THREE.MeshLambertMaterial({color:0x0000ff});通过构造函数THREE.MeshLambertMaterial()创建了一个可以用于立方体的材质对象, 构造函数的参数是一个对象,对象包含了颜色、透明度等属性,本案例中只定义了颜色color,颜色属性值0x0000ff表示蓝色,可以把颜色值改为0x00ff00,可以看到是绿色的立方体效果, 这里使用的颜色值表示方法是16进制RGB三原色模型.Used rendering software、You should know if you have designed web pages or studied graphicsRGB三原色模型,这里就不再详述.

Title light sourceLight

代码var point=new THREE.PointLight(0xffffff);通过构造函数THREE.PointLight()创建了一个点光源对象,参数0xffffff定义的是光照强度, 你可以尝试把参数更改为为0x444444,刷新浏览器你会看到立方体的表面颜色变暗,这很好理解,实际生活中灯光强度变低了,周围的景物自然暗淡,three.js引擎对WebGL光照模型算法都进行了封装,不需要你了解计算机图形学, 可以直接使用调用three.js光源相关API直接创建一个光源对象,就像你使用普通的三维建模渲染软件一样,只是这里多了一个Javascript编程语言而已.

Title cameraCamera

代码var camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 1000);通过构造函数THREE.OrthographicCamera()创建了一个正射投影相机对象, 什么是“正射投影”,什么是“相机对象”,每个人的基础不一样,或许你不太理解,或许你非常理解,如果不清楚还是那句话,刚一开始不用深究,改个参数测试一下看看视觉效果你就会有一定的感性认识. 比如把该构造函数参数中用到的参数s,也就是代码var s = 200;中定义的一个系数,可以把200更改为300,你会发现立方体显示效果变小,这很好理解,相机构造函数的的前四个参数定义的是拍照窗口大小, 就像平时拍照一样,取景范围为大,被拍的人相对背景自然变小了.camera.position.set(200, 300, 200);和camera.lookAt(scene.position);定义的是相机的位置和拍照方向,可以更改camera.position.set(200,300,200);参数重新定义的相机位置,把第一个参数也就是x坐标从200更改为250, 你会发现立方的在屏幕上呈现的角度变了,这就像你生活中拍照人是同一个人,但是你拍照的位置角度不同,显示的效果肯定不同.这些具体的参数细节可以不用管, 至少你知道相机可以缩放显示三维场景、对三维场景的不同角度进行取景显示.

场景——相机——渲染器

Understand the case code of this lesson from the perspective of taking pictures in real life or using 3D rendering software,立方体网格模型和光照组成了一个虚拟的三维场景,相机对象就像你生活中使用的相机一样可以拍照,只不过一个是拍摄真实的景物,一个是拍摄虚拟的景物,拍摄一个物体的时候相机的位置和角度需要设置,虚拟的相机还需要设置投影方式,当你创建好一个三维场景,相机也设置好,就差一个动作“咔”,通过渲染器就可以执行拍照动作.
在这里插入图片描述
在这里插入图片描述

旋转动画、requestAnimationFrame周期性渲染

周期性渲染
在1.1explained in the section,每执行一次渲染器对象WebGLRenderer的渲染方法.render(),浏览器就会渲染出一帧图像并显示在Web页面上,这就是说你按照一定的周期不停地调用渲染方法.render()就可以不停地生成新的图像覆盖原来的图像.这也就是说只要一边旋转立方体,一边执行渲染方法.render()重新渲染,就可以实现立方体的旋转效果.

In order to achieve periodic rendering can be through the browser global objectwindow对象的一个方法setInterval(),可以通过window对象调用该方法window.setInterval(),It can also be called directly as a functionsetInterval().

setInterval()is a periodic function,like a timer,每隔多少毫秒msExecute a function once.
setInterval()is a periodic function,like a timer,每隔多少毫秒msExecute a function once.

// 间隔20ms周期性调用函数fun
setInterval("render()",20)

In order to achieve the cube rotation animation effect,Use the code below directly instead1.1section coderenderer.render(scene,camera);即可.

// 渲染函数
function render() {
    
    renderer.render(scene,camera);//执行渲染操作
    mesh.rotateY(0.01);//每次绕y轴旋转0.01弧度
}
//间隔20ms周期性调用函数fun,20ms也就是刷新频率是50FPS(1s/20ms),每秒渲染50次
setInterval("render()",20);

上面代码定义了一个渲染函数render(),函数中定义了三个语句,通过setInterval(“render()”,20);可以实现m每间隔20毫秒调用一次函数render(),每次调用渲染函数的时候,执行renderer.render(scene,camera);渲染出一帧图像,执行mesh.rotateY(0.01);语句使立方体网格模型绕y轴旋转0.01弧度.

渲染频率
调用渲染方法.render()进行渲染的渲染频率不能太低,比如执行setInterval(“render()”,200);间隔200毫秒调用渲染函数渲染一次,相当于每秒渲染5次,你会感觉到比较卡顿.渲染频率除了不能太低,也不能太高,太高的话计算机的硬件资源跟不上,函数setInterval()The set rendering method may not be able to be realized normally.一般调用渲染方法.render()进行渲染的渲染频率控制在每秒30~60次,人的视觉效果都很正常,也可以兼顾渲染性能.

//设置调用render函数的周期为200ms,刷新频率相当于5你能明显的感受到卡顿
setInterval("render()",200);
函数requestAnimationFrame()

前面讲解threejs动画效果,使用了setInterval()函数,实际开发中,为了更好的利用浏览器渲染,可以使用函数requestAnimationFrame()代替setInterval()函数,requestAnimationFrame()和setInterval()一样都是浏览器window对象的方法.

requestAnimationFrame()参数是将要被调用函数的函数名,requestAnimationFrame()调用一个函数不是立即调用而是向浏览器发起一个执行某函数的请求, 什么时候会执行由浏览器决定,一般默认保持60FPS的频率,大约每16.7ms调用一次requestAnimationFrame()方法指定的函数,60FPS是理想的情况下,如果渲染的场景比较复杂或者说硬件性能有限可能会低于这个频率.可以查看文章《requestAnimationFrame()》了解更多requestAnimationFrame()函数的知识.

function render() {
    
        renderer.render(scene,camera);//执行渲染操作
        mesh.rotateY(0.01);//每次绕y轴旋转0.01弧度
        requestAnimationFrame(render);//请求再次执行渲染函数render
    }
render();

均匀旋转
在实际执行程序的时候,可能requestAnimationFrame(render)请求的函数并不一定能按照理想的60FPS频率执行,两次执行渲染函数的时间间隔也不一定相同,如果执行旋转命令的rotateY的时间间隔不同,旋转运动就不均匀,为了解决这个问题需要记录两次执行绘制函数的时间间隔.

Use the following render function to replace the original render function,rotateY()的参数是0.001t,也意味着两次调用渲染函数执行渲染操作的间隔t毫秒时间内,立方体旋转了0.001t弧度,很显然立方体的角速度是0.001弧度每毫秒(0.0001 rad/ms = 1 rad/s = 180度/s).CPU和GPU执行一条指令时间是纳秒ns级,相比毫秒ms低了6个数量级,所以一般不用考虑渲染函数中几个计时语句占用的时间,除非你编写的是要精确到纳秒ns的级别的标准时钟程序.

let T0 = new Date();//上次时间
function render() {
    
        let T1 = new Date();//本次时间
        let t = T1-T0;//时间差
        T0 = T1;//把本次时间赋值给上次时间
        requestAnimationFrame(render);
        renderer.render(scene,camera);//执行渲染操作
        mesh.rotateY(0.001*t);//旋转角速度0.001弧度每毫秒
    }
render();

鼠标操作三维场景
In order to use the mouse to manipulate the 3D scene,可以借助three.jsOne of many controlsOrbitControls.js,可以在下载的three.js-master文件中找到(three.js-master\examples\js\controls). Then and importthree.jsThe files are still therehtml文件中引入控件OrbitControls.js.The purpose of this lesson is not to explain in depthOrbitControls.js,The main purpose is to show you on the one handthreejs的功能,On the other hand, the mouse is often rotated during the learning process of the later courses、Scale the model for code debugging.

代码实现
OrbitControls.js控件支持鼠标左中右键操作和键盘方向键操作,具体代码如下,使用下面的代码替换1.1节中renderer.render(scene,camera);即可.

function render() {
    
  renderer.render(scene,camera);//执行渲染操作
}
render();
var controls = new THREE.OrbitControls(camera,renderer.domElement);//创建控件对象
controls.addEventListener('change', render);//监听鼠标、键盘事件

OrbitControls.js控件提供了一个构造函数THREE.OrbitControls(),把一个相机对象作为参数的时候,执行代码new THREE.OrbitControls(camera,renderer.domElement),浏览器会自动检测鼠标键盘的变化, 并根据鼠标和键盘的变化更新相机对象的参数,比如你拖动鼠标左键,浏览器会检测到鼠标事件,把鼠标平移的距离按照一定算法转化为相机的的旋转角度,你可以联系生活中相机拍照,即使景物没有变化,你的相机拍摄角度发生了变化,自然渲染器渲染出的结果就变化了,通过定义监听事件controls.addEventListener(‘change’, render),如果你连续操作鼠标,相机的参数不停的变化,同时会不停的调用渲染函数render()进行渲染,这样threejs就会使用相机新的位置或角度数据进行渲染.

执行构造函数THREE.OrbitControls()浏览器会同时干两件事,一是给浏览器定义了一个鼠标、键盘事件,自动检测鼠标键盘的变化,如果变化了就会自动更新相机的数据, 执行该构造函数同时会返回一个对象,可以给该对象添加一个监听事件,只要鼠标或键盘发生了变化,就会触发渲染函数. About the listener functionaddEventListenerThe introduction can follow the article《HTML5事件》.

场景操作
缩放:滚动—鼠标中键
旋转:拖动—鼠标左键
平移:拖动—鼠标右键
requestAnimationFrame()使用情况
如果threejs代码中通过requestAnimationFrame()实现渲染器渲染方法render()的周期性调用,当通过OrbitControls操作改变相机状态的时候,没必要在通过controls.addEventListener(‘change’, render)监听鼠标事件调用渲染函数,因为requestAnimationFrame()就会不停的调用渲染函数.

function render() {
    
  renderer.render(scene,camera);//执行渲染操作
  // mesh.rotateY(0.01);//每次绕y轴旋转0.01弧度
  requestAnimationFrame(render);//请求再次执行渲染函数render
}
render();
var controls = new THREE.OrbitControls(camera,renderer.domElement);//创建控件对象
// 已经通过requestAnimationFrame(render);周期性执行render函数,没必要再通过监听鼠标事件执行render函数
// controls.addEventListener('change', render)

注意开发中不要同时使用requestAnimationFrame()或controls.addEventListener(‘change’, render)调用同一个函数,这样会冲突.

原网站

版权声明
本文为[Programmers run forward]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/212/202207311739452079.html