Threejs——十四、关于深度冲突、重叠、以及加载模型进度条效果实现(附完整代码)

news2025/2/3 14:53:10

深度冲突

两个模型重叠的模型,通过浏览器旋转预览,会发现模型旋转的时候会发生闪烁。
这种情况,主要是两个模型重合,电脑分不清谁在前谁在后,这种情况,可以理解为深度冲突Z-fighting

function addBox() {
  const geometry = new THREE.BoxGeometry(10, 10, 10);
  // 材质
  const material = new THREE.MeshPhysicalMaterial({
    color: 0x51efe4, //0x51efe4设置材质颜色
  });
  // 网络模型
  mesh = new THREE.Mesh(geometry, material);
  mesh.position.set(0, 10, 0);
  const mesh2 = mesh.clone();
  mesh2.geometry = mesh.geometry.clone();
  mesh2.material = mesh.material.clone();
  mesh2.position.x = 5;
  mesh2.material.color.set(0xffff00);
  scene.add(mesh);
  scene.add(mesh2);
}

效果:
请添加图片描述

两个几何体 Mesh 拉开距离

适当偏移,解决深度冲突,偏移尺寸相对模型尺寸比较小,视觉上两个几何体近似还是重合效果。

mesh2.position.z = 1;

请添加图片描述

webgl 渲染器设置对数深度缓冲区

这种情况我这里遇到过一次,通过压缩模型后进行放大缩小会发现出现模型闪烁的 bug,所以这里可以用logarithmicDepthBuffer解决冲突问题。
注意:如果两模型面间隙过小,或者重合,,此渲染器对数深度缓冲区也是没有效果的

// WebGL渲染器设置
const renderer = new THREE.WebGLRenderer({
  // 设置对数深度缓冲区,优化深度冲突问题
  logarithmicDepthBuffer: true,
});

区别:

const geometry = new THREE.BoxGeometry(10, 10, 10);
// 材质
const material = new THREE.MeshPhysicalMaterial({
  color: 0x51efe4, //0x51efe4设置材质颜色
});
// 网络模型
mesh = new THREE.Mesh(geometry, material);
mesh.position.set(0, 10, 0);
const mesh2 = mesh.clone();
mesh2.geometry = mesh.geometry.clone();
mesh2.material = mesh.material.clone();
mesh2.position.x = 5;
mesh2.material.color.set(0xffff00);
mesh2.position.z = 1;
mesh.position.y = 10.01;  // 加Y轴
scene.add(mesh);
scene.add(mesh2);

请添加图片描述

不加logarithmicDepthBuffer
请添加图片描述

模型加载进度条

这里拿GLTFLoader来测试

let loadedData = 0
loader.load(new URL(`../assets/model.glb`, import.meta.url).href,function (gltf) {
      scene.add(gltf.scene);
      render();
    },
    function (xhr) {
      // 后台打印查看模型文件加载进度
    //   console.log("加载完成的百分比" + (xhr.loaded / xhr.total) * 100 + "%");
      loadedData = Math.floor((xhr.loaded / xhr.total) * 100);
    //   console.log(Math.floor((xhr.loaded / xhr.total) * 100));
      if (Math.floor((xhr.loaded / xhr.total) * 100) == 100) {
        setTimeout(() => {
          data.statu = false;
        }, 1000);
      }
    },
    function (err) {
      console.error("加载发生错误");
    }
  );

这里可以进行判断,如果loadedData等于100,也就是模型加载完毕的时候,那么这段文字就隐藏起来
附完整代码:

/*
 * @Author: SouthernWind 
 * @Date: 2023-06-14 16:38:59 
 * @Last Modified by: SouthernWind 
 * @Last Modified time: 2023-06-20 14:39:07
 */

<template>
  <el-button class="yellow-btn" type="warning" plain @click="yellowBtn">黄色</el-button>
  <el-button class="green-btn" type="success" plain @click="greenBtn">绿色</el-button>
  <el-button class="save-btn" @click="saveFile">下载</el-button>
  <div class="container" ref="container"></div>
</template>

<script setup>
import * as THREE from "three";
// 轨道
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
import { GLTFLoader } from "three/addons/loaders/GLTFLoader.js";
import { GUI } from "three/addons/libs/lil-gui.module.min.js";

import { ref, reactive, onMounted } from "vue";
// 三个必备的参数
let scene,
  camera,
  renderer,
  controls,
  mesh,
  material,
  group,
  texture,
  gui,
  textureCube;

onMounted(() => {
  // 外层需要获取到dom元素以及浏览器宽高,来对画布设置长宽
  // clientWidth等同于container.value.clientWidth
  let container = document.querySelector(".container");
  const { clientWidth, clientHeight } = container;
  console.log(clientHeight);
  // 首先需要获取场景,这里公共方法放在init函数中
  const init = () => {
    scene = new THREE.Scene();
    // 给相机设置一个背景
    scene.background = new THREE.Color(0xaaaaaa);
    // 透视投影相机PerspectiveCamera
    // 支持的参数:fov, aspect, near, far
    camera = new THREE.PerspectiveCamera(
      60,
      clientWidth / clientHeight,
      0.001,
      6000
    );
    // 相机坐标
    camera.position.set(30, 30, 30);

    // 相机观察目标
    camera.lookAt(scene.position);
    // 渲染器
    renderer = new THREE.WebGLRenderer({
      antialias: true,
      preserveDrawingBuffer: true,
      logarithmicDepthBuffer: true
    });
    renderer.shadowMap.enabled = true;
    renderer.shadowMap.type = THREE.PCFSoftShadowMap;
    // 渲染多大的地方
    renderer.setClearAlpha(0.0);
    renderer.setSize(clientWidth, clientHeight);
    /* renderer.outputEncoding = THREE.sRGBEncoding; */
    // const axesHelper = new THREE.AxesHelper(150);
    // scene.add(axesHelper);
    container.appendChild(renderer.domElement);
    addBox();
    console.log("查看当前屏幕设备像素比", window.devicePixelRatio);
  };
  init();
  function addBox() {
    /* gui = new GUI();
    const geometry = new THREE.TorusKnotGeometry(10, 3, 100, 16);
    const material = new THREE.MeshPhysicalMaterial({
      color: 0x30cff8,
      metalness: 0,
      roughness: 0,
      transmission: 0.5,
      ior: 1.5,
    });
    mesh = new THREE.Mesh(geometry, material);
    scene.add(mesh);
    gui.add(material, "transmission", 0, 1);
    gui.add(material, "ior", 1, 2.333); */

    const geometry = new THREE.BoxGeometry(10, 10, 10);
    // 材质
    const material = new THREE.MeshPhysicalMaterial({
      color: 0x51efe4, //0x51efe4设置材质颜色
    });
    // 网络模型
    mesh = new THREE.Mesh(geometry, material);
    mesh.position.set(0, 10, 0);
    const mesh2 = mesh.clone();
    mesh2.geometry = mesh.geometry.clone();
    mesh2.material = mesh.material.clone();
    mesh2.position.x = 5;
    mesh2.material.color.set(0xffff00);
    mesh2.position.z = 1;
    mesh.position.y = 10.01;
    scene.add(mesh);
    scene.add(mesh2);
    // camera.position.set(292*5, 223*5, 185*5);
  }

  // 相机控件
  const control = () => {
    controls = new OrbitControls(camera, renderer.domElement);
    controls.addEventListener("change", function () {});
  };
  control();

  // 光源
  const linght = () => {
    const pointLight = new THREE.PointLight(0xffffff, 1.0);
    // pointLight.position.set(400, 0, 0);//点光源放在x轴上
    pointLight.position.set(100, 60, 50); //设置光源的位置
    // 光源和网格模型Mesh对应一样是三维场景的一部分,自然需要添加到三维场景中才能起作用。
    scene.add(pointLight); // 添加光源到场景中

    /*  const pointLight = new THREE.AmbientLight(0xffffff, 1.0);
    pointLight.position.set(150, 150, 150);
        scene.add(pointLight); */
    const pointLightHelper = new THREE.PointLightHelper(pointLight, 1);
    scene.add(pointLightHelper);
  };
  linght();
  const render = () => {
    renderer.render(scene, camera);
    requestAnimationFrame(render);
  };
  render();
  window.addEventListener("resize", () => {
    // 更新摄像头
    camera.aspect = window.innerWidth / window.innerHeight;
    camera.updateProjectionMatrix();
    renderer.setSize(window.innerWidth, window.innerHeight);
  });
});
const yellowBtn = () => {
  console.log(mesh);
  mesh.material.color.set(0xe5a144);
};
const greenBtn = () => {
  console.log(mesh);
  mesh.material.color.set(0x69c242);
};
const saveFile = () => {
  const link = document.createElement("a");
  // 通过超链接herf属性,设置要保存到文件中的数据
  var canvas = renderer.domElement; //获取canvas对象
  link.href = canvas.toDataURL("image/png");
  link.download = "threejs.png"; //下载文件名
  link.click(); //js代码触发超链接元素a的鼠标点击事件,开始下载文件到本地

  // 通过超链接herf属性,设置要保存到文件中的数据
  // link.href = window.URL.createObjectURL(new Blob([JSON.stringify(scene),JSON.stringify(mesh)]));
  // link.download = '模型数据.txt';//下载文件名
  // link.download = 'threejs.png';
  // const canvas = renderer.domElement; //获取canvas对象
  // link.href = canvas.toDataURL("image/png");
  // link.click();//js代码触发超链接元素a的鼠标点击事件,开始下载文件到本地
};
</script>

<style>
.container {
  width: 100%;
  height: 100vh;
  position: relative;
  z-index: 1;
  /* background: #ff5810; */
}
.yellow-btn {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 99;
}
.green-btn {
  position: absolute;
  top: 0;
  left: 50px;
  z-index: 99;
}
.save-btn {
  position: absolute;
  top: 0;
  left: 111px;
  z-index: 99;
}
</style>


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

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

相关文章

Pytorch基本使用——NLP数据集构建总结

构建NLP数据集&#xff0c;分为如下几步&#xff1a; 1.单词分割形式 2.词汇表 3.利用词汇表word2idx映射&#xff0c;制作数据集 4.打包 ✨ 1.单词分割 有两种表示方式&#xff0c;一种是word-level&#xff0c;另外一种是char-level。 &#x1f30a; 1.1 word-level token…

可爱小猫猫【InsCode Stable Diffusion美图活动一期】

一、 Stable Diffusion 模型在线使用地址&#xff1a;https://inscode.csdn.net/inscode/Stable-Diffusion 二、模型版本及相关配置&#xff1a; 模型&#xff1a;chilloutmix_NiPrunedFp32fix Lora&#xff1a;cat_20230627113759 采样迭代步数&#xff08;steps&#xff09;:…

十三、前端包管理工具详解

一、代码共享方案 我们已经学习了在JavaScript中可以通过模块化的方式将代码划分成一个个小的结构&#xff1a; 在以后的开发中我们就可以通过模块化的方式来封装自己的代码&#xff0c;并且封装成一个工具&#xff1b; 这个工具我们可以让同事通过导入的方式来使用&#xf…

jetson系列开发板生成.engine部署

jetson系列开发板 生成engine 1. 下载 tensorrtx 至 NX git clone -b yolov5-v5.0 https://github.com/wang-xinyu/tensorrtx.git2. 修改 yololayer.h 中的参数 labels.txt 中有几类就将 CLASS_NUM 修改为几。 static constexpr int CLASS_NUM 80; 3. 编译 tensorrtx/yolov…

OLED拼接屏出现坏点怎么办?专家提供的修复方法与建议

OLED拼接屏作为一种高级显示技术&#xff0c;广泛应用于商业展示、会议室和监控中心等场所。 然而&#xff0c;由于制造过程中的缺陷或长时间使用导致的原因&#xff0c;OLED拼接屏可能出现屏幕坏点问题。本文将详细介绍OLED拼接屏屏幕坏点的修复方法与注意事项&#xff0c;帮…

高效编程:如何优雅地判断数组中所有对象的值不为空?

前言 在前端开发中&#xff0c;判断数组中所有对象的值是否都不为空是一个常见的任务。这个任务可能涉及到多个对象和多个属性&#xff0c;因此需要一种简洁而高效的方法来处理。本文将介绍三种不同的方法&#xff0c;帮助你轻松应对这个问题。 方法一&#xff1a;使用 every()…

原生js实现将图片内容复制到剪贴板

核心代码 /*复制图片*/ copyImg(dom) {/* 警告&#xff1a;dom不能是img标签&#xff0c;建议用DIV标签包裹img标签&#xff0c;否者会报错&#xff01;不支持复制背景图&#xff01; */dom.style.userSelect auto;let selection getSelection(), range document.createRan…

【AT89C52单片机项目】数字密码锁设计

实验目的 使用单片机设计数字密码锁。 实验仪器 一套STC89C52RC开发板套件&#xff0c;包括STC89C52RC开发板&#xff0c;以及USB烧录线。 设计要求 1、有设置密码、开锁工作模式&#xff1b; 2、可以每次都设置密码&#xff0c;也可以设置一次密码多次使用。 实验原理 …

JS加密之JS基础大考验

JS加密之JS基础大考验 工欲利其器 必先善其事 JavaScript&#xff08;简称JS&#xff09;是一种高级、动态、弱类型的编程语言&#xff0c;主要用于前端网页开发&#xff0c;但也可用于后端服务器开发&#xff08;通过Node.js&#xff09;。下面是JavaScript的一些特点&#…

windows 安装Vcenter6.7避坑指南

1、推荐windows server 2016。第一次选择windows 2019会出现很多错误 2、内存要求&#xff1a;8G以上 3、如果安装了VMtools&#xff0c;则需要把VCC全部卸载了&#xff08;控制面板-->卸载程序&#xff09;

【Linux初阶】基础IO - 软硬链接 | 初识、理解、应用 文件acm时间

&#x1f31f;hello&#xff0c;各位读者大大们你们好呀&#x1f31f; &#x1f36d;&#x1f36d;系列专栏&#xff1a;【Linux初阶】 ✒️✒️本篇内容&#xff1a;初识软硬链接&#xff0c;软硬链接的区别&#xff0c;理解软硬链接&#xff0c;软硬链接的应用&#xff0c;文…

Access简单应用

不说废话,直入正题. 关于Access的用法 一开始大家想用添加数据快速生成sql语句,其实在这里 java链接Access数据库需要ODBC连接池 机器jar包 ODBC连接池在 首次添加需要配置如上图所示,jar包链接在下面,直接放到项目下即可 UCanAccess - Browse Files at SourceForge.net下载…

前端学习记录~2023.7.13~CSS杂记 Day6

前言一、基本文字和字体样式1、CSS 中的文字样式涉及什么2、字体&#xff08;1&#xff09;颜色&#xff08;2&#xff09;字体种类a. 网络安全字体b. 默认字体c. 字体栈 &#xff08;3&#xff09;字体大小&#xff08;4&#xff09;字体样式&#xff08;5&#xff09;字体粗细…

基于SpringBoot+vue的交流互动系统设计与实现

博主介绍&#xff1a; 大家好&#xff0c;我是一名在Java圈混迹十余年的程序员&#xff0c;精通Java编程语言&#xff0c;同时也熟练掌握微信小程序、Python和Android等技术&#xff0c;能够为大家提供全方位的技术支持和交流。 我擅长在JavaWeb、SSH、SSM、SpringBoot等框架…

C语言strcmp()函数学习

strcmp函数是string compare(字符串比较)的缩写&#xff0c;用于比较两个字符串并根据比较结果返回整数&#xff1b; strcmp(str1,str2)&#xff1b; 若str1str2&#xff0c;则返回零&#xff1b;若str1<str2&#xff0c;则返回负数&#xff1b;若str1>str2&#xff0c;则…

尚硅谷--Vue从入门到精通

尚硅谷–Vue从入门到精通 第1章&#xff1a;Vue核心 1.1 Vue简介 1.1.1 Vue是什么&#xff1f; 一套用于构建用户界面的渐进式JS框架。 1.1.2 谁开发的&#xff1f; ——尤雨溪。 2015-10-27 正式发布 Vue1.0.0 Evangelion&#xff08;新世纪福音战士&#xff09;2016-1…

【PythonBA】商业分析:Business Analytics 的理解

猛戳订阅&#xff01; &#x1f449; 《一起玩蛇》&#x1f40d; &#x1f4dc; 本章目录&#xff1a; Ⅰ. BA 的基础概念 0x00 什么是商业分析&#xff08;Business Analytics&#xff09; 0x01 Explain 和 Predict 0x02 如何去进行分析&#xff1f; 0x03 Python 数据分…

Flutter加载Html

Flutter_Fai_Webview 插件可实现的功能&#xff1a; 同时适配于 Android Ios 两个平台通过 url 来加载渲染一个Html 页面加载 Html 文本数据 如 <html> .... </html>等加载 Html 标签数据 如 <p> ... </p>实现 WebView 加载完成后&#xff0c;自动测量…

【报错】Failed to determine a suitable driver class

文章目录 是否需要mybatis依赖&#xff1a;不需要排除resources未编译 报错信息 *************************** APPLICATION FAILED TO START ***************************Description:Failed to configure a DataSource: url attribute is not specified and no embedded datas…

Python实现HBA混合蝙蝠智能算法优化循环神经网络回归模型(LSTM回归算法)项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档视频讲解&#xff09;&#xff0c;如需数据代码文档视频讲解可以直接到文章最后获取。 1.项目背景 蝙蝠算法是2010年杨教授基于群体智能提出的启发式搜索算法&#xff0c;是一种搜索全局最优解的有效方法…