【Three.js】Layers图层的使用

目录

前言

创建图层对象

启用图层

关闭图层

其他


前言

Layers 对象为Object3D对象分配了1-32个图层,编号为0-31。在内部实现上,每个图层对象被存储为一个bit mask, 默认所有 Object3D 对象都存储在第 0 个图层上

图层对象可以用于控制对象的显示,和相机处于同一个图层的物体才可以被显示出来。

每个继承自 Object3D 的对象都有一个 Object3D.layers 对象。Mesh、Camera、Group等都继承自基类 Object3D,所以它们都有一个 layers 属性。

创建图层对象

通过构造函数 Layers() 可以创建一个新的图层对象,该对象默认与第 0 图层关联。

每个图层都被存储为一个32位的BitMask(掩码),启用了哪个图层,哪个位置的比特位就为1,其余为0。可以同时启用多个图层。

  const layers = new THREE.Layers()console.log(`默认图层0, mask值为: ${layers.mask} ---> 对应二进制:${layers.mask.toString(2)}`)for (let i = 0; i < 10; ++i) {layers.set(i)console.log(`layers.set(${i}) -> layers.mask: ${layers.mask} ---> 对应二进制:${layers.mask.toString(2)}`)}layers.set(0)layers.enableAll()console.log(`layers.enableAll() -> layers.mask: ${layers.mask} ---> 对应二进制:${layers.mask.toString(2)}`)layers.disableAll()console.log(`layers.disableAll() -> layers.mask: ${layers.mask} ---> 对应二进制:${layers.mask.toString(2)}`)layers.enable(2)console.log(`layers.enable(2) -> layers.mask: ${layers.mask} ---> 对应二进制:${layers.mask.toString(2)}`)layers.disable(2)console.log(`layers.disable(2) -> layers.mask: ${layers.mask} ---> 对应二进制:${layers.mask.toString(2)}`)for (let i = 0; i < 3; ++i) {layers.toggle(i)console.log(`layers.toggle(${i}) -> layers.mask: ${layers.mask} ---> 对应二进制:${layers.mask.toString(2)}`)}

打印结果:

启用图层

.enable(layerNum) 增加一个layerNum图层的显示

.set(layerNum) 删除原来设置的图层,启用layerNum图层

.toggle(layerNum) 切换图层,开启或关闭layerNum图层

.enableAll() 启用全部图层

<template><div class="app"><div id="three"></div><div class="btns"><button @click="setLayer(0)">layers.set(0)</button><button @click="setLayer(1)">layers.set(1)</button><button @click="setLayer(2)">layers.set(2)</button><br><button @click="enableLayer(0)">layers.enable(0)</button><button @click="enableLayer(1)">layers.enable(1)</button><button @click="enableLayer(2)">layers.enable(2)</button><br><button @click="toggleLayer(0)">layers.toggle(0)</button><button @click="toggleLayer(1)">layers.toggle(1)</button><button @click="toggleLayer(2)">layers.toggle(2)</button><br><button @click="enableAll">layers.enableAll()</button><button @click="reset">重置</button></div></div>
</template><script setup>
import { onMounted, ref } from 'vue'
import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'const camera = ref(null)
onMounted(() => {const threeContainer = document.getElementById('three')// 创建场景const scene = new THREE.Scene()// 创建相机camera.value = new THREE.PerspectiveCamera( 75, threeContainer.offsetWidth / threeContainer.offsetHeight, 0.1, 1000 )// const camera = new THREE.OrthographicCamera(//   -5*threeContainer?.offsetWidth / threeContainer?.offsetHeight, //   5*threeContainer?.offsetWidth / threeContainer?.offsetHeight, //   5, -5, //   0.1, //   1000 // ) //正交视角// 设置相机位置camera.value.position.set(0, 0, 10)// 将相机添加到场景中scene.add(camera.value)// 创建渲染器const renderer = new THREE.WebGLRenderer({antialias: true //开启抗锯齿})// 设置渲染的尺寸和大小renderer.setSize(threeContainer.offsetWidth, threeContainer.offsetHeight)// 将webgl渲染的canvas内容添加到DOM容器threeContainer.appendChild(renderer.domElement)/*创建几何体*/ const cubeGeometry = new THREE.BoxGeometry(1, 1, 1) //几何体对象const cubeMaterial = new THREE.MeshBasicMaterial({ color: 0xffff00 }) //材质const cube = new THREE.Mesh(cubeGeometry, cubeMaterial) //根据几何体和材质创建物体// 将几何体添加到场景当中scene.add(cube)cube.layers.set(0)const cubeGeometry1 = new THREE.BoxGeometry(1, 1, 1) //几何体对象const cubeMaterial1 = new THREE.MeshBasicMaterial({ color: 'hotpink' }) //材质const cube1 = new THREE.Mesh(cubeGeometry1, cubeMaterial1) //根据几何体和材质创建物体// 将几何体添加到场景当中scene.add(cube1)cube1.position.set(1,0,0)cube1.layers.set(1)const cubeGeometry2 = new THREE.BoxGeometry(1, 1, 1) //几何体对象const cubeMaterial2 = new THREE.MeshBasicMaterial({ color: 'skyblue' }) //材质const cube2 = new THREE.Mesh(cubeGeometry2, cubeMaterial2) //根据几何体和材质创建物体// 将几何体添加到场景当中scene.add(cube2)cube2.position.set(2,0,0)cube2.layers.set(2)// 添加坐标轴辅助器const axesHelper = new THREE.AxesHelper(5)scene.add(axesHelper)axesHelper.layers.enableAll()// 轨道控制器const controls  = new OrbitControls(camera.value, renderer.domElement)// 循环渲染function animate() {requestAnimationFrame(animate)renderer.render(scene, camera.value)controls.update()}animate()window.addEventListener("resize", () => {// 更新摄像头camera.value.aspect = threeContainer.offsetWidth / threeContainer.offsetHeight//   更新摄像机的投影矩阵camera.value.updateProjectionMatrix()//   更新渲染器renderer.setSize(threeContainer.offsetWidth, threeContainer.offsetHeight)//   设置渲染器的像素比renderer.setPixelRatio(threeContainer.devicePixelRatio)})
})const setLayer = (num) => {camera.value.layers.set(num)
}
const enableLayer = (num) => {camera.value.layers.enable(num)
}
const toggleLayer = (num) => {camera.value.layers.toggle(num)
}
const enableAll = () => {camera.value.layers.enableAll()
}
const reset = () => {camera.value.layers.disableAll()camera.value.layers.set(0)
}
</script><style lang="scss" scoped>
.app{width: 100vw;height: 100vh;position: relative;#three{width: 100%;height: 100%;background-color: skyblue;}.btns{position: absolute;top: 10px;right: 20px;button{cursor: pointer;margin-right: 10px;margin-top: 10px;}}
}
</style>

上述代码设置三个物体的图层分别为0、1、2,然后通过控制相机所在图层来控制物体显示和隐藏。 

关闭图层

.disable(layerNum) 删除layerNum图层

.disableAll() 关闭所有图层

    <div class="btns"><button @click="enableAll">layers.enableAll()</button><br><button @click="hideLayer(0)">layers.disable(0)</button><button @click="hideLayer(1)">layers.disable(1)</button><button @click="hideLayer(2)">layers.disable(2)</button><br><button @click="disableAll">layers.disableAll()</button></div>
const enableAll = () => {camera.value.layers.enableAll()
}
const hideLayer = (num) => {camera.value.layers.disable(num)
}
const disableAll = () => {camera.value.layers.disableAll()
}

其他

.test(layers) 如果传入图层对象与当前对象属于相同的一组图层,则返回 true,否则返回 false。 

.isEnabled(layerNum) 如果layerNum层已启用,则返回true。

console.log('cube&&camera', cube.layers.test(camera.value.layers));
console.log('cube1&&camera', cube1.layers.test(camera.value.layers));
console.log('cube2&&camera', cube2.layers.test(camera.value.layers));/*
打印结果:
cube&&camera true
cube1&&camera false
cube2&&camera false
*/
const enableAll = () => {camera.value.layers.enableAll()console.log(camera.value.layers.isEnabled(0),camera.value.layers.isEnabled(1),camera.value.layers.isEnabled(2),camera.value.layers.isEnabled(3),camera.value.layers.isEnabled(31)); //true true true true true 
}

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

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

相关文章

美国将限制中国,使用Azure、AWS等云,训练AI大模型

1月29日&#xff0c;美国商务部在Federal Register&#xff08;联邦公报&#xff09;正式公布了&#xff0c;《采取额外措施应对与重大恶意网络行为相关的国家紧急状态》提案。 该提案明确要求美国IaaS&#xff08;云服务&#xff09;厂商在提供云服务时&#xff0c;要验证外国…

深度强化学习(王树森)笔记09

深度强化学习&#xff08;DRL&#xff09; 本文是学习笔记&#xff0c;如有侵权&#xff0c;请联系删除。本文在ChatGPT辅助下完成。 参考链接 Deep Reinforcement Learning官方链接&#xff1a;https://github.com/wangshusen/DRL 源代码链接&#xff1a;https://github.c…

【数据结构:顺序表】

文章目录 线性表顺序表1.1 顺序表结构的定义1.2 初始化顺序表1.3 检查顺序表空间1.4 打印1.5 尾插1.6 头插1.7 尾删1.8 头删1.9 查找1.10 指定位置插入1.11 删除指定位置数据1.12 销毁顺序表 数据结构(Data Structure)是计算机存储、组织数据的方式&#xff0c;指相互之间存在一…

2024Cypress自动化测试开发指南!

cypress是基于JavaScript语言为编写语言的自动化测试开发工具&#xff0c;配合使用cucumber测试开发框架&#xff0c;以node.js为服务进程&#xff0c;可以简单的帮助测试人员完成需要人工手点的所有页面人机交互操作&#xff0c;可以模拟键盘和鼠标输入&#xff0c;快捷完成ca…

使用串口WiFi透传模块需要解决的几个问题,2串口双串口,3串口多串口转WiFi模块S2W-M02

我们知道在现在物联网时代&#xff0c;串口设备通过WiFi联网上传数据已经有很多的场景需求。但是&#xff0c;现在市面上的大部分串口转WiFi模块都仅仅支持一个串口的数据透传应用。 如果串口转WiFi模块仅仅有一个串口资源进行透传&#xff0c;那么它的应用场景是如下的&#x…

问卷发放实战指南:提高问卷回收率与数据质量的技巧

进行问卷调查分为四步&#xff1a;制作问卷、发放问卷、收集问卷、分析问卷。其中&#xff0c;发放问卷起到了关键性的作用。他关乎到我们后续收集问卷是否顺利&#xff0c;收集到的问卷数据是否具备真实性和有效性。那么&#xff0c;怎么有效地进行问卷发放呢&#xff1f; ​…

【C项目】顺序表

简介&#xff1a;本系列博客为C项目系列内容&#xff0c;通过代码来具体实现某个经典简单项目 适宜人群&#xff1a;已大体了解C语法同学 作者留言&#xff1a;本博客相关内容如需转载请注明出处&#xff0c;本人学疏才浅&#xff0c;难免存在些许错误&#xff0c;望留言指正 作…

网络战新高度!俄罗斯280台服务器被摧毁,200万GB数据丢失

Hackread网站消息&#xff0c;乌克兰国防部主要情报总局&#xff08;HUR&#xff09;的网络安全专家宣称对俄罗斯IPL咨询公司发起了一次成功的网络攻击&#xff0c;摧毁了该公司所有的IT基础设施&#xff0c;导致全国通信中断。 乌克兰HUR在Facebook上的发布公告表示&#xff0…

nginx负载均衡案例

大家好今天给大家带来nginx负载均衡实验案例,首大家先看一下我的各类版本信息。&#xff08;还有两台设备信息相同就不展示了&#xff09; 一&#xff0c;搭建nginx环境 ❶首先创建Nginx的目录并进入&#xff1a; [rootlocalhost]# mkdir /soft && mkdir /soft/nginx…

电气自动化行业,全面数字化工作流程

电气自动化行业数字化转型所需流程软件&#xff0c;与大家分享如下&#xff1a; D-Hub企业数字化协同平台、SuperHarness数字线束软件、SuperPanel母排设计软件、D-Hub生产管理系统&#xff0c;全面的数字化工作流程&#xff0c;智能降本增效&#xff01; D-Hub D-Hub是一款…

解决网站 “debugger“ 阻止调试

某些网站耍小聪明 以为在网站内 添加了 debugger 就能阻止别人对网站进行调试&#xff01; 针对某些网站 当你浏览器打开F12 后 你发现无论你怎么执行下一步 你始终停留在 debugger 这个代码文件内现在的问题是 每当我执行 下一步调试 时 都会被 “(function(){setInterval(f…

洗地机怎么选?洗地机选购必看

如今&#xff0c;洗地机已经成为了我们地板清洁的主力军了&#xff0c;但市场上的产品繁多让人眼花缭乱&#xff0c;不少朋友做了半天功课&#xff0c;还是不明白到底哪款产品适合自己。所以今天笔者给大家带来了满满的洗地机选购干货&#xff0c;还给大家附赠了选购清单&#…

AI创作之旅:探索提示工程的奇妙世界

目录 推荐 1. 引言 2. 什么是提示工程&#xff1f; 3. 准备工作 3.1 安装必要的库 3.2 获取 OpenAI API 密钥 4 设置 OpenAI API 密钥 5. 提示工程实战 6. 探索更多可能性 6.1 尝试不同的提示 6.2 调整参数 结语 ⭐️ 好书推荐 推荐 前些天发现了一个巨牛的人工智…

软件物料清单管理 | 打开“应用软件盲盒”,预警“开源组件风险”

更多网络安全干货内容&#xff1a;点此获取 ——————— 01 开源组件安全风险管控难 随着软件规模化发展和开源软件的兴起&#xff0c;越来越多的软件在开发过程中集成第三方组件或开源组件&#xff0c;这极大地提高了开发效率&#xff0c;但也难以避免地引入了安全风险。…

在RunnerGo测试平台中做WebSocket、Dubbo、TCP/IP接口测试

大家好&#xff0c;RunnerGo作为一款一站式测试平台不断为用户提供更好的使用体验&#xff0c;最近得知RunnerGo新增对&#xff0c;WebSocket、Dubbo、TCP/IP&#xff0c;三种协议API的测试支持&#xff0c;本篇文章跟大家分享一下使用方法。 WebSocket协议 WebSocket 是一种…

SpringBoot整合EasyCaptcha图形验证码

简介 EasyCaptcha&#xff1a;https://github.com/ele-admin/EasyCaptcha Java图形验证码&#xff0c;支持gif、中文、算术等类型&#xff0c;可用于Java Web、JavaSE等项目。 添加依赖 <dependency><groupId>com.github.whvcse</groupId><artifactId…

从公有云对象存储迁移到回私有化 MinIO需要了解的所有信息

我们上一篇文章《如何从 AWS S3 遣返到 MinIO》的反响非常出色 - 我们已经接到了数十个企业的电话&#xff0c;要求我们提供遣返建议。我们已将这些回复汇总到这篇新文章中&#xff0c;其中我们更深入地研究了与遣返相关的成本和节省&#xff0c;以便您更轻松地进行自己的分析。…

【MyBatis】快速入门MyBatis(保姆式教学),你值得一看

文章目录 &#x1f4c4;前言一. Mybatis简介✈️1. 什么是Mybatis&#x1f680;2. 为什么使用Mybatis 二. Mybatis快速入门&#x1f346;1. mybatis使用前准备1.1 创建springboot项目并引入相关依赖1.2 在 application.ym中进行数据源的配置1.3 创建数据表&#xff0c;准备表数…

Walrus 0.5发布:重构交互流程,打造开箱即用的部署体验

开源应用管理平台 Walrus 0.5 已于近日正式发布&#xff01; Walrus 0.4 引入了全新应用模型&#xff0c;极大程度减少了重复的配置工作&#xff0c;并为研发团队屏蔽了云原生及基础设施的复杂度。Walrus 0.5 在这一基础上&#xff0c;通过重构交互流程、增强抽象能力&#xff…

C++中 this指针、构造函数、析构函数

1.this指针 我们定义一个日期类来举例子 对于上述类&#xff0c;有这样一个问题&#xff0c;Date类中有Init和Print这两个成员函数&#xff0c;函数体中没有关于不同对象的区分&#xff0c;那d1调用函数的时候&#xff0c;编译器是如和来确定d1而不是d2呢&#xff1f;C通过引入…