Three.js学习之旅--相机适配与dat.gui库

canvas画布动态变化

js 复制代码
// canvas画布动态变化
// 简体页面窗口变化
// 画布变化 需要更新相机和渲染参数
window.onresize = function () {
    //更改画布大小 
    renderer.setSize(window.innerWidth,window.innerHeight);
    //摄像机视锥体长宽比
    camera.aspect = window.innerWidth / window.innerHeight;
    //更新摄像机投影矩阵。在任何参数被改变以后必须被调用。
    camera.updateProjectionMatrix();
}

阵列立方体

沿x、y、z轴分布排列,可以改变相机的fov参数观察,fov越大视野越大

js 复制代码
// 循环创建阵列物体
for (let i = 0; i < 10; i++) {
    for (let j = 0; j < 10; j++) {
        for(let k=0;k<10;k++){
            // 创建物体-网格模型
            const mesh = new THREE.Mesh(geometry, meterial);
            // 设置物体的位置
            mesh.position.set(i*10, j*10, k*10);
            // 将物体添加到场景中
            scene.add(mesh);
        }
    }
}

高光网格材质

js 复制代码
// 创建球形几何体
const geometry = new THREE.SphereGeometry( 30, 32, 16 );
// 高光网格材质(受光照影响、镜面反射)
const meterial = new THREE.MeshPhongMaterial({
    color: 0x0000FF,
    shininess:20, //亮度,默认20
    specular:0xFFFFFF, //反射光颜色
})
// 创建物体-网格模型
const mesh = new THREE.Mesh(geometry, meterial);

MeshPhongMaterial:镜面反射 类似与阳光照射到镜子
MeshLambertMaterial:漫反射 类似于阳光照射到白纸上,不会感到刺眼

添加dat.gui.js

dat.gui.js可以快速创建控制三维场景的UI交互界面,three.js已内置,无需下载

js 复制代码
// 添加dat.gui.js
import { GUI } from 'three/addons/libs/lil-gui.module.min.js'

gui改变模型位置

.add(obj,'xx',value1,value2)添加改变的对象属性,value1、value2为可选范围

js 复制代码
// gui改变模型位置
gui.add(mesh.position,'x',0,100);
gui.add(mesh.position,'y',0,100);
gui.add(mesh.position,'z',0,100);

name方法为属性命名

js 复制代码
// 为属性命名
gui.add(mesh.position,'x',0,100).name('x轴');
gui.add(mesh.position,'y',0,100).name('y轴');
gui.add(mesh.position,'z',0,100).name('z轴');

step方法为模型添加改变步长

js 复制代码
// step方法为模型添加改变步长  上下箭头增减时 每次调整的大小
gui.add(rotate,'x',0,1).name('沿x轴旋转速度').step(0.01);
gui.add(rotate,'y',0,1).name('沿y轴旋转速度').step(0.01);

addColor添加颜色

js 复制代码
const colorObj = {
    color:0xffffff
}
gui.addColor(colorObj,'color').onChange(value=>{
    // console.log(value)
    mesh.material.color.set(value);
})

下拉

js 复制代码
// 下拉菜单 数组或对象
gui.add(mesh.position,'x',[0,50,100]).name('x轴下拉');
gui.add(mesh.position,'y',{
    左:0,
    中:50,
    右:100
}).name('y轴下拉');

单选

js 复制代码
// 是否旋转
const rotate = {
    bool:true
}
gui.add(rotate,'bool').name('是否旋转');

addFolder 添加分组

js 复制代码
const gui = new GUI();
// 创建文件夹
const positionFolder = gui.addFolder('位置');
//子文件夹添加控制属性
positionFolder.add(mesh.position,'x',0,100).name('x轴');
positionFolder.add(mesh.position,'y',0,100).name('y轴');
positionFolder.add(mesh.position,'z',0,100).name('z轴');

效果展示:

完整代码

js 复制代码
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Three.js学习之旅-gui</title>
    <script type="importmap">
        {
         "imports":{
             "three":"./node_modules/three/build/three.module.js",
             "three/addons/":"./node_modules/three/examples/jsm/"
         }
        }
     </script>
</head>

<body>
    <style>
        * {
            margin: 0;
            padding: 0;
        }
    </style>
    <script type="module">
        import * as THREE from 'three';
        // 引入轨道控制器
        import { OrbitControls } from 'three/addons/controls/OrbitControls.js'
        // 添加dat.gui.js
        import { GUI } from 'three/addons/libs/lil-gui.module.min.js'

        // 创建场景
        const scene = new THREE.Scene();
        // 创建长方形几何体
        const geometry = new THREE.BoxGeometry(20, 20, 20); //长 宽 高
        // 创建物体材质-基础网格材质(不受光照影响)
        // const material = new THREE.MeshBasicMaterial({
        //     color: 0x0000FF
        // });
        //漫反射材质(受光照影响)
        const material = new THREE.MeshLambertMaterial({
            color: 0x0000FF
        });
        // 创建物体-网格模型
        const mesh = new THREE.Mesh(geometry, material);
        // 设置物体的位置
        mesh.position.set(0, 0, 0);
        // 将物体添加到场景中
        scene.add(mesh);


        // 定义canvas画布
        const width = window.innerWidth;
        const height = window.innerHeight;


        // 创建相机(透视投影相机)
        //PerspectiveCamera(fov, aspect, near, far)
        const camera = new THREE.PerspectiveCamera(30, width / height, 0.1, 1000); // 定义相机视距大小
        // 设置相机位置
        camera.position.set(200, 200, 200);
        // 设置相机观察目标点
        camera.lookAt(0, 0, 0);
        // 或者直接看物体
        camera.lookAt(mesh.position);


        // 添加辅助观察坐标系
        // 红色代表 X 轴. 绿色代表 Y 轴. 蓝色代表 Z 轴 -- R G B
        // AxesHelper( size : Number ) size -- (可选的) 表示代表轴的线段长度. 默认为 1.
        const axesHelper = new THREE.AxesHelper(100);
        scene.add(axesHelper);

        //创建光源
        // 环境光
        const light = new THREE.AmbientLight(0xffffff);
        scene.add(light);

        // 平行光
        const directionalLight = new THREE.DirectionalLight(0xffffff, 2);
        // 设置光源位置
        directionalLight.position.set(80, 40, 60);
        // 方向光指向对象网格模型mesh,可以不设置,默认的位置是0,0,0
        directionalLight.target = mesh;
        scene.add(directionalLight);

        // 创建渲染器
        const renderer = new THREE.WebGLRenderer();
        // 设置渲染画布大小
        renderer.setSize(width, height);
        // 渲染场景、相机
        renderer.render(scene, camera);
        // 将渲染画布插入到body中
        document.body.appendChild(renderer.domElement); //renderer.domElement为渲染画布元素


        // 添加轨道控制器
        const controls = new OrbitControls(camera, renderer.domElement);
        // 监听控制器事件
        controls.addEventListener('change', () => {
            // 执行渲染操作
            renderer.render(scene, camera)
        })


        // 旋转物体
        const rotate = {
            x:0.01,
            y:0.01,
            bool:true
        }
        function render() {
            // 每次执行时render()函数时,重新渲染
            renderer.render(scene, camera);
            // 物体沿x轴旋转
            if(rotate.bool){
                mesh.rotateX(rotate.x);
                mesh.rotateY(rotate.y);
            }
            requestAnimationFrame(render); //下一帧执行函数render
        }
        render()


        // 创建gui对象
        const gui = new GUI();
        // 创建文件夹
        const positionFolder = gui.addFolder('位置');
        const rotateFolder = gui.addFolder('旋转');
        const colorFolder = gui.addFolder('颜色');
        
        // gui改变模型位置 为属性命名
        positionFolder.add(mesh.position,'x',0,100).name('x轴');
        positionFolder.add(mesh.position,'y',0,100).name('y轴');
        positionFolder.add(mesh.position,'z',0,100).name('z轴');

        // 下拉菜单 数组或对象
        positionFolder.add(mesh.position,'x',[0,50,100]).name('x轴下拉');
        positionFolder.add(mesh.position,'y',{
           左:0,
           中:50,
           右:100
        }).name('y轴下拉');



        // step方法为模型添加改变步长  上下箭头增减时 每次调整的大小
        rotateFolder.add(rotate,'x',0,1).name('沿x轴旋转速度').step(0.01);
        rotateFolder.add(rotate,'y',0,1).name('沿y轴旋转速度').step(0.01);

        // 单选
        rotateFolder.add(rotate,'bool').name('是否旋转');


        // addColor添加颜色
        const colorObj = {
            color:0xffffff
        }
        colorFolder.addColor(colorObj,'color').onChange(value=>{
            // console.log(value)
            mesh.material.color.set(value);
        })
    </script>
</body>

</html>
相关推荐
小白小白从不日白2 分钟前
react hooks--useReducer
前端·javascript·react.js
下雪天的夏风14 分钟前
TS - tsconfig.json 和 tsconfig.node.json 的关系,如何在TS 中使用 JS 不报错
前端·javascript·typescript
diygwcom26 分钟前
electron-updater实现electron全量版本更新
前端·javascript·electron
Hello-Mr.Wang42 分钟前
vue3中开发引导页的方法
开发语言·前端·javascript
程序员凡尘1 小时前
完美解决 Array 方法 (map/filter/reduce) 不按预期工作 的正确解决方法,亲测有效!!!
前端·javascript·vue.js
B站计算机毕业设计超人1 小时前
计算机毕业设计Python+Flask微博情感分析 微博舆情预测 微博爬虫 微博大数据 舆情分析系统 大数据毕业设计 NLP文本分类 机器学习 深度学习 AI
爬虫·python·深度学习·算法·机器学习·自然语言处理·数据可视化
编程零零七5 小时前
Python数据分析工具(三):pymssql的用法
开发语言·前端·数据库·python·oracle·数据分析·pymssql
(⊙o⊙)~哦6 小时前
JavaScript substring() 方法
前端
无心使然云中漫步7 小时前
GIS OGC之WMTS地图服务,通过Capabilities XML描述文档,获取matrixIds,origin,计算resolutions
前端·javascript
Bug缔造者7 小时前
Element-ui el-table 全局表格排序
前端·javascript·vue.js