[three.js]搭建场景

背景

虽然一直在从事three.js方面的开发工作,但是都是在同事搭建好的场景下工作的。最近接手的任务让我可以从0到1搭建一个场景,顺便复习一下

搭建三维场景

<script lang="ts" setup>
import { ref, onMounted } from 'vue';                                      
import * as THREE from 'three';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader';
// 导入 DRACOLoader
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js';
import { KTX2Loader } from 'three/examples/jsm/loaders/KTX2Loader.js';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
import { CSS3DRenderer, CSS3DObject } from 'three/examples/jsm/renderers/CSS3DRenderer.js';onMounted(() => {createScene();
});let scene: any, camera: any, renderer: any, controls: any;                                               
let css3dRenderer: any;function createScene() {//场景scene = new THREE.Scene();//辅助观察的坐标系const axesHelper = new THREE.AxesHelper(100);scene.add(axesHelper);//光源设置const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8);directionalLight.position.set(100, 60, 50);scene.add(directionalLight);const ambient = new THREE.AmbientLight(0xffffff, 0.4);scene.add(ambient);//渲染器和相机let renderCanvas = document.getElementById('renderCanvas');const width = renderCanvas.offsetWidth;const height = renderCanvas.offsetHeight; camera = new THREE.PerspectiveCamera(30, width / height, 1, 3000); // camera.position.set(292, 223, 185);camera.position.set(200, 250, 410); //根据渲染范围尺寸数量级设置相机位置// camera.lookAt(0, -23, 41);renderer = new THREE.WebGLRenderer();renderer.setSize(width, height);renderCanvas.appendChild(renderer.domElement);// 设置相机控件轨道控制器OrbitControlscontrols = new OrbitControls(camera, renderer.domElement);controls.target.set(0, -23, 41);// 加载模型const loader = new GLTFLoader();loader.setDRACOLoader(new DRACOLoader().setDecoderPath('/js/draco/')) .setKTX2Loader(new KTX2Loader().setTranscoderPath('/js/basis/').detectSupport(renderer as THREE.WebGLRenderer)); loader.load('./三维图.glb', (gltf: any) => { scene.add(gltf.scene);});// 加入文字标签const textLabel = tag3D('1组');css3dRenderer = labelRenderer(renderCanvas);scene.add(textLabel);render();
}// 渲染循环
function render() {renderer.render(scene, camera); //执行渲染操作css3dRenderer.render(scene, camera);controls.update();// console.log('camera.position: ', camera.position); // console.log('controls.target: ', controls.target); // mesh.rotateY(0.01); //每次绕y轴旋转0.01弧度requestAnimationFrame(render); //请求再次执行渲染函数render,渲染下一帧
}// 创建一个HTML标签
function tag3D(name) {// 创建div元素(作为标签)let div = document.createElement('div');div.innerHTML = name;div.classList.add('tag');//div元素包装为CSS3模型对象CSS3DObjectvar label = new CSS3DObject(div);div.style.pointerEvents = 'none'; //避免HTML标签遮挡三维场景的鼠标事件// 设置HTML元素标签在three.js世界坐标中位置label.position.set(0, 0, 50);//缩放CSS3DObject模型对象label.scale.set(0.04, 0.04, 0.04); //根据相机渲染范围控制HTML 3D标签尺寸// label.rotateY(Math.PI / 2); //控制HTML标签CSS3对象姿态角度label.rotateX(-Math.PI / 2);return label; //返回CSS3模型标签
}// 创建一个CSS2渲染器CSS2DRenderer
function labelRenderer(container) {var labelRenderer = new CSS3DRenderer();labelRenderer.setSize(container.offsetWidth, container.offsetHeight);labelRenderer.domElement.style.position = 'absolute';// 相对标签原位置位置偏移大小labelRenderer.domElement.style.top = '0px';labelRenderer.domElement.style.left = '0px';// //设置.pointerEvents=none,以免模型标签HTML元素遮挡鼠标选择场景模型labelRenderer.domElement.style.pointerEvents = 'none';container.appendChild(labelRenderer.domElement);return labelRenderer;
}
</script>
<template><div id="renderCanvas" class="renderCanvas"></div>
</template>

注意点

一定要有renderer.render(scene, camera);否则屏幕上啥也看不见;加了CSS3DRenderer,也要有相应的css3dRenderer.render(scene, camera);

如果有OrbitControls,相机就不用设置lookAt,直接设置OrbitControls的target就行了

GLTFLoader也不是上来就能load的,需要加上下面的东西才能load,原因我暂时也没弄清楚

loader.setDRACOLoader(new DRACOLoader().setDecoderPath('/js/draco/'))  .setKTX2Loader(new KTX2Loader().setTranscoderPath('/js/basis/').detectSupport(renderer as THREE.WebGLRenderer));

后记

刚学three.js的时候,按照教程也没遇到这么多问题,好久不写,问题一堆,感觉基础摇摇欲坠,所以特地记录一下

参考

参考1
参考2

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

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

相关文章

pycharm进入函数定义快捷键

在 PyCharm 中&#xff0c;你可以通过使用快捷键来快速进入函数&#xff0c;而不必通过鼠标点击。以下是几个常用的快捷键&#xff1a; 用鼠标选择函数后&#xff1a; Ctrl B&#xff1a;进入函数的定义。 Ctrl Alt B&#xff1a;进入函数的实现&#xff08;如果有的话&…

目标检测——摩托车头盔检测数据集

一、简介 首先&#xff0c;摩托车作为一种交通工具&#xff0c;具有高速、开放和稳定性差的特点&#xff0c;其事故发生率高&#xff0c;伤亡率排在机动车辆损伤的首位。因此&#xff0c;摩托车乘员头盔对于保护驾乘人员头部安全至关重要。在驾乘突发状况、人体受冲击时&#…

mysql 分组取前10条数据

mysql 分组取前10条数据 1.使用自定义函数 select name,gender,age,rankk from (selectname,gender,age,rankk:if(gengender,rankk1,1) as rankk,gen:gender from t_user,(select rankk:0,gen:null) temp order by gender,age asc) a where a.rankk < 10;2.使用row_nu…

#14vue3生成表单并跳转到外部地址的方式

1、背景 后端返回的json数据中包含一个json数组&#xff0c;此数组中是目标跳转地址所需要的form表单的数据。 2、跳转前的页面 const goto () > {finish.value true;request.post(/xxx/yyy,{zzz: zzz.value}).then(res > {const url res.data.submitUrlconst params…

拉电流、灌电流和漏电流

一、介绍 拉电流&#xff08;source current&#xff09;就是输出电流&#xff0c;即从芯片引脚向外流出的电流&#xff1b;灌电流&#xff08;sink current&#xff09;就是吸收电流&#xff0c;即从芯片引脚向内&#xff0c;流入芯片内的电流&#xff1b;漏电流就是泄露电流。…

在线安装MySQL5.7

在线安装MySQL 安装MySQL5.7 yum -y install mysql57-community-release-el7-10.noarch.rpm 若无可用安装包&#xff0c;执行下面这句 wget http://dev.mysql.com/get/mysql57-community-release-el7-7.noarch.rpm 本地安装 yum localinstall -y mysql57-community-releas…

python异常机制

当代码出现异常后底下代码都不会被执行了&#xff0c;也就是程序崩溃了。当然能避免异常的话尽量避免但是有的时候这个是没有办法避免的。 异常处理 &#xff08;注&#xff1a;异常处理是从上往下处理&#xff0c;所以编写代码时要注意&#xff09; 语法 try:可能出现异常…

【漏洞复现】锐捷 EWEB auth 远程命令执行漏洞

免责声明&#xff1a;文章来源互联网收集整理&#xff0c;请勿利用文章内的相关技术从事非法测试&#xff0c;由于传播、利用此文所提供的信息或者工具而造成的任何直接或者间接的后果及损失&#xff0c;均由使用者本人负责&#xff0c;所产生的一切不良后果与文章作者无关。该…

力扣面试经典150 —— 6-10题

力扣面试经典150题在 VScode 中安装 LeetCode 插件即可使用 VScode 刷题&#xff0c;安装 Debug LeetCode 插件可以免费 debug本文使用 python 语言解题&#xff0c;文中 “数组” 通常指 python 列表&#xff1b;文中 “指针” 通常指 python 列表索引 文章目录 6. [中等] 轮转…

MySQL基础-----约束

目录 前言 一、概述 二、约束演示 三、外键约束 1.介绍 2.语法 四、删除/更新行为 1.CASCADE 2.SET NULL 前言 本期我们开始MySQL约束的学习&#xff0c;约束一般是只数据键对本条数据的约束&#xff0c;通过约束我们可以保证数据库中数据的正确、有效性和完整性。 下面…

vite+vue3门户网站菜单栏动态路由控制

门户网站用户端需要分板块展示&#xff0c;板块内容由管理端配置&#xff0c;包括板块名称&#xff0c;访问路径&#xff0c;路由组件&#xff0c;展示顺序&#xff0c;是否展示。如下图所示&#xff1a; 用户访问门户网站时&#xff0c;展示菜单跳转通过板块配置&#xff0c;动…

#微信小程序(布局、渲染层基础知识)

1.IDE&#xff1a;微信开发者工具 2.实验&#xff1a; 3.记录: &#xff08;1&#xff09;view&#xff08;类似于div&#xff09; &#xff08;2&#xff09;块级元素不占满一行且水平均分布局flex,justify(space-around) &#xff08;3&#xff09;滚动<scroll view sc…

从破局到引领,小牛电动确立“领航者”地位

一代人有一代人的使命&#xff0c;一代名企也有一代名企的长征。 当下&#xff0c;高端智能两轮电动车正在跨越鸿沟进入到主流市场中&#xff0c;其中&#xff0c;以小牛电动为代表的新势力正在经历由“颠覆者”到扮演“领航者”角色转型&#xff0c;引领市场顺势而上。 不破…

C++:string的介绍

C语言中&#xff0c;字符串是以\0结尾的一些字符的集合&#xff0c;为了操作方便&#xff0c;C标准库中提供了一些str系列的库函数&#xff0c;但是这些库函数与字符串是分离开的&#xff0c;不太符合面向对象的思想&#xff0c;而且底层空间需要用户自己管理&#xff0c;稍不留…

浅谈去耦电容的作用、选择、布局及其它电容的区别!

在一些文章资料中&#xff0c;去耦电容器被认为是旁路电容器。在其他资料中&#xff0c;去耦电容和旁路电容的区别在于&#xff1a;“旁路电容以输入信号中的干扰为滤波对象&#xff0c;而去耦电容以输出信号的干扰为滤波对象&#xff0c;防止干扰信号返回到输出端。”力量。”…

基于Java的生活废品回收系统(Vue.js+SpringBoot)

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、研究内容三、界面展示3.1 登录注册3.2 资源类型&资源品类模块3.3 回收机构模块3.4 资源求购/出售/交易单模块3.5 客服咨询模块 四、免责说明 一、摘要 1.1 项目介绍 生活废品回收系统是可持续发展的解决方案&#xff0c;旨在鼓…

如何远程访问电脑文件?

远程访问电脑文件是当今数字化时代中十分常见且实用的技术。它允许我们从任何地方的计算机或移动设备访问和操作我们的电脑中的文件。无论是远程工作、远程学习、远程协作还是方便地获得自己计算机上的重要文件&#xff0c;远程访问电脑文件都为我们提供了巨大的便利。 在远程访…

【C++】stack/queue

链表完了之后就是我们的栈和队列了&#xff0c;当然我们的STL中也有实现&#xff0c;下面我们先来看一下简单用法&#xff0c;跟我们之前C语言实现的一样&#xff0c;stack和queue有这么几个重要的成员函数 最主要的就是这么几个&#xff1a;empty&#xff0c;push&#xff0c;…

LeetCode-91题:解码方法(原创)

【题目描述】 一条包含字母 A-Z 的消息通过以下映射进行了 编码 &#xff1a; A -> "1" B -> "2" ... Z -> "26" 要 解码 已编码的消息&#xff0c;所有数字必须基于上述映射的方法&#xff0c;反向映射回字母&#xff08;可能有多种…

Nginx入门到精通

介绍 Nginx是一个高性能的Web服务器&#xff0c;它可以处理大量的并发请求&#xff0c;同时还可以作为负载均衡器和反向代理服务器。在本篇博文中&#xff0c;我们将介绍如何从入门到精通Nginx的使用。 Nginx的安装和配置 在开始使用Nginx之前&#xff0c;您需要先安装和配置…