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>
相关推荐
NoneCoder1 分钟前
CSS系列(26)-- 动画性能优化详解
前端·css·性能优化
滚雪球~2 分钟前
@vue/cli启动异常:ENOENT: no such file or directory, scandir
前端·javascript·vue.js
GDAL12 分钟前
vue3入门教程:ref函数
前端·vue.js·elementui
GISer_Jing20 分钟前
Vue3状态管理——Pinia
前端·javascript·vue.js
好开心3335 分钟前
axios的使用
开发语言·前端·javascript·前端框架·html
Domain-zhuo1 小时前
Git常用命令
前端·git·gitee·github·gitea·gitcode
菜根Sec1 小时前
XSS跨站脚本攻击漏洞练习
前端·xss
m0_748257181 小时前
Spring Boot FileUpLoad and Interceptor(文件上传和拦截器,Web入门知识)
前端·spring boot·后端
桃园码工2 小时前
15_HTML5 表单属性 --[HTML5 API 学习之旅]
前端·html5·表单属性
百万蹄蹄向前冲2 小时前
2024不一样的VUE3期末考查
前端·javascript·程序员