当前位置: 首页 > news >正文

Three.js渲染较大的模型之解决方案

文章目录

    • Three.js渲染较大的模型 解决方案
    • 视锥体剔除实例 和 遮挡剔除 实例
      • 视锥体剔除(Frustum Culling)实例
        • 原理概述
        • 代码示例
        • 解释
      • 遮挡剔除(Occlusion Culling)实例
        • 原理概述
        • 代码示例
        • 解释
    • three.js 模型压缩

Three.js渲染较大的模型 解决方案

一、模型优化方面

  1. 简化模型结构

    • 对于复杂的3D模型,可以使用专业的3D建模软件(如Blender、Maya等)来减少模型的面数和顶点数。例如,在不影响模型整体外观的前提下,将高细节的装饰部分进行简化,将复杂的曲线用更简单的几何形状近似。
    • 利用建模软件中的减面工具,这些工具可以根据设定的参数,自动减少模型的多边形数量。比如将一个具有数百万个面的高精度角色模型,通过合理的减面操作,降低到数十万面,同时保留主要的外形特征。
  2. 使用LOD(Level of Detail)技术

    • LOD是一种根据物体与摄像机的距离来切换模型细节程度的技术。在Three.js中,可以创建多个具有不同细节层次的模型版本。
    • 例如,对于一个大型的建筑模型,当摄像机距离建筑较远时,使用一个低细节版本的模型,它可能只有简单的几何形状和较少的纹理;当摄像机靠近建筑时,切换到高细节版本的模型,显示更多的细节,如门窗的细节、建筑表面的装饰纹理等。通过这种方式,可以有效地减少远处模型的渲染负担。
    • 可以使用THREE.LOD对象来实现。首先创建不同细节层次的模型,然后将它们添加到THREE.LOD对象中,并设置相应的距离范围。例如:
    const lod = new THREE.LOD();
    const lowDetailModel = new THREE.Mesh(lowDetailGeometry, lowDetailMaterial);
    const mediumDetailModel = new THREE.Mesh(mediumDetailGeometry, 
    mediumDetailMaterial);
    const highDetailModel = new THREE.Mesh(highDetailGeometry, highDetailMaterial);
    lod.addLevel(lowDetailModel, 200); // 当距离大于200时显示低细节模型
    lod.addLevel(mediumDetailModel, 100); // 当距离小于200大于100时显示中细节模型
    lod.addLevel(highDetailModel, 0);   // 当距离小于100时显示高细节模型
    scene.add(lod);
    
  3. 压缩纹理

    • 对于模型的纹理,如果纹理文件较大,可以使用图像编辑软件(如Photoshop)或专门的纹理压缩工具来减小纹理文件的大小。
    • 例如,将高分辨率的纹理(如4096x4096像素)转换为更合适的分辨率(如2048x2048像素),同时采用合适的纹理压缩格式,如DXT(DirectX Texture Compression)或ETC(Ericsson Texture Compression)格式,这些格式可以在保持一定纹理质量的同时显著减小文件大小。在Three.js中,加载纹理时可以指定压缩后的纹理文件路径。

二、渲染优化方面

  1. 视锥体剔除(Frustum Culling)

    • Three.js会自动进行视锥体剔除,它的原理是只渲染位于摄像机视锥体内的物体。但是对于复杂的场景和大型模型,确保正确设置模型的包围盒(Bounding Box或Bounding Sphere)可以提高视锥体剔除的效率。
    • 例如,对于一个由多个部分组成的大型机械模型,为每个可分离的部分设置准确的包围盒,这样当某个部分完全在视锥体外时,Three.js可以快速地跳过对该部分的渲染。在模型加载或初始化阶段,可以通过计算模型的最小包围盒或包围球来实现更精确的视锥体剔除。
  2. 遮挡剔除(Occlusion Culling)

    • 遮挡剔除是指不渲染被其他物体完全遮挡的物体。在Three.js中,可以使用一些插件或自定义算法来实现遮挡剔除。
    • 一种简单的方法是基于深度缓冲来实现近似的遮挡剔除。首先渲染场景的深度信息,然后在后续渲染过程中,对于那些深度值大于当前像素深度的物体部分,可以认为是被遮挡的,从而不进行渲染。不过这种方法有一定的局限性,对于复杂的透明物体等情况可能需要更复杂的算法。
  3. 使用实例化(Instancing)技术

    • 如果模型中有大量重复的元素,例如森林中的树木、城市中的路灯等,使用实例化可以显著提高渲染效率。
    • 在Three.js中,可以使用THREE.InstancedMesh来实现实例化渲染。它允许使用一个单一的几何体和材质来渲染多个相同的物体实例。例如,要渲染一片森林,可以先创建一个树的几何体和材质,然后使用THREE.InstancedMesh来创建大量的树实例,通过设置每个实例的位置、旋转和缩放等变换矩阵,就可以高效地渲染整个森林。代码示例如下:
    const treeGeometry = new THREE.BoxGeometry(1, 2, 1);
    const treeMaterial = new THREE.MeshLambertMaterial({ color: 0x00ff00 });
    const treeInstances = new THREE.InstancedMesh(treeGeometry, treeMaterial,1000); // 1000个树实例
    for (let i = 0; i < 1000; i++) {const matrix = new THREE.Matrix4();matrix.setPosition(new THREE.Vector3(Math.random() * 100 - 50, 0, Math.random() * 100 - 50));matrix.setRotationFromAxisAngle(new THREE.Vector3(0, 1, 0),Math.random() * 2 * Math.PI);matrix.scale(new THREE.Vector3(Math.random() * 0.5 + 0.5, Math.random() * 0.5 + 0.5, Math.random() * 0.5 + 0.5));treeInstances.setMatrixAt(i, matrix);
    }
    scene.add(treeInstances);
    
  4. 优化渲染循环(Render Loop)

    • 在渲染循环中,避免不必要的计算和渲染操作。例如,只有当模型的属性(如位置、旋转、材质等)发生变化时,才重新计算和渲染相关部分。
    • 可以使用节流(Throttle)或防抖(Debounce)技术来控制渲染频率。如果模型的动画更新频率不需要非常高,可以使用节流函数来限制每秒的渲染次数。例如,使用lodash库中的throttle函数来控制渲染循环的执行频率:
    import throttle from 'lodash/throttle';
    function render() {renderer.render(scene, camera);
    }
    const throttledRender = throttle(render, 1000 / 30); // 限制每秒渲染30次
    function animate() {// 模型更新等操作throttledRender();requestAnimationFrame(animate);
    }
    animate();
    

视锥体剔除实例 和 遮挡剔除 实例

视锥体剔除(Frustum Culling)实例

原理概述

视锥体剔除是指只渲染位于摄像机视锥体内的物体,Three.js本身内置了对视锥体剔除的基本支持,但我们可以通过合理设置物体的包围盒(Bounding Box或Bounding Sphere)来优化这个过程,提高剔除效率。

代码示例
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><title>Frustum Culling Example</title><style>body {margin: 0;overflow: hidden;}</style><script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r134/three.min.js"></script>
</head><body><script>// 创建场景const scene = new THREE.Scene();// 创建摄像机const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);camera.position.z = 5;// 创建渲染器const renderer = new THREE.WebGLRenderer();renderer.setSize(window.innerWidth, window.innerHeight);document.body.appendChild(renderer.domElement);// 创建多个立方体(模拟多个物体)const cubeGeometry = new THREE.BoxGeometry(1, 1, 1);const cubeMaterial = new THREE.MeshBasicMaterial({ color: 0x00ff00 });const numCubes = 10;for (let i = 0; i < numCubes; i++) {const cube = new THREE.Mesh(cubeGeometry, cubeMaterial);cube.position.x = (Math.random() - 0.5) * 10;cube.position.y = (Math.random() - 0.5) * 10;cube.position.z = (Math.random() - 0.5) * 10;// 为每个立方体设置包围盒//(这里使用包围盒辅助对象可视化展示,实际应用中不需要可视化部分)const box = new THREE.Box3().setFromObject(cube);scene.add(cube);}// 渲染函数const render = () => {renderer.render(scene, camera);};// 动画循环const animate = () => {requestAnimationFrame(animate);// 模拟摄像机移动camera.position.x += 0.01;camera.position.y += 0.01;camera.lookAt(scene.position);render();};animate();</script>
</body></html>
解释
  1. 首先创建了一个基本的Three.js场景,包含了透视摄像机、渲染器等基础元素。
  2. 通过循环创建了多个立方体(模拟多个物体),并为每个立方体设置了随机的位置。
  3. 对于每个立方体,使用THREE.Box3().setFromObject(cube)创建了包围盒,这里额外添加了THREE.Box3Helper来可视化包围盒(在实际的应用中,如果不需要可视化展示,这一步只是为了内部计算包围盒范围,不需要添加这个辅助对象)。Three.js会基于这个包围盒自动进行视锥体剔除,在渲染时,只有处于摄像机视锥体内的立方体会被渲染(以及它们对应的可视化包围盒辅助对象,如果有的话)。
  4. 在动画循环中,模拟了摄像机的移动,随着摄像机位置变化,视锥体范围改变,视锥体剔除机制持续生效,决定哪些立方体被渲染出来。

遮挡剔除(Occlusion Culling)实例

原理概述

遮挡剔除是指不渲染被其他物体完全遮挡的物体,下面的示例是一种基于深度缓冲来实现近似遮挡剔除的简单方法。基本思路是先渲染场景的深度信息,然后在后续渲染过程中,对于那些深度值大于当前像素深度的物体部分,认为是被遮挡的,从而不进行渲染。不过这种方法对于复杂的透明物体等情况有一定局限性。

代码示例
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><title>Occlusion Culling Example</title><style>body {margin: 0;overflow: hidden;}</style><script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r134/three.min.js"></script>
</head><body><script>// 创建场景const scene = new THREE.Scene();// 创建透视摄像机const camera = new THREE.PerspectiveCamera(75,window.innerWidth / window.innerHeight, 0.1, 1000);camera.position.z = 5;// 创建渲染器const renderer = new THREE.WebGLRenderer();renderer.setSize(window.innerWidth, window.innerHeight);document.body.appendChild(renderer.domElement);// 创建地板平面(作为遮挡物示例)const floorGeometry = new THREE.PlaneGeometry(10, 10);const floorMaterial = new THREE.MeshBasicMaterial({ color: 0xcccccc });const floor = new THREE.Mesh(floorGeometry, floorMaterial);floor.rotation.x = -Math.PI / 2;scene.add(floor);// 创建多个球体(模拟被遮挡物体)const sphereGeometry = new THREE.SphereGeometry(0.5, 32, 32);const sphereMaterial = new THREE.MeshBasicMaterial({ color: 0x00ff00 });const numSpheres = 5;for (let i = 0; i < numSpheres; i++) {const sphere = new THREE.Mesh(sphereGeometry, sphereMaterial);sphere.position.x = (Math.random() - 0.5) * 5;sphere.position.y = (Math.random() * 0.5) + 0.5;sphere.position.z = (Math.random() - 0.5) * 5;scene.add(sphere);}// 渲染深度缓冲的渲染目标const depthRenderTarget = new THREE.WebGLRenderTarget(window.innerWidth,window.innerHeight);// 渲染深度信息的函数const renderDepth = () => {renderer.setRenderTarget(depthRenderTarget);renderer.clear();renderer.render(scene, camera);renderer.setRenderTarget(null);};// 正常渲染函数const renderScene = () => {renderer.render(scene, camera);};// 动画循环const animate = () => {requestAnimationFrame(animate);// 先渲染深度信息renderDepth();// 再渲染场景,此时可以基于深度信息进行简单的遮挡判断//(Three.js内部基于深度缓冲有一定的机制来辅助实现部分遮挡剔除效果)renderScene();};animate();</script>
</body></html>
解释
  1. 同样先构建了基础的Three.js场景,包含摄像机、渲染器等,并且创建了一个地板平面(作为遮挡物)以及多个球体(作为可能被遮挡的物体),设置了它们的位置和几何形状、材质等属性。
  2. 创建了一个WebGLRenderTarget对象作为渲染深度缓冲的目标,它的大小与窗口大小一致。
  3. 在动画循环中,首先调用renderDepth函数,这个函数将渲染器的目标设置为之前创建的深度渲染目标,先清空它,然后渲染整个场景到这个深度渲染目标中,这样就获取了场景的深度信息(实际上是深度缓冲的内容),之后再将渲染器的目标设置回默认(null,即渲染到屏幕上)。
  4. 接着调用renderScene函数正常渲染整个场景,此时Three.js会基于之前渲染得到的深度缓冲信息,在一定程度上自动进行一些简单的遮挡判断,不渲染那些深度值大于当前像素深度的物体部分(不过要注意这种方法对于复杂情况有局限性,比如透明物体的遮挡关系处理就比较复杂,还需要更复杂的算法来完善)。

three.js 模型压缩

  1. Draco在Three.js中的应用

    • Draco压缩原理
      • Draco是一种高效的3D数据压缩格式。它主要通过预测和量化技术来减少3D模型数据的大小。例如,对于模型的顶点位置和法向量等几何信息,Draco会分析其分布规律,利用相邻顶点之间的相关性进行预测编码。在量化过程中,它会将高精度的数值转换为较低精度的表示形式,从而大大减少数据量。
    • Three.js中的Draco加载流程
      • 设置加载器
        • 首先需要引入DRACOLoaderGLTFLoaderDRACOLoader用于处理Draco压缩的数据,GLTFLoader用于加载GLTF模型格式(因为Draco通常用于压缩GLTF模型)。
        import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
        import { DRACOLoader} from 'three/examples/jsm/loaders/DRACOLoader.js';
        
      • 配置解码器路径
        • 初始化DRACOLoader后,需要设置解码器路径。解码器可以从Google的官方服务器获取,也可以下载到本地使用。
        const dracoLoader = new DRACOLoader();
        dracoLoader.setDecoderPath
        ('https://www.gstatic.com/draco/v1/decoders/');
        
      • 关联加载器
        • DRACOLoader关联到GLTFLoader上,这样GLTFLoader就能识别和处理Draco压缩的GLTF模型。
        const gltfLoader = new GLTFLoader();
        gltfLoader.setDRACOLoader(dracoLoader);
        
      • 加载模型
        • 最后使用gltfLoader.load方法加载模型。这个方法接受模型文件路径、加载成功回调函数、加载进度回调函数和加载失败回调函数。
        gltfLoader.load('draco_compressed_model.gltf', function (gltf) {const model = gltf.scene;scene.add(model);
        }, function (xhr) {console.log((xhr.loaded / xhr.total * 100) + '% loaded');
        }, function (error) {console.log('An error occurred', error);
        });
        
  2. gltf - pipeline

    • gltf - pipeline概述
      • gltf - pipeline是一个用于处理GLTF模型的工具集。它允许开发者在模型加载前或加载后对GLTF模型进行各种优化操作,如压缩、转换、添加或删除特定的模型属性等。
    • 主要功能和应用场景
      • 模型压缩
        • 可以使用gltf - pipeline进一步压缩已经是GLTF格式的模型。例如,通过优化纹理、量化顶点数据等方式,在Draco压缩的基础上进一步减小模型文件大小。它可以将模型的几何数据、纹理数据等进行更精细的处理,以达到更好的压缩效果。
      • 模型转换和优化
        • 有时候,原始的GLTF模型可能包含一些不必要的信息或者不符合特定的渲染要求。gltf - pipeline可以用于转换模型,比如将模型的坐标系进行调整,或者将模型的材质属性进行统一优化。例如,将多个不同类型的材质转换为更适合WebGL渲染的材质类型,提高渲染效率。
    • 使用示例(命令行工具)
      • 安装
        • 首先需要在项目目录下通过npm安装gltf - pipeline。
        npm install -g gltf-pipeline
        
      • 基本用法 - 模型压缩
        • 假设要压缩一个GLTF模型,可以使用以下命令。这个命令会对输入的模型进行一系列优化处理,包括几何数据和纹理数据的优化,然后输出一个新的压缩后的模型。
        gltf-pipeline -i input_model.gltf -o output_model.gltf -d
        
        • 其中-i指定输入模型路径,-o指定输出模型路径,-d表示进行Draco压缩(如果已经是Draco压缩的模型,这个选项可能会进一步优化)。
    • 在JavaScript代码中集成(高级用法)
      • 安装依赖
        • 除了安装gltf - pipeline,还需要安装相关的JavaScript库,如@gltf - pipeline/functions等。
        npm install @gltf-pipeline/functions
        
      • 代码示例 - 模型优化
        • 以下代码片段展示了如何在JavaScript代码中使用gltf - pipeline的函数来优化模型。
        const { optimize } = require('@gltf-pipeline/functions');
        const fs = require('fs');
        const gltfPipeline = require('gltf-pipeline');
        const { GLTF } = gltfPipeline;
        // 读取GLTF模型文件
        const inputGltf = JSON.parse(fs.readFileSync('input_model.gltf'));
        const options = {dracoOptions: {compressionLevel: 7}
        };
        // 对模型进行优化
        optimize(inputGltf, options).then((optimizedGltf) => {// 将优化后的模型保存为新的文件fs.writeFileSync('optimized_model.gltf', JSON.stringify(optimizedGltf));
        });
        
        • 这段代码首先读取一个GLTF模型文件,然后设置优化选项(这里包括Draco压缩的级别),接着使用optimize函数对模型进行优化,最后将优化后的模型保存为一个新的文件。

相关文章:

Three.js渲染较大的模型之解决方案

文章目录 Three.js渲染较大的模型 解决方案视锥体剔除实例 和 遮挡剔除 实例视锥体剔除&#xff08;Frustum Culling&#xff09;实例原理概述代码示例解释 遮挡剔除&#xff08;Occlusion Culling&#xff09;实例原理概述代码示例解释 three.js 模型压缩 Three.js渲染较大的模…...

webpack 项目访问静态资源

使用 webpack dev serve 启动 react 项目后&#xff0c;发现无法使用 http://localhost:8080/1.png 访问到项目的 /static 目录下的 1.png 文件。我的 webpack-dev.js 配置如下&#xff1a; const webpack require(webpack) const webpackMerge require(webpack-merge) cons…...

Day 25

491.递增子序列 力扣题目链接(opens new window) 给定一个整型数组, 你的任务是找到所有该数组的递增子序列&#xff0c;递增子序列的长度至少是2。 示例: 输入: [4, 6, 7, 7]输出: [[4, 6], [4, 7], [4, 6, 7], [4, 6, 7, 7], [6, 7], [6, 7, 7], [7,7], [4,7,7]] 说明: …...

【金猿案例展】无锡征信——百望云绿色金融数据要素+数据资产入表服务方案...

‍ 百望云数据要素案例 该数据要素项目案例由百望云投递并参与“数据猿年度金猿策划活动——2024数据要素产业年度创新服务企业榜单/奖项”评选。 大数据产业创新服务媒体 ——聚焦数据 改变商业 在数字化浪潮奔涌的时代&#xff0c;数据要素已成为驱动经济发展的关键引擎&…...

【C++】C++新增特性解析:Lambda表达式、包装器与绑定的应用

V可变参数模板与emplace系列 C语法相关知识点可以通过点击以下链接进行学习一起加油&#xff01;命名空间缺省参数与函数重载C相关特性类和对象-上篇类和对象-中篇类和对象-下篇日期类C/C内存管理模板初阶String使用String模拟实现Vector使用及其模拟实现List使用及其模拟实现…...

python学opencv|读取图像

【1】引言 前序学习了使用matplotlib模块进行画图&#xff0c;今天开始我们逐步尝试探索使用opencv来处理图片。 【2】学习资源 官网的学习链接如下&#xff1a; OpenCV: Getting Started with Images 不过读起来是英文版&#xff0c;可能略有难度&#xff0c;所以另推荐一…...

租辆酷车小程序开发(二)—— 接入微服务GRPC

vscode中golang的配置 设置依赖管理 go env -w GO111MODULEon go env -w GOPROXYhttps://goproxy.cn,direct GO111MODULEauto 在$GOPATH/src 外面且根目录有go.mod 文件时&#xff0c;开启模块支持 GO111MODULEoff 无模块支持&#xff0c;go会从GOPATH 和 vendor 文件夹寻找包…...

leetcode 208. 实现 Trie (前缀树)

Trie&#xff08;发音类似 "try"&#xff09;或者说 前缀树 是一种树形数据结构&#xff0c;用于高效地存储和检索字符串数据集中的键。这一数据结构有相当多的应用情景&#xff0c;例如自动补全和拼写检查。 请你实现 Trie 类&#xff1a; Trie() 初始化前缀树对象…...

kafka进阶_3.消费消息

文章目录 一、消费消息概览1.1、消费示例代码1.2、消费过程 二、消费者组2.1、push & pull2.2、消费者组 三、调度器Coordinator四、消费者分配策略4.1、引言4.2、分配基本流程4.3、分配策略4.3.1、轮询分配策略4.3.2、轮询分配策略 五、消费偏移量5.1、起始偏移量5.2、指定…...

预测未来 | MATLAB实现Transformer时间序列预测未来

预测未来 | MATLAB实现Transformer时间序列预测未来 预测效果 基本介绍 1.Matlab实现Transformer时间序列预测未来&#xff1b; 2.运行环境Matlab2023b及以上&#xff0c;data为数据集&#xff0c;单变量时间序列预测&#xff1b; 3.递归预测未来数据&#xff0c;可以控制预…...

VirtualBox7.0.6安装配置

VirtualBox7.0.6安装配置 提示&#xff1a;这里可以添加系列文章的所有文章的目录&#xff0c;目录需要自己手动添加 文章目录 VirtualBox7.0.6安装配置1.安装虚拟机1.1安装虚拟机的必要条件1.1.1开启虚拟化1.1.1.1检查虚拟化是否开启1.1.1.2 开启虚拟化 1.2 安装虚拟机1.1创建…...

Spring Boot英语知识分享网站:技术与实践

2相关技术 2.1 MYSQL数据库 MySQL是一个真正的多用户、多线程SQL数据库服务器。 是基于SQL的客户/服务器模式的关系数据库管理系统&#xff0c;它的有点有有功能强大、使用简单、管理方便、安全可靠性高、运行速度快、多线程、跨平台性、完全网络化、稳定性等&#xff0c;非常…...

HarmonyOS4+NEXT星河版入门与项目实战(22)------动画(属性动画与显示动画)

文章目录 1、属性动画图解2、案例实现-小鱼移动游戏1、代码实现2、代码解释3、资源图片4、实现效果3、显示动画4、案例修改-显示动画5、总结1、属性动画图解 这里我们用一张完整的图来汇整属性动画的用法格式和使用的主要属性范围,如下所示: 2、案例实现-小鱼移动游戏 1、代…...

AI赋能公共服务转型升级 | 第十届中国行业互联网大会暨腾讯云TVP行业大使三周年庆典公共服务专场圆满举办!

引言 党的二十大报告把“基本公共服务实现均等化”作为 2035 年我国发展的总体目标之一&#xff0c;强调要“健全基本公共服务体系&#xff0c;提高公共服务水平”。AI 作为新质生产力的核心驱动力之一&#xff0c;正在公共服务领域发挥着越来越重要的作用。 2024 年 10 月 2…...

网络基础 - 地址篇

一、IP 地址 IP 协议有两个版本&#xff0c;IPv4 和 IPv6IP 地址(IPv4 地址)是一个 4 字节&#xff0c;32 位的正整数&#xff0c;通常使用 “点分十进制” 的字符串进行表示&#xff0c;例如 192.168.0.1&#xff0c;用点分割的每一个数字表示一个字节&#xff0c;范围是 0 ~…...

chrome允许http网站打开摄像头和麦克风

第一步 chrome://flags/#unsafely-treat-insecure-origin-as-secure 第二步 填入网址&#xff0c;点击启用 第三步 重启 Chrome&#xff1a;设置完成后&#xff0c;点击页面底部的 “Relaunch” 按钮&#xff0c;重新启动 Chrome 浏览器&#xff0c;使更改生效。...

uniapp前端开发,基于vue3,element plus组件库,以及axios通讯

简介 UniApp 是一个基于 Vue.js 的跨平台开发框架&#xff0c;旨在通过一次开发、编译后运行在多个平台上&#xff0c;如 iOS、Android、H5、以及小程序&#xff08;微信小程序、支付宝小程序、百度小程序等&#xff09;等。UniApp 为开发者提供了统一的开发体验&#xff0c;使…...

STM32-- 串口发送数据

while(USART_GetFlagStatus(USART2,USART_FLAG_TXE)RESET);&#xff1f;&#xff1f; 答&#xff1a; 这行代码&#xff1a; while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) RESET);的作用是等待串口 USART2 的发送数据寄存器&#xff08;TXE&#xff0c;Transmit Dat…...

网络安全提示

如果您是企业主或 IT 经理&#xff0c;您应该知道计算机安全的重要性。从保护密码安全的基础知识到网络钓鱼、恶意软件等的危险&#xff0c;本文将为您提供您需要了解的有关网络安全的信息。 每年&#xff0c;互联网都变得越来越大&#xff0c;这意味着我们为黑客和网络犯罪分…...

【计算机网络】多路转接之epoll

epoll也是一种linux中的多路转接方案(epoll也是只负责IO过程中的"等") 一、epoll相关接口的使用 1.epoll_create int epoll_create(int size); ​功能&#xff1a;创建一个epoll模型 ① int size&#xff1a;没意义了 >0就行 返回值&#xff1a;返回一个文件…...

nextjs+nestjs+prisma写todolist全栈项目

技术栈 nextjsnestjsprisma所学知识 Nextjs组件渲染,状态,路由docker启动Mysql容器prisma操作Mysql(CRUD)允许跨域请求APITanStack Query异步状态管理fetch api服务器组件预请求数据nestjs 管道和异常处理检测id是否正整数Docker启动Mysql容器 compose.yml name: todoLis…...

重构代码之将双向关联改为单向关联

在代码重构中&#xff0c;双向关联改为单向关联是指将原本双向关联转变为单向关联。这种重构方式有助于简化对象模型和提高代码的可维护性&#xff0c;减少不必要的耦合。下面是对这个重构技巧的详细讲解。 一、为什么需要将双向关联改为单向关联&#xff1f; 减少耦合&#…...

Linux介绍与安装指南:从入门到精通

1. Linux简介 1.1 什么是Linux&#xff1f; Linux是一种基于Unix的操作系统&#xff0c;由Linus Torvalds于1991年首次发布。Linux的核心&#xff08;Kernel&#xff09;是开源的&#xff0c;允许任何人自由使用、修改和分发。Linux操作系统通常包括Linux内核、GNU工具集、图…...

深度学习中的正则化模型是什么意思?

一、定义 在深度学习中&#xff0c;正则化是一种用于防止过拟合的技术。过拟合是指模型在训练数据上表现非常好&#xff0c;但在新的、未见过的数据&#xff08;测试数据&#xff09;上表现很差的情况。正则化模型就是通过在损失函数中添加额外的项来约束模型的复杂度&#xf…...

rabbitMq两种消费应答失败处理方式

在rabbitMq消费端&#xff0c;有三种应答模式&#xff1a; none&#xff1a;不处理。即消息投递给消费者后立刻 ack 消息会立刻从MQ删除。非常不安全&#xff0c;不建议使用 manual&#xff1a;手动模式。需要自己在业务代码中调用api&#xff0c;发送 ack 或 reject&#xff…...

windows C#-使用反射访问特性

你可以定义自定义特性并将其放入源代码中这一事实&#xff0c;在没有检索该信息并对其进行操作的方法的情况下将没有任何价值。 通过使用反射&#xff0c;可以检索通过自定义特性定义的信息。 主要方法是 GetCustomAttributes&#xff0c;它返回对象数组&#xff0c;这些对象在…...

java中链表的数据结构的理解

在 Java 中&#xff0c;链表是一种常见的数据结构&#xff0c;可以通过类的方式实现自定义链表。以下是关于 Java 中链表的数据结构和实现方式的详细介绍。 1. 自定义链表结构 Java 中链表通常由一个节点类 (ListNode) 和可能的链表操作类构成。 节点类 (ListNode) 这是链表…...

ctfshow

1,web153 大小写绕过失败 使用.user.ini 来构造后⻔ php.ini是php的⼀个全局配置⽂件&#xff0c;对整个web服务起作⽤&#xff1b;⽽.user.ini和.htaccess⼀样是⽬录的配置⽂件&#xff0c;.user.ini就是⽤户⾃定义的⼀个php.ini&#xff0c;我们可以利⽤这个⽂件来构造后⻔和…...

【AI绘画】Midjourney进阶:色调详解(下)

博客主页&#xff1a; [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: AI绘画 | Midjourney 文章目录 &#x1f4af;前言&#x1f4af;Midjourney中的色彩控制为什么要控制色彩&#xff1f;为什么要在Midjourney中控制色彩&#xff1f; &#x1f4af;色调纯色调灰色调暗色调 &#x1f4af…...

lanqiaoOJ 3747:繁忙的精神疗养院 ← STL queue

【题目来源】https://www.lanqiao.cn/problems/3747/learning/【题目描述】 心灵之园是一家知名的精神疗养院&#xff0c;为了提供更优质的服务&#xff0c;他们专门设立了一个 VIP 诊室和一个普通诊室。VIP 诊室主要接待特殊需求的高级会员&#xff0c;而普通诊室则服务所有的…...

Local Changes不展示,DevEco Studio的git窗口中没有Local Changes

DevEco Studio的git窗口中&#xff0c;没有Local Changes&#xff0c;怎么设置可以调出&#xff1f; 进入File-->Settings-->Version Control&#xff0c;将Use non-modal commit interface前的勾选框取消勾选&#xff0c;点击OK即可在打开git窗口&#xff0c;就可以看到…...

探索Python项目模板化的新纪元 —— Copier库揭秘

文章目录 **探索Python项目模板化的新纪元 —— Copier库揭秘**1. 背景介绍&#xff1a;为何Copier成为Python开发者的新宠&#xff1f;2. Copier究竟是什么&#xff1f;3. 如何安装Copier&#xff1f;4. 简单库函数使用方法创建模板从Git URL创建项目使用快捷方式动态文件生成…...

导入100道注会cpa题的方法,导入试题,自己刷题

一、问题描述 复习备考的小伙伴们&#xff0c;往往希望能够利用零碎的时间和手上的试题&#xff0c;来复习和备考 用一个能够导入自己试题的刷题工具&#xff0c;既能加强练习又能利用好零碎时间&#xff0c;是一个不错的解决方案 目前市面上刷题工具存下这些问题 1、要收费…...

使用NAS开启无纸化办公,Docker部署开源文档管理系统『Paperless-ngx』

使用NAS开启无纸化办公&#xff0c;Docker部署开源文档管理系统『Paperless-ngx』 哈喽小伙伴们好&#xff0c;我是Stark-C~ 对于文案类的办公场景来说&#xff0c;手头堆放最多的可能就是各种文档文件&#xff0c;以及各种用过的打印废纸。 这么多年来&#xff0c;不管是领…...

docker安装mysql

1.拉取mysql镜像 docker pull mysql:5.7 2.启动mysql容器 docker run -d -e MYSQL_ROOT_PASSWORD123456 -e MYSQL_TCP_PORT3307 -p 3307:3307 -v /SDXL/wjz/docker_mysql_log:/var/log/mysql -v /SDXL/wjz/docker_mysql_data:/var/lib/mysql -v /SDXL/wjz/docker_mysql_conf:/e…...

9、深入剖析PyTorch的nn.Sequential及ModuleList源码

文章目录 1. train&eval2. 求导数3. 参数更新4. ModuleList,Sequential5. Parameter&Parameter_List&ParmeterDict 1. train&eval train 模式&#xff1a;表示的是神经网络的训练模式&#xff0c;能够进行样本学习&#xff0c;通过样本来更新权重weighteval 模…...

idea初始化设置

下载idea&#xff1a; https://www.jetbrains.com/idea/ 安装idea 安装插件&#xff1a; Rainbow BracketsLombokMybatisXSonarLintMaven HelperCodeGeeX&#xff08;国内AI插件可用&#xff09; 设置idea注释模板&#xff1a; 设置代码注释模板&#xff1a; https://blo…...

【C/C++】内存管理详解:从new/delete到智能指针的全面解析

文章目录 更多文章C/C中的传统内存管理方式new和delete运算符malloc和free函数传统内存管理的弊端 智能指针的崛起智能指针的定义与作用C11引入的标准智能指针 详解C标准智能指针std::unique_ptr特点使用方法适用场景 std::shared_ptr特点使用方法适用场景 std::weak_ptr特点使…...

Vue.Draggable使用nested-with-vmodel进行拖拽

Vue.Draggable使用nested-with-vmodel进行拖拽 1. 介绍 ‌draggable‌是一个基于Sortable.js的Vue组件&#xff0c;用于实现拖拽功能。它支持触摸设备、拖拽和选择文本、智能滚动、不同列表之间的拖拽等功能&#xff0c;并且与Vue的视图模型同步刷新&#xff0c;兼容Vue2的过…...

MySQL 中的乐观锁与悲观锁

文章目录 MySQL 中的乐观锁与悲观锁一、引言二、乐观锁&#xff08;一&#xff09;原理&#xff08;二&#xff09;应用场景&#xff08;三&#xff09;示例代码 三、悲观锁&#xff08;一&#xff09;原理&#xff08;二&#xff09;应用场景&#xff08;三&#xff09;示例代…...

面试题分享(一)

实习的项目 成员规模 用到过哪些设计模式&#xff1f; 策略、单例、工厂、代理 责任链模式了解吗&#xff1f; 责任链模式&#xff08;Chain of Responsibility Pattern&#xff09;是一种行为型设计模式&#xff0c;目的是为了避免请求的发送者与接收者之间的耦合关系。通…...

用天翼云搭建一个HivisionIDPhoto证件照处理网站

世人不必记我&#xff0c;我不记世人。 HivisionIDPhoto证件照处理网站 世人不必记我&#xff0c;我不记世人。项目地址项目搭建与修改前端后端遇到的坑 成果图 前段时间工作需要频繁处理证件照&#xff0c;当时同事推荐一个证件照小程序&#xff08;要看广告&#xff09;&…...

Conda环境迁移到内网

文章目录 一、conda是什么&#xff1f; conda环境迁移 二、迁移方法 1.docker方式 2.conda包方式 3.conda指定目录创建环境 4.pip方式 5.单个包安装 总结 前言 搞Python&#xff0c;使用conda是避免不了的&#xff0c;利用conda可以方便的管理多个不同的虚拟环境&…...

React Hooks中use的细节

文档 useState useState如果是以函数作为参数&#xff0c;那要求是一个纯函数&#xff0c;不接受任何参数&#xff0c;同时需要一个任意类型的返回值作为初始值。 useState可以传入任何类型的参数作为初始值&#xff0c;当以一个函数作为参数进行传入的时候需要注意&#xff…...

Android 16 开发者预览版抢先使用

Android 16 开发者预览版 获取 Android 16在 Google Pixel 设备上获取 Android 16设置 Android 模拟器 设置 Android 16 SDK获取 Android Studio安装 SDK更新应用的 build 配置 获取 Android 16 你可以通过以下任一方式获取 Android 16 在 Google Pixel 设备上获取 Android 1…...

蓝桥杯c++算法秒杀【6】之动态规划【上】(数字三角形、砝码称重(背包问题)、括号序列、组合数问题:::非常典型的必刷例题!!!)

下将以括号序列、组合数问题超级吧难的题为例子讲解动态规划 别忘了请点个赞收藏关注支持一下博主喵&#xff01;&#xff01;&#xff01;! ! ! ! &#xff01; 关注博主&#xff0c;更多蓝桥杯nice题目静待更新:) 动态规划 一、数字三角形 【问题描述】 上图给出了…...

c#:winform引入bartender

1、vs新建项目 ①选择Windows窗体应用&#xff08;.NET Framework&#xff09; 2、将bartender引入vs中 ①找到bartender的安装目录&#xff0c;复制Seagull.BarTender.Print.dll文件 ②粘贴到项目->bin->Debug文件&#xff0c;并可创建Model文件夹&#xff1a;为了存放…...

Zabbix 模板翻译自动化教程

在企业 IT 运维管理中&#xff0c;Zabbix 作为一款强大的开源监控平台被广泛应用。而 Zabbix 模板作为监控配置的重要组成部分&#xff0c;用来定义监控项、触发器、图形等。随着国际化的需求增加&#xff0c;Zabbix 模板的翻译工作变得日益重要&#xff0c;特别是在需要为不同…...

HarmonyOS开发:DevEco Studio的Beta3(5.0.5.200)新增和增强特性

新增特性 DevEco Studio支持开发API 13工程。DevEco Profiler Frame模板新增Lost Frames和Hitch Time泳道&#xff0c;用于识别和优化卡顿和丢帧现象。具体请参考Frame分析。hvigor-config.json5中properties下新增ohos.arkCompile.noEmitJs字段&#xff0c;用于指定ArkTS编译…...

macOS安装nvm node

macOS安装nvm macOS安装nvm创建 nvm 工作目录配置环境变量使用 nvm查看可用的 Node.js 版本安装特定版本 macOS安装nvm brew install nvm创建 nvm 工作目录 mkdir ~/.nvm配置环境变量 vim ~/.zshrc# nvm export NVM_DIR"$HOME/.nvm" [ -s "/opt/homebrew/opt…...