【ThreeJS基础教程-初识Threejs】1.2掌控我们的物体和模型

掌控我们的物体和模型

  • 学习ThreeJS的捷径
  • 引入帧数监控与调试时使用的GUI
  • 案例解析
    • 引入刷新率检测器stats和lil-gui
      • Stats
      • LIL.GUI (Dat.GUI)

学习ThreeJS的捷径

本段内容会写在0篇以外所有的,本人所编写的Threejs教程中

对,学习ThreeJS有捷径
当你有哪个函数不懂的时候,第一时间去翻一翻文档
当你有哪个效果不会做的时候,第一时间去翻一翻所有的案例,也许就能找到你想要的效果
最重要的一点,就是,绝对不要怕问问题,越怕找找别人问题,你的问题就会被拖的越久

如果你确定要走WebGL/ThreeJS的开发者路线的话,以下行为可以让你更快的学习ThreeJS

  1. 没事就把所有的文档翻一遍,哪怕看不懂,也要留个印象,至少要知道Threejs有什么
  2. 没事多看看案例效果,当你记忆的案例效果足够多时,下次再遇到相似问题时,你就有可能第一时间来找对应的案例,能更快解决你自己的问题
  3. 上述案例不只是官网的案例,郭隆邦技术博客,跃焱邵隼,暮志未晚等站点均有不少优质案例,记得一并收藏
    http://www.yanhuangxueyuan.com/ 郭隆邦技术博客
    https://www.wellyyss.cn/ 跃焱邵隼
    http://www.wjceo.com/ 暮志未晚
    这三个站点是我最常逛的站点,推荐各位有事没事逛一下,看看他们的案例和写法思路,绝对没坏处

引入帧数监控与调试时使用的GUI

DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Titletitle>
    <style>
        canvas{
            display: block;
        }
        body {
            margin: 0;
            overscroll-behavior: none;
        }
        #btns{
            position: absolute;
            top:10%;
            width: 500px;
            height: 100px;
            left: 50%;
            transform:translateX(-50%);
        }
    style>
head>
<body>
<div id="btns">div>



<script async src="https://unpkg.com/[email protected]/dist/es-module-shims.js">script>

<script type="importmap">
			{
				"imports": {
					"three": "../three.js-master/build/three.module.js"
				}
			}
		script>
<script type="module">
    import * as THREE from '../three.js-master/build/three.module.js';
    import {OrbitControls} from "../three.js-master/examples/jsm/controls/OrbitControls.js";
    import {GUI} from "../three.js-master/examples/jsm/libs/lil-gui.module.min.js"
    import Stats from "../three.js-master/examples/jsm/libs/stats.module.js"

    let scene,renderer,camera,orbitControls;

    let stats,gui;

    let mesh;

    function init(){
        scene = new THREE.Scene();
        renderer = new THREE.WebGLRenderer({
            alpha:true,
            antialias:true
        });
        renderer.setSize(window.innerWidth,window.innerHeight);
        document.body.appendChild(renderer.domElement);
        camera = new THREE.PerspectiveCamera(60,window.innerWidth/window.innerHeight,1,1000);
        camera.position.set(10,10,10);
        orbitControls = new OrbitControls(camera,renderer.domElement);
        let helper = new THREE.GridHelper(50,10);
        scene.add(helper);

        stats= new Stats();
        document.body.appendChild(stats.dom);
        gui = new GUI();
    }
    function addMesh(){
        let geometry = new THREE.BoxGeometry(1,1,1);
        let material = new THREE.MeshBasicMaterial({
            color:"#ff0000"
        });
        mesh = new THREE.Mesh(geometry,material);
        scene.add(mesh);
    }

    function addGUI() {
        gui.add(mesh.position,"x",-10,10).step(0.5).name("位置x");
        gui.add(mesh.position,"y",-10,10).step(0.5).name("位置y");
        gui.add(mesh.position,"z",-10,10).step(0.5).name("位置z");

        let params = {
            rx:0,
            ry:0,
            rz:0
        };

        gui.add(params,"rx",-Math.PI,Math.PI).step(Math.PI/180).name("旋转x").onChange((value)=>{
            mesh.rotation.x = params.rx;
        });
        gui.add(params,"ry",-Math.PI,Math.PI).step(Math.PI/180).name("旋转y").onChange((value)=>{
            mesh.rotation.y = params.ry;
        });
        gui.add(params,"rz",-Math.PI,Math.PI).step(Math.PI/180).name("旋转z").onChange((value)=>{
            mesh.rotation.z = params.rz;
        });

    }

    function render(){
        renderer.render(scene,camera);
        requestAnimationFrame(render);
        stats.update();
    }
    init();
    addMesh();
    addGUI();
    render();
script>
body>
html>

案例效果
【ThreeJS基础教程-初识Threejs】1.2掌控我们的物体和模型_第1张图片

当你运行案例时,你发现,左上角有了一个小窗口,并且显示着你的当前刷新率,笔者这里使用的是144hz的屏幕,所以显示的刷新率为144,常见刷新率为60,75,120,144等
刷新率会直接反馈给你你的项目运行是否卡顿,如果你的显示器常驻刷新率是60帧,当你加载了过于复杂的模型后,你的帧率降到了60以下,甚至低于30的时候,那么,这个模型在你的设备和同等级及以下水平的设备下运行,会降低用户的实际使用体验

一般来说,做WebGL项目要考虑最低的设备等级,你的用户群如果是全民,那么你在开发时,就应考虑【如何使最低配置的设备能流畅运行你的程序】,左上角的这个插件,就是一个很好的检测程序运行流畅度的插件

右上角多了一个比较大的窗口,你发现,拖动中间的蓝色小杆,让它左右移动,可以让中间的模型发生变化,比如位置x,可以让模型沿着x轴移动,旋转x可以让模型沿着x轴旋转等

其他功能均与上一个案例一致

案例解析

多数代码已经在上一篇解析完毕,本篇仅针对新出现的代码进行解析

引入刷新率检测器stats和lil-gui

【ThreeJS基础教程-初识Threejs】1.2掌控我们的物体和模型_第2张图片
文件位置如图所示,对应的ES5版本在examples/js/libs/下

    import {GUI} from "../three.js-master/examples/jsm/libs/lil-gui.module.min.js"
    import Stats from "../three.js-master/examples/jsm/libs/stats.module.js"

	let stats,gui;

	function init(){
		......
		stats= new Stats();
		document.body.appendChild( stats.dom );
		gui = new GUI();
	}
	...
	render(){
		......
		stats.update();
	}

按上述写法引入对应的这两个文件后,先全局创建对应的变量,然后在初始化阶段初始化它们即可

Stats

构造器:new Stats() 没啥说的,就是一个new,创建完记得把dom添加到你的html中,上述代码是添加到了body中 ,添加后,你的左上角就会出现上面效果图中的刷新率检测方块
函数:stats.update(); 因为这个东西要时刻检测帧率,所以需要放到requestAnimationFrame绑定的函数中,否则不会生效

左上角的方块有三种模式,使用鼠标点击方块即可切换,目前我们仅使用蓝色的即可

LIL.GUI (Dat.GUI)

构造器 new GUI() lil-gui,升级于Dat.GUI,如果想要找一套系统的使用教程,请搜索Dat.GUI,或者去lil-gui的github地址或官网,其中也有相关的文档和教程
lil-gui的官方网站 https://lil-gui.georgealways.com/
这个构造器相对来说就只new一下就ok了,右上角会直接出现一个黑色的小方框,但是,仅仅只new一个它,它什么也不会显示,会显示成这样
在这里插入图片描述

    function addGUI() {
        gui.add(mesh.position,"x",-10,10).step(0.5).name("位置x");
        gui.add(mesh.position,"y",-10,10).step(0.5).name("位置y");
        gui.add(mesh.position,"z",-10,10).step(0.5).name("位置z");

        let params = {
            rx:0,
            ry:0,
            rz:0
        };

        gui.add(params,"rx",-Math.PI,Math.PI).step(Math.PI/180).name("旋转x").onChange((value)=>{
            mesh.rotation.x = params.rx;
        });
        gui.add(params,"ry",-Math.PI,Math.PI).step(Math.PI/180).name("旋转y").onChange((value)=>{
            mesh.rotation.y = params.ry;
        });
        gui.add(params,"rz",-Math.PI,Math.PI).step(Math.PI/180).name("旋转z").onChange((value)=>{
            mesh.rotation.z = params.rz;
        });
    }

以上展示了两种,向GUI添加控制块的方法

方法1:直接操作物体的对应属性

gui.add(对象,属性名,属性值下限,属性值上限) 用于添加一个控制器
比如我这里,想要控制小方块的位置,那么:

我们的对象是:mesh.position ,positions一个THREE.Vector3对象,这里我们要拿到最小的对象
属性是:x,Vector3对象有三个基础属性,分别是x,y,z
属性值下限:默认为负无限大,但是我们做项目调试的话,尽量设置一个下限值和上限值
属性值上限:同上

接下来,我需要为它添加步长,拖动一下让物体移动多少距离
gui.add().step(0.5) 这样,我们在gui上拖动,每触发一次mousemove,方块会移动0.5个单位

英文的看不懂或者不会翻译怎么办?那我们添加一个中文的标签名
gui.add().name(“位置x”)

完整的写法下来就是
gui.add( mesh.position,“x”, -10, 10 ).step(0.5).name(“位置x”)

翻译下来为:
向GUI添加一组控制器,控制mesh(小方块)位置对象的x属性,使控制器可以将x这个属性值,修改为-10~10的数字,每一次操作会改变0.5的值,为控制块设定名称为:“位置x”

将x,y,z三个属性都添加了控制器之后,我们就可以使用GUI控制方块了

但是我们还有第二种写法

首先创建一个对象

	        let params = {
	            x:0,
	            y:0,
	            z:0
	        };

同样的方式,我们控制这个对象,而非直接控制模型的属性
gui.add( params,“x”, -10, 10 ).step(0.5).name(“位置x”)

这样我们并不能直接控制模型,我们还需要下一步操作

gui.add().onChange( function(value){} )

使用onChange函数,可以让我们的属性变的更实用

上面同样的段落,我们可以这样写

gui.add( params,"x", -10, 10 ).step(0.5).name("位置x").onChange( value=>{
	mesh.position.x = value;
} );

这样写的好处是,你可以用一个params控制多个属性,且逻辑上比较清晰

上面代码块中,关于mesh的旋转的控制,就是由gui控制param,进一步控制mesh.rotation来进行旋转的

ThreeJS中使用的旋转角度均为弧度制,代码中设置了下限为180度,在js中使用Math.PI来表示弧度制的180度,弧度制忘了的同学可以去搜一下做个基本复习

这样,添加旋转的那一部分代码就讲完了

你可能感兴趣的:(ThreeJS,WebGL,javascript,前端,html)