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

Three的lod技术

 1、资源:https://sbcode.net/threejs/lod/

import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
import Stats from 'three/examples/jsm/libs/stats.module'
import { GUI } from 'dat.gui'
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'
import TWEEN from '@tweenjs/tween.js'const scene = new THREE.Scene()
scene.background = new THREE.Color(0x87ceeb)const light = new THREE.DirectionalLight(0xffffff, 10)
light.position.set(100, 100, 100)
light.castShadow = true
light.shadow.mapSize.width = 4096
light.shadow.mapSize.height = 4096
light.shadow.camera.near = 0.5
light.shadow.camera.far = 500
light.shadow.camera.left = -500
light.shadow.camera.right = 500
light.shadow.camera.top = 500
light.shadow.camera.bottom = -500
scene.add(light)// const helper = new THREE.CameraHelper(light.shadow.camera);
// scene.add(helper);const camera = new THREE.PerspectiveCamera(75,window.innerWidth / window.innerHeight,0.1,1000
)
camera.position.set(4, 5, 7)const renderer = new THREE.WebGLRenderer()
renderer.setSize(window.innerWidth, window.innerHeight)
renderer.shadowMap.enabled = true
document.body.appendChild(renderer.domElement)const controls = new OrbitControls(camera, renderer.domElement)
controls.dampingFactor = 0.05
controls.enableDamping = true
controls.screenSpacePanning = falseconst raycaster = new THREE.Raycaster()
const sceneMeshes = new Array()const material = new THREE.MeshPhongMaterial({ color: 0x567d46 })
const planeGeometry = new THREE.PlaneGeometry(1, 1)
planeGeometry.scale(500, 500, 1)
const planeMesh = new THREE.Mesh(planeGeometry, material)
planeMesh.rotateX(-Math.PI / 2)
planeMesh.receiveShadow = true
scene.add(planeMesh)
sceneMeshes.push(planeMesh)let childObjectCount = 2 //how many child meshes are in the tree model. The trunk and leaves are different meshes
const treeCount = 1200 //this many trees are drawn
let treeCounter = 0const positions = new Array()
for (let i = 0; i < treeCount; i++) {positions.push({x: Math.random() * 400 - 200,y: 0,z: Math.random() * 400 - 200,})
}
const scales = new Array()
for (let i = 0; i < treeCount; i++) {scales.push({x: Math.random() * 2 + 1,y: Math.random() * 5 + 1,z: Math.random() * 2 + 1,})
}const treesTypes = ['saplingTree', 'birchTreeWithLeaves', 'tree1WithLeaves']
treesTypes.forEach((treeType) => {let treeHighDetail = new THREE.Object3D()let treeMediumDetail = new THREE.Object3D()let treeLowDetail = new THREE.Object3D()const glTFLoader = new GLTFLoader()glTFLoader.load('models/' + treeType + '_high.glb', (gltf) => {for (let j = 0; j < childObjectCount; j++) {const geometry = (gltf.scene.children[0].children[j] as THREE.Mesh).geometrytreeHighDetail.add(new THREE.Mesh(geometry,(gltf.scene.children[0].children[j] as THREE.Mesh).material))}treeHighDetail.traverse(function (child) {if ((<THREE.Mesh>child).isMesh) {child.castShadow = true}})glTFLoader.load('models/' + treeType + '_medium.glb', (gltf) => {for (let j = 0; j < childObjectCount; j++) {const geometry = (gltf.scene.children[0].children[j] as THREE.Mesh).geometrytreeMediumDetail.add(new THREE.Mesh(geometry,(gltf.scene.children[0].children[j] as THREE.Mesh).material))}treeMediumDetail.traverse(function (child) {if ((<THREE.Mesh>child).isMesh) {child.castShadow = true}})glTFLoader.load('models/' + treeType + '_low.glb', (gltf) => {for (let j = 0; j < childObjectCount; j++) {const geometry = (gltf.scene.children[0].children[j] as THREE.Mesh).geometrytreeLowDetail.add(new THREE.Mesh(geometry,(gltf.scene.children[0].children[j] as THREE.Mesh).material))}treeLowDetail.traverse(function (child) {if ((<THREE.Mesh>child).isMesh) {child.castShadow = true}})for (let i = 0; i < treeCount / treesTypes.length; i++) {const lod = new THREE.LOD()let mesh = treeHighDetail.clone()mesh.scale.copy(scales[treeCounter])lod.addLevel(mesh, 5)mesh = treeMediumDetail.clone()mesh.scale.copy(scales[treeCounter])lod.addLevel(mesh, 10)mesh = treeLowDetail.clone()mesh.scale.copy(scales[treeCounter])lod.addLevel(mesh, 30)lod.position.copy(positions[treeCounter])scene.add(lod)treeCounter++}})})})
})window.addEventListener('resize', onWindowResize, false)
function onWindowResize() {camera.aspect = window.innerWidth / window.innerHeightcamera.updateProjectionMatrix()renderer.setSize(window.innerWidth, window.innerHeight)render()
}renderer.domElement.addEventListener('dblclick', onDoubleClick, false)
function onDoubleClick(event: MouseEvent) {const mouse = {x: (event.clientX / renderer.domElement.clientWidth) * 2 - 1,y: -(event.clientY / renderer.domElement.clientHeight) * 2 + 1,}raycaster.setFromCamera(mouse, camera)const intersects = raycaster.intersectObjects(sceneMeshes, false)if (intersects.length > 0) {const p = intersects[0].pointnew TWEEN.Tween(controls.target).to({x: p.x,y: p.y,z: p.z,},500).easing(TWEEN.Easing.Cubic.Out).start()}
}const stats = new Stats()
document.body.appendChild(stats.dom)var data = {color: light.color.getHex(),shadowMapSizeWidth: 4096,shadowMapSizeHeight: 4096,mapsEnabled: true,
}
const gui = new GUI()
const lightFolder = gui.addFolder('THREE.Light')
lightFolder.addColor(data, 'color').onChange(() => {light.color.setHex(Number(data.color.toString().replace('#', '0x')))
})
lightFolder.add(light, 'intensity', 0, 20, 0.01)
lightFolder.open()const directionalLightFolder = gui.addFolder('THREE.DirectionalLight')
directionalLightFolder.add(light.shadow.camera, 'left', -500, 1, 1).onChange(() => light.shadow.camera.updateProjectionMatrix())
directionalLightFolder.add(light.shadow.camera, 'right', 1, 500, 1).onChange(() => light.shadow.camera.updateProjectionMatrix())
directionalLightFolder.add(light.shadow.camera, 'top', 1, 500, 1).onChange(() => light.shadow.camera.updateProjectionMatrix())
directionalLightFolder.add(light.shadow.camera, 'bottom', -500, -1, 1).onChange(() => light.shadow.camera.updateProjectionMatrix())
directionalLightFolder.add(light.shadow.camera, 'near', 0.1, 500).onChange(() => light.shadow.camera.updateProjectionMatrix())
directionalLightFolder.add(light.shadow.camera, 'far', 0.1, 500).onChange(() => light.shadow.camera.updateProjectionMatrix())
directionalLightFolder.add(data, 'shadowMapSizeWidth', [256, 512, 1024, 2048, 4096]).onChange(() => updateShadowMapSize())
directionalLightFolder.add(data, 'shadowMapSizeHeight', [256, 512, 1024, 2048, 4096]).onChange(() => updateShadowMapSize())
directionalLightFolder.add(light.position, 'x', -50, 50, 0.01)
directionalLightFolder.add(light.position, 'y', -50, 50, 0.01)
directionalLightFolder.add(light.position, 'z', -50, 50, 0.01)
directionalLightFolder.open()function updateShadowMapSize() {light.shadow.mapSize.width = data.shadowMapSizeWidthlight.shadow.mapSize.height = data.shadowMapSizeHeight;(light.shadow.map as any) = null
}function animate() {requestAnimationFrame(animate)controls.update()TWEEN.update()//helper.update()render()stats.update()
}function render() {renderer.render(scene, camera)
}animate()

2、效果

 

相关文章:

Three的lod技术

1、资源&#xff1a;https://sbcode.net/threejs/lod/ import * as THREE from three import { OrbitControls } from three/examples/jsm/controls/OrbitControls import Stats from three/examples/jsm/libs/stats.module import { GUI } from dat.gui import { GLTFLoader }…...

Git配置

个人主页&#xff1a;Lei宝啊 愿所有美好如期而遇 前言 前面我们新建了远程仓库并且在Linux上克隆了远程仓库&#xff0c;但是在新建仓库时我们提到会配置gitignore文件&#xff0c;这次我们将会配置他&#xff0c;并给命令起别名。 目录 前言 忽略特殊文件 给命令起别名…...

阻抗控制下机器人接触刚性环境振荡不稳定进行阻抗调节

阻抗接触 刚性环境为ke10000 虚拟阻抗为&#xff1a;kd100&#xff0c;bd10&#xff0c;md1 虚拟阻抗为&#xff1a;kd100&#xff0c;bd10&#xff0c;md5 虚拟阻抗为&#xff1a;kd100&#xff0c;bd10&#xff0c;md10 性能滤波函数的Bode图&#xff1a; bode(1e5/(0.000…...

【鸿蒙应用ArkTS开发系列】-自定义底部菜单列表弹窗

文章目录 前言创建Demo工程创建dialog 文件夹创建ListMenu 接口创建自定义弹窗 ListMenuDialog使用自定义弹窗 打包测试效果演示默认效果菜单带图标效果设置文本颜色效果不同文本颜色效果无标题效果 前言 上一篇文章中我们实现了选择图片、选择文件、拍照的功能 。 链接在这里…...

yolov8添加ca注意力机制

创建文件 coordAtt.py 位置&#xff1a;ultralytics/nn/modules/coordAtt.py ###################### CoordAtt #### start by AI&CV ############################### # https://zhuanlan.zhihu.com/p/655475515 import torch import torch.nn as nn import t…...

linux java后台启动的几种方式

1.使用 nohup 命令 可以使用 nohup 命令启动 Java 应用程序&#xff0c;使其在后台运行&#xff0c;这样即使退出终端或关闭 SSH 连接&#xff0c;Java 应用程序也能继续运行。nohup java -jar myapp.jar &2.使用 & 符号 使用 & 符号可以将 Java 应用程序放到后台…...

selinux-policy-default(2:2.20231119-2)软件包内容详细介绍(5)

接前一篇文章:selinux-policy-default(2:2.20231119-2)软件包内容详细介绍(4) 4. 重点文件内容解析 (1)control/postist文件 上一回解析了control/postinst文件的部分内容,本回继续往下解析。为了便于理解,再次贴出postinst完整代码: #!/bin/sh set -e# summary o…...

代码随想录二刷 |栈与队列 |理论基础

代码随想录二刷 &#xff5c;栈与队列 &#xff5c;理论基础 栈常用操作 队列常用操作 栈与队列是C标准库中的两个数据结构。 栈 栈先进后出&#xff0c;提供 push 和 pop 等接口&#xff0c;所有元素必须符合先进后出的原则&#xff0c;所以栈不提供走访功能&#xff0c;也不…...

java--接口概述

1.认识接口 ①java提供了一个关键字interface&#xff0c;用这个关键字我们可以定义出一个特殊的结构&#xff1a;接口。 ②注意&#xff1a;接口不能创建对象&#xff1b;接口是用来被类实现(implements)的&#xff0c;实现接口的类称为实现类。 ③一个类可以实现多个接口(接…...

出海风潮:中国母婴品牌征服国际市场的机遇与挑战!

近年来&#xff0c;中国母婴品牌在国内市场蓬勃发展的同时&#xff0c;也逐渐将目光投向国际市场。这一趋势不仅受益于中国经济的崛起&#xff0c;还得益于全球市场对高质量母婴产品的不断需求。然而&#xff0c;面对国际市场的机遇&#xff0c;中国母婴品牌同样面临着一系列挑…...

一文读懂MongoDB的知识点(3),惊呆面试官。

&#x1f3c6;作者简介&#xff0c;普修罗双战士&#xff0c;一直追求不断学习和成长&#xff0c;在技术的道路上持续探索和实践。 &#x1f3c6;多年互联网行业从业经验&#xff0c;历任核心研发工程师&#xff0c;项目技术负责人。 &#x1f389;欢迎 &#x1f44d;点赞✍评论…...

ssm的“魅力”西安宣传网站(有报告)。Javaee项目。

演示视频&#xff1a; ssm的“魅力”西安宣传网站(有报告)。Javaee项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构&#xff0c;通过Spring SpringMvc MybatisVueLayuiElemen…...

怎么让SecureCRT不自动断开连接

SecureCRT 是一个常用的远程连接工具&#xff0c;它可能会因为会话超时或者其他设置而自动断开连接。要防止 SecureCRT 自动断开连接&#xff0c;你可以尝试以下方法&#xff1a; 1. 更改会话选项&#xff1a; 打开 SecureCRT 并连接到你的远程主机后&#xff0c;依次执行以下…...

介绍几种Go语言开发的IDE

文章目录 1.前言2.几种ide2.1 Goland2.2 VsCode示例 2.3 LiteIDE2.4 Eclipse插件GoClipse2.5 Atom2.6 Vim2.7 Sublime Text 3.总结写在最后 1.前言 Go语言作为一种新兴的编程语言&#xff0c;近年来受到了越来越多的关注。 它以其简洁、高效和并发性能而闻名&#xff0c;被广…...

1、设计模式简介(7大原则,3大类)

设计模式有7个原则&#xff1a;单一职责原则、开闭原则、里氏代换原则、依赖倒转原则、接口隔离原则、合成/聚合复用原则、迪米特法则 1&#xff0e;单一职责原则 单一职责原则又称单一功能原则&#xff0c;它规定一个类只有一个职责。如果有多个职责&#xff08;功能&#x…...

华为鲲鹏+银河麒麟V10编译FreeSWITCH1.10.9

# uname -r 4.19.90-17.5.ky10.aarch64 本想编译FreeSWITCH1.10.7&#xff0c;但碰到点问题&#xff0c;后来改1.10.9&#xff0c;相对比较顺利&#xff0c;记录如下&#xff1a; 先安装工具/开发库等&#xff1a; yum install -y git yum install -y wget yum install -y au…...

CFS三层靶机内网渗透

CFS三层靶机内网渗透 一、靶场搭建1.基础参数信息2.靶场搭建2.1网卡配置2.2Target1配置2.2.1 网卡配置2.2.2 Target1 BT配置 2.3Target2配置2.3.1 网卡配置2.3.2 Target2 BT配置 2.4Target3配置 二、内网渗透Target11.1信息收集1.1.1IP收集1.1.2端口收集1.1.3目录收集 1.2 webs…...

软件分享--智能照片识别分类软件

智能照片识别分类软件&#xff0c;批量识别图片并分类 自动识别照片类型&#xff0c;分为10个类别&#xff1a;车辆、动物、风景、花卉、建筑、街景、美食、人像、夜景、植物、其它 分类准确率90% 本地运行、不需要联网、没有网络也能用、没有注册码、永久使用 如果你拍摄了上…...

Leetcode—409.最长回文串【简单】

2023每日刷题&#xff08;四十八&#xff09; Leetcode—409.最长回文串 强烈吐槽&#xff01;&#xff01;&#xff01; 非常不理解&#xff0c;同样的代码&#xff0c;为什么C跑不了C就跑得了&#xff0c;力扣编译器是对C语言有歧视吗&#xff1f;&#xff1f;&#xff1f;…...

计算机网络入侵检测技术研究

摘 要 随着网络技术的发展&#xff0c;全球信息化的步伐越来越快&#xff0c;网络信息系统己成为一个单位、一个部门、一个行业&#xff0c;甚至成为一个关乎国家国计民生的基础设施&#xff0c;团此&#xff0c;网络安全就成为国防安全的重要组成部分&#xff0c;入侵检测技术…...

BilibiliDown:让音乐爱好者实现Hi-Res音频提取的全流程方案

BilibiliDown&#xff1a;让音乐爱好者实现Hi-Res音频提取的全流程方案 【免费下载链接】BilibiliDown (GUI-多平台支持) B站 哔哩哔哩 视频下载器。支持稍后再看、收藏夹、UP主视频批量下载|Bilibili Video Downloader &#x1f633; 项目地址: https://gitcode.com/gh_mirr…...

解决Windows远程桌面连接Ubuntu时xrdp闪退的配置技巧

1. 问题现象与排查思路 最近在帮同事配置Windows远程连接Ubuntu时遇到了一个典型问题&#xff1a;用Windows自带的远程桌面连接工具输入账号密码后&#xff0c;界面闪退无法进入桌面。这种情况在Ubuntu 18.04/20.04/22.04各版本中都可能出现&#xff0c;特别是使用GNOME桌面环…...

Chord实战效果:一段30秒视频的深度解析,展示其视觉定位与描述能力

Chord实战效果&#xff1a;一段30秒视频的深度解析&#xff0c;展示其视觉定位与描述能力 1. 引言&#xff1a;为什么选择这段30秒视频 今天我要带大家近距离观察Chord视频理解工具的实际表现。不同于传统的技术参数罗列&#xff0c;我们将通过一段精心挑选的30秒视频&#x…...

解决Qt中使用qmqtt连接ONENet MQTT服务端的版本兼容性问题

1. 问题背景&#xff1a;当qmqtt遇上ONENet 最近在做一个物联网项目&#xff0c;需要用Qt开发一个MQTT客户端连接ONENet平台。按照官方文档&#xff0c;我选择了emqx/qmqtt这个第三方库&#xff0c;结果连接时直接报错。代码明明照着示例写的&#xff0c;参数也都检查过&#x…...

双冗余链路实现(2/2期)

目录 拓扑&#xff1a; 基础需求&#xff1a; 出口路由器&#xff08;双路&#xff09;&#xff1a; 静态路由&#xff1a; 防火墙配置&#xff1a; 全区域互通透传&#xff1a; 静态路由&#xff1a; 冗余备份&#xff1a; 核心交换机&#xff1a; 静态路由&#xff…...

网络异常排查:快速定位域连接问题

问题描述与初步排查网络位置异常通常表现为计算机无法正确识别当前所在的AD域环境&#xff0c;导致访问域资源受限或登录问题。常见症状包括系统托盘显示“无法访问域”、组策略无法应用、DNS解析失败等。检查计算机是否能够ping通域控制器的主机名和IP地址。使用nslookup命令验…...

Stable Yogi Leather-Dress-Collection 一键部署教程:基于Ubuntu的快速环境搭建

Stable Yogi Leather-Dress-Collection 一键部署教程&#xff1a;基于Ubuntu的快速环境搭建 最近在折腾AI图像生成&#xff0c;发现了一个挺有意思的模型叫Stable Yogi Leather-Dress-Collection。听名字就知道&#xff0c;它特别擅长生成皮革、连衣裙这类时尚单品的设计图。对…...

无线音频桥接实战指南:让传统音响实现跨设备兼容的完整方案

无线音频桥接实战指南&#xff1a;让传统音响实现跨设备兼容的完整方案 【免费下载链接】AirConnect Use AirPlay to stream to UPnP/Sonos & Chromecast devices 项目地址: https://gitcode.com/gh_mirrors/ai/AirConnect &#x1f3b6; 从"音响孤岛"到&…...

Vivado+Vitis双剑合璧:从零构建Zynq-7020的SD卡Linux系统启动镜像

VivadoVitis双剑合璧&#xff1a;从零构建Zynq-7020的SD卡Linux系统启动镜像 在嵌入式系统开发领域&#xff0c;Xilinx Zynq系列SoC凭借其独特的ARM处理器与FPGA可编程逻辑的完美结合&#xff0c;成为众多高性能嵌入式应用的理想选择。本文将带领开发者深入探索如何利用Vivado和…...

如何10分钟快速上手:语音转换工具完全指南

如何10分钟快速上手&#xff1a;语音转换工具完全指南 【免费下载链接】Retrieval-based-Voice-Conversion-WebUI 语音数据小于等于10分钟也可以用来训练一个优秀的变声模型&#xff01; 项目地址: https://gitcode.com/GitHub_Trending/re/Retrieval-based-Voice-Conversion…...