【ThreeJS Basics 09】Debug

news2025/3/9 7:04:54

文章目录

  • 简介
  • 从 dat.GUI 到 lil-gui
  • 例子
  • 安装 lil-gui 并实例化
  • 不同类型的调整
    • 改变位置
    • 针对非属性的调整
    • 复选框
    • 颜色
  • 功能/按钮
  • 调整几何形状
  • 文件夹
  • 调整 GUI
    • 宽度
    • 标题
    • 关闭文件夹
    • 隐藏
    • 按键切换
  • 结论


简介

每一个创意项目的一个基本方面是能够轻松调整。开发人员和参与项目的其他参与者(如设计师甚至客户)必须能够更改尽可能多的参数。

您必须考虑到这一点,以便他们找到完美的颜色、速度、数量等,获得最佳体验。您甚至可能会得到意想不到的很棒的结果。

首先,我们需要一个调试 UI。

虽然您可以使用 HTML / CSS / JS 创建自己的调试 UI,但已经有多个库:

  • dat.GUI
  • lil-gui
  • control-panel
  • ControlKit
  • Uil
  • Tweakpane
  • Guify
  • Oui

所有这些库都可以做我们想做的事,但我们将使用lil-gui,因为它很流行、维护良好、并且易于使用

从 dat.GUI 到 lil-gui

最初,Three.js 练习都是使用 dat.GUI

一段时间以来,这个库一直没有更新,NPM 在安装它时开始触发漏洞警告。这些漏洞已经修复,但替代方案已经开始出现,这就是 lil-gui 作为 dat.GUI 的替代品越来越受欢迎的原因。额外的好处是它甚至有更好的功能。

所有 Three.js 练习现在都使用 lil-gui

顺便说一下,GUI 代表图形用户界面。

例子

https://bruno-simon.com/#debug

安装 lil-gui 并实例化

npm i lil-gui

引入并使用

import GUI from 'lil-gui'

/**
 * Debug
 */
const gui = new GUI()

不同类型的调整

  • 范围— 针对具有最小值和最大值的数字
  • 颜色— 适用于各种格式的颜色
  • 文本— 用于简单文本
  • 复选框— 用于布尔值(true或false)
  • 选择— 从值列表中进行选择
  • 按钮——触发功能

改变位置

const mesh = new THREE.Mesh(geometry, material)
scene.add(mesh)

gui.add(mesh.position, 'y')

we

或者写一个范围,这样 ui 就会变成一个滑杆

gui.add(mesh.position, 'y', - 3, 3, 0.01)

在这里插入图片描述

也可以使用链式调用

gui
    .add(mesh.position, 'y')
    .min(- 3)
    .max(3)
    .step(0.01)

针对非属性的调整

这里需要注意的一点是 lil-gui 只能修改属性。如果你想更新变量,则不能:

let myVariable = 1337
gui.add(myVariable, '???')

但是您可以使用一些技巧来实现这一点,例如创建一个对象,其目的是保存 lil-gui 在该对象上使用的属性:

const myObject = {
    myVariable: 1337
}
gui.add(myObject, 'myVariable')

复选框

lil-gui 会自动检测你想要调整的属性类型,并使用相应的接口。Object3D visible 的属性就是一个很好的例子。它是一个布尔值,如果,false 则会隐藏对象:

gui.add(mesh, 'visible')

颜色

处理颜色有点麻烦。让我们尝试修改 color 的属性 material

需要通过回调函数里的 value 来设置值, GUI 上的 hex 并不是最终的值

你最终得到了错误的颜色:

这是因为 Three.js 应用了一些颜色管理来优化渲染。因此,调整中显示的颜色值与内部使用的值不同。

我们现在不讨论色彩管理, 有两种方法可以解决这个问题。

gui.addColor(material, 'color')

需要通过回调函数来覆盖掉 ui 上显示的值

debugObject.color = '#3a6ea6'

const geometry = new THREE.BoxGeometry(1, 1, 1, 2, 2, 2)
const material = new THREE.MeshBasicMaterial({ color: debugObject.color, wireframe: false })

cubeTweaks
    .addColor(debugObject, 'color')
    .onChange(() =>
    {
        material.color.set(debugObject.color)
    })

功能/按钮

有时,我们只想按需触发指令。现在,当我们点击调试 UI 中的某个位置时,我们希望让立方体执行一点旋转动画。

我们可以通过向包含函数的 tweak 发送一个属性来实现这一点。不幸的是,这意味着我们不能让一个函数像这样独立存在,然后将其发送给 lil-gui

const myFunction = () => {
    console.log('do something')
}
gui.add(myFunction, '???')

但是我们可以为我们之前创建的对象添加一个spin属性debugObject,并将 GSAP 动画集成到其中:

debugObject.spin = () =>
{
    gsap.to(mesh.rotation, { duration: 1, y: mesh.rotation.y + Math.PI * 2 })
}

最后,我们可以将调整添加到 debugObject.spin

debugObject.spin = () =>
{
    // ...
}
gui.add(debugObject, 'spin')

在这里插入图片描述

调整几何形状

gui
    .add(debugObject, 'subdivision')
    .min(1)
    .max(20)
    .step(1)
    .onChange(() =>
    {
        console.log('subdivision changed')
    })

对于 CPU 来说,构建几何图形可能是一个相当漫长的过程。现在,我们正在监听更改事件,如果用户过多地拖放范围调整,则可能会多次触发该事件。

onChange我们不会使用 ,而是使用onFinishChange,它仅当我们停止调整值时才会触发:

gui
    .add(debugObject, 'subdivision')
    .min(1)
    .max(20)
    .step(1)
    .onFinishChange(() =>
    {
        console.log('subdivision finished changing')
    })

除此之外console.log(),我们还可以使用 构建一个新的几何体,并通过将其分配给其属性来debugObject.subdivision将其与 关联:meshgeometry

gui
    .add(debugObject, 'subdivision')
    .min(1)
    .max(20)
    .step(1)
    .onFinishChange(() =>
    {
        mesh.geometry = new THREE.BoxGeometry(
            1, 1, 1,
            debugObject.subdivision, debugObject.subdivision, debugObject.subdivision
        )
    })

就是这样,但我们犯了一个小错误。旧几何图形仍位于 GPU 内存中的某个位置,这可能会导致内存泄漏。

dispose()为了解决这个问题,我们可以在创建新的几何图形之前在旧几何图形上调用该方法:

gui
    .add(debugObject, 'subdivision')
    .min(1)
    .max(20)
    .step(1)
    .onFinishChange(() =>
    {
        mesh.geometry.dispose()
        mesh.geometry = new THREE.BoxGeometry(
            1, 1, 1,
            debugObject.subdivision, debugObject.subdivision, debugObject.subdivision
        )
    })

文件夹

假设我们有很多调整,调试 UI 开始变得拥挤。我们可以使用此addFolder()方法将它们分成文件夹。

要创建文件夹,请调用addFolder()并发送您想要的名称作为参数。请确保在调整之前执行此操作并将其保存为cubeTweaks:

const cubeTweaks = gui.addFolder('Awesome cube')

然后,不要使用gui来创建调整,而是使用cubeTweaks变量:

const cubeTweaks = gui.addFolder('Awesome cube')

cubeTweaks
    .add(mesh.position, 'y')
    // ...

cubeTweaks
    .add(mesh, 'visible')

cubeTweaks
    .add(material, 'wireframe')

cubeTweaks
    .addColor(material, 'color')
    // ...

// ...
cubeTweaks
    .add(debugObject, 'spin')

// ...
cubeTweaks
    .add(debugObject, 'subdivision')
    // ...

可以默认

const cubeTweaks = gui.addFolder('Awesome cube')
cubeTweaks.close()

调整 GUI

宽度

const gui = new GUI({
    width: 300
})

标题

const gui = new GUI({
    width: 300,
    title: 'Nice debug UI'
})

关闭文件夹

const gui = new GUI({
    width: 300,
    title: 'Nice debug UI',
    closeFolders: true
})

隐藏

const gui = new GUI({
    width: 300,
    title: 'Nice debug UI',
    closeFolders: false,
})
// gui.close()
gui.hide()

按键切换

window.addEventListener('keydown', (event) =>
{
    if(event.key == 'h')
        gui.show(gui._hidden)
})

结论

随着你的 项目的进行,来添加各种各样的 gui 参数

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2312013.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【笔记】STM32L4系列使用RT-Thread Studio电源管理组件(PM框架)实现低功耗

硬件平台:STM32L431RCT6 RT-Thread版本:4.1.0 目录 一.新建工程 二.配置工程 ​编辑 三.移植pm驱动 四.配置cubeMX 五.修改驱动文件,干掉报错 六.增加用户低功耗逻辑 1.设置唤醒方式 2.设置睡眠时以及唤醒后动作 ​编辑 3.增加测试命…

类和对象:

1. 类的定义: 1. 类定义格式: 对于我们的类的话,我们是把类看成一个整体,我们的函数里面没有找到我们的成员变量,我们就在我们的类里面找。 我们看我们的第二点: 我们的类里面,我们通常会对…

【十三】Golang 通道

💢欢迎来到张胤尘的开源技术站 💥开源如江河,汇聚众志成。代码似星辰,照亮行征程。开源精神长,传承永不忘。携手共前行,未来更辉煌💥 文章目录 通道通道声明初始化缓冲机制无缓冲通道代码示例 带…

软考中级_【软件设计师】知识点之【面向对象】

简介: 软件设计师考试中,面向对象模块为核心考点,涵盖类与对象、继承、封装、多态等基础概念,重点考查UML建模(类图/时序图/用例图)、设计模式(如工厂、单例模式)及SOLID设计原则。要…

分布式锁—7.Curator的分布式锁一

大纲 1.Curator的可重入锁的源码 2.Curator的非可重入锁的源码 3.Curator的可重入读写锁的源码 4.Curator的MultiLock源码 5.Curator的Semaphore源码 1.Curator的可重入锁的源码 (1)InterProcessMutex获取分布式锁 (2)InterProcessMutex的初始化 (3)InterProcessMutex.…

《UE5_C++多人TPS完整教程》学习笔记35 ——《P36 武器类(Weapon Class)》

本文为B站系列教学视频 《UE5_C多人TPS完整教程》 —— 《P36 武器类(Weapon Class)》 的学习笔记,该系列教学视频为计算机工程师、程序员、游戏开发者、作家(Engineer, Programmer, Game Developer, Author) Stephen …

[密码学实战]Java实现国密TLSv1.3单向认证

一、代码运行结果 1.1 运行环境 1.2 运行结果 1.3 项目架构 二、TLS 协议基础与国密背景 2.1 TLS 协议的核心作用 TLS(Transport Layer Security) 是保障网络通信安全的加密协议,位于 TCP/IP 协议栈的应用层和传输层之间,提供: • 数据机密性:通过对称加密算法(如 AE…

最小栈 _ _

一:题目 二:思路 解释:一个栈名为st,其用来正常的出入栈,一个栈名为minst,其的栈顶元素一定是最小的元素 入栈:第一个元素,两个栈一起入,后面再入栈,只有入栈…

HTTPS加密原理详解

目录 HTTPS是什么 加密是什么 HTTPS的工作流程 1.使用对称加密 2.引入非对称加密 3.引入证书机制 客户端验证证书真伪的过程 签名的加密流程 整体工作流程 总结 HTTPS是什么 HTTPS协议也是一个应用程协议,是在HTTP的基础上加入了一个加密层,由…

黑金风格人像静物户外旅拍Lr调色教程,手机滤镜PS+Lightroom预设下载!

调色教程 针对人像、静物以及户外旅拍照片,运用 Lightroom 软件进行风格化调色工作。旨在通过软件中的多种工具,如基本参数调整、HSL(色相、饱和度、明亮度)调整、曲线工具等改变照片原本的色彩、明度、对比度等属性,将…

安装pyqt6出现的问题

安装PyQt6报错: PermissionError: [WinError 32] 另一个程序正在使用此文件,进程无法访问。: C:\\Users\\xyj19\\AppData\\Local\\Temp\\tmp3xfmekh7 [end of output] note: This error originates from a subprocess, and is likely not a pr…

java调用c++

VScode 配置java 并且使用JNA调用c 动态库 安装 Java 开发环境 ​ 安装 JDK官网直接下载就好,推荐镜像下载 通过网盘分享的文件:jdk-8u144-windows-x64.exe​ 链接: https://pan.baidu.com/s/1Ov9bJkPNnOgcliBL-PSTFQ?pwdpg43 提取码: pg43 ​ 直接安…

gitlab+jenkins+harbor+k8s安装操作流程之Jenkins

准备环境 一台centos7系统 4C/8G/100G 如果是jenkins2.5以上版本需要centos8以上版本 JDK1.8编译安装(最新版本jdk需要18以上) MAVEN编译安装 GIT编译安装 JDK1.8步骤 tar -zxvf 解压 vim /etc/profile export JAVA_HOME/data/jdk1.8.0_111 export JRE_HOME$JAVA…

【机械视觉】C#+VisionPro联合编程———【三、加载CogToolBlock工具详解,以及实例】

【机械视觉】C#VisionPro联合编程———【三、加载CogToolBlock工具详解,以及实例】 在VisionPro中,CogToolBlock 是一种容器工具,可以将多个视觉工具(如CogBlob、CogPMAlign等)组合成一个可复用的流程。通过C#与Visi…

启动wsl里的Ubuntu24报错:当前计算机配置不支持 WSL2,HCS_E_HYPERV_NOT_INSTALLED

问题:启动wsl里的Ubuntu24报错 报错信息: 当前计算机配置不支持 WSL2。 请启用“虚拟机平台”可选组件,并确保在 BIOS 中启用虚拟化。 通过运行以下命令启用“虚拟机平台”: wsl.exe --install --no-distribution 有关信息,请访…

信息安全与网络安全的区别_信息安全与网络安全之差异探析

在当今数字化时代,信息安全与网络安全成为了人们关注的热点话题。尽管这两个概念经常被提及,但它们之间存在着明显的区别。本文旨在探讨信息安全与网络安全的定义、范畴及应对策略,以帮助读者更好地理解和应对相关挑战。 一、定义与范畴的差…

充电桩快速搭建springcloud(微服务)+前后端分离(vue),客户端实现微信小程序+ios+app使用uniapp(一处编写,处处编译)

充电桩管理系统是专为中小型充电桩运营商、企业和个人开发者设计的一套高效、灵活的管理平台。系统基于Spring Cloud微服务架构开发,采用模块化设计,支持单机部署与集群部署,能够根据业务需求动态扩展。系统前端使用uniapp框架,可…

设计AI芯片架构的入门 研究生入行数字芯片设计、验证的项目 opentitan

前言 这几年芯片设计行业在国内像坐过山车。时而高亢,时而低潮。最近又因为AI的热潮开始high起来。到底芯片行业的规律是如何? 我谈谈自己观点:芯片设计是“劳动密集型”行业。 “EDA和工具高度标准化和代工厂的工艺标准化之后,芯…

串口助手的C#编写以及有人串口服务器USR-DR301的使用

本文介绍C#编写串口程序的要点,串口服务器USR-DR301(RS232转TCP)的使用、以及调试过程中碰到的两个问题: 1). 调用串口报“连到系统上的设备没有发挥作用”. 2). “所有文本框都变成了透明”的异常处理 代码见:https://download.csdn.net/download/qq_34047402/9046713…

Android中AIDL和HIDL的区别

在Android中,AIDL(Android Interface Definition Language) 和 HIDL(HAL Interface Definition Language) 是两种用于定义跨进程通信接口的语言。AIDL 是 Android 系统最早支持的 IPC(进程间通信&#xff0…