当前位置: 首页 > 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;入侵检测技术…...

黑马Mybatis

Mybatis 表现层&#xff1a;页面展示 业务层&#xff1a;逻辑处理 持久层&#xff1a;持久数据化保存 在这里插入图片描述 Mybatis快速入门 ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/6501c2109c4442118ceb6014725e48e4.png //logback.xml <?xml ver…...

React第五十七节 Router中RouterProvider使用详解及注意事项

前言 在 React Router v6.4 中&#xff0c;RouterProvider 是一个核心组件&#xff0c;用于提供基于数据路由&#xff08;data routers&#xff09;的新型路由方案。 它替代了传统的 <BrowserRouter>&#xff0c;支持更强大的数据加载和操作功能&#xff08;如 loader 和…...

Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例

使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件&#xff0c;常用于在两个集合之间进行数据转移&#xff0c;如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model&#xff1a;绑定右侧列表的值&…...

蓝牙 BLE 扫描面试题大全(2):进阶面试题与实战演练

前文覆盖了 BLE 扫描的基础概念与经典问题蓝牙 BLE 扫描面试题大全(1)&#xff1a;从基础到实战的深度解析-CSDN博客&#xff0c;但实际面试中&#xff0c;企业更关注候选人对复杂场景的应对能力&#xff08;如多设备并发扫描、低功耗与高发现率的平衡&#xff09;和前沿技术的…...

spring:实例工厂方法获取bean

spring处理使用静态工厂方法获取bean实例&#xff0c;也可以通过实例工厂方法获取bean实例。 实例工厂方法步骤如下&#xff1a; 定义实例工厂类&#xff08;Java代码&#xff09;&#xff0c;定义实例工厂&#xff08;xml&#xff09;&#xff0c;定义调用实例工厂&#xff…...

从零实现STL哈希容器:unordered_map/unordered_set封装详解

本篇文章是对C学习的STL哈希容器自主实现部分的学习分享 希望也能为你带来些帮助~ 那咱们废话不多说&#xff0c;直接开始吧&#xff01; 一、源码结构分析 1. SGISTL30实现剖析 // hash_set核心结构 template <class Value, class HashFcn, ...> class hash_set {ty…...

OPENCV形态学基础之二腐蚀

一.腐蚀的原理 (图1) 数学表达式&#xff1a;dst(x,y) erode(src(x,y)) min(x,y)src(xx,yy) 腐蚀也是图像形态学的基本功能之一&#xff0c;腐蚀跟膨胀属于反向操作&#xff0c;膨胀是把图像图像变大&#xff0c;而腐蚀就是把图像变小。腐蚀后的图像变小变暗淡。 腐蚀…...

动态 Web 开发技术入门篇

一、HTTP 协议核心 1.1 HTTP 基础 协议全称 &#xff1a;HyperText Transfer Protocol&#xff08;超文本传输协议&#xff09; 默认端口 &#xff1a;HTTP 使用 80 端口&#xff0c;HTTPS 使用 443 端口。 请求方法 &#xff1a; GET &#xff1a;用于获取资源&#xff0c;…...

C# 表达式和运算符(求值顺序)

求值顺序 表达式可以由许多嵌套的子表达式构成。子表达式的求值顺序可以使表达式的最终值发生 变化。 例如&#xff0c;已知表达式3*52&#xff0c;依照子表达式的求值顺序&#xff0c;有两种可能的结果&#xff0c;如图9-3所示。 如果乘法先执行&#xff0c;结果是17。如果5…...

[大语言模型]在个人电脑上部署ollama 并进行管理,最后配置AI程序开发助手.

ollama官网: 下载 https://ollama.com/ 安装 查看可以使用的模型 https://ollama.com/search 例如 https://ollama.com/library/deepseek-r1/tags # deepseek-r1:7bollama pull deepseek-r1:7b改token数量为409622 16384 ollama命令说明 ollama serve #&#xff1a…...