ThreeJS-3D教学一:基础场景创建

news2024/11/24 23:12:16

Three.js 是一个开源的 JS 3D 图形库,用于创建和展示高性能、交互式的 3D 图形场景。它建立在 WebGL 技术之上,并提供了丰富的功能和工具,使开发者可以轻松地构建令人惊叹的 3D 可视化效果。

Three.js 提供了一套完整的工具和 API,用于创建和管理 3D 场景、几何体、纹理、光照、材质和相机等方面。它具有强大的渲染引擎,可以处理复杂的渲染任务,如阴影、透明度、反射和折射等效果。该库还支持动画、骨骼动画、粒子系统和物理模拟,可以实现流畅的动态效果和交互行为。它提供了丰富的控制器和用户交互工具,如旋转、缩放、平移和点击等操作。

Three.js 还支持加载和导入各种文件格式,如 OBJ、STL、FBX 和 glTF 等,以便使用外部工具创建和编辑 3D 模型。它还可以与音频、视频和其他 Web 技术进行集成,实现更丰富的应用场景。

接下来我们依次介绍three的三大件,渲染器(Renderer),场景(Scene),照相机(Camera),这三个展开说每一个都能单开一篇,这里简单介绍下概念,我们主要从案例中学习具体知识,感兴趣的朋友可以看这个链接Three.js学习,介绍的比较详细

渲染器(Renderer)

当我们在官方文档搜索WebGL时会显示七个类渲染器
WebGLMultipleRenderTargets
WebGLRenderer
WebGL1Renderer
WebGLRenderTarget
WebGL3DRenderTarget
WebGLArrayRenderTarget
WebGLCubeRenderTarget
暂时我们只聚焦于WebGLRenderer,其实真正经常用到的也是它。

WebGL1Renderer
three在 r118(包含此版本)后,自动使用WebGL 2 渲染上下文,如果您没有时间升级代码,但仍想使用最新版本,可以使用WebGL1Render。此版本的渲染器将强制执行WebGL 1渲染上下文。

WebGLRenderer
下面是一个基础的WebGLRenderer应用

 var renderer;
 var width,height;
 function initThree() {
	 width = document.getElementById("box").clientWidth;
	 height = document.getElementById("box").clientHeight;
	  // 生成渲染器对象(属性antialias:抗锯齿效果为设置有效)
	 renderer = new THREE.WebGLRenderer({
	 	antialias: true
	 });
	 renderer.setSize(width,height);
	 document.getElementById("box").appendChild(renderer.domElement);
	 // 设置canvas背景色(clearColor)和背景色透明度(clearAlpha)
	 renderer.setClearColor(0xFFFFFF, 1.0);
 }

场景(Scene)

three.js添加的模型都添加到了场景中,其初始化很简单

 var scene;
 function initScene(){
   scene = new THREE.Scene();
   // 场景的背景色
   scene.background = new THREE.Color( 0xf0f0f0 );
 }
 // 添加一个物体 mesh是什么后面会说明
 scene.add(mesh);

照相机(Camera)

你可以把相机想象为我们的眼睛,它决定了场景中哪个角度的景色会显示出来 ,就是我们所看到的,人站在不同位置,抬头或者低头都能够看到不同的景色 ,默认的照相机与加载进来的模型都处于坐标原点,为了能够看到模型,需要将照相机位置偏移。
经常用到相机分为:
CubeCamera

此相机适配 WebGLCubeRenderTarget

正交相机-OrthographicCamera

在此投影模式下,无论对象与摄影机的距离如何,其在渲染图像中的大小都保持不变。这对于渲染2D场景和UI元素等非常有用。

透视相机-PerspectiveCamera

这种投影模式是为了模仿人眼的视觉方式而设计的。它是用于渲染三维场景的最常见的投影模式。

我所有案例three版本是 three-155
先看效果图
在这里插入图片描述

上代码

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
  <style>
    body {
      width: 100%;
      height: 100%;
    }
    * {
      margin: 0;
      padding: 0;
    }
    .label {
      font-size: 20px;
      color: #fff;
      font-weight: 700;
    }
  </style>
</head>
<body>
<div id="container"></div>
<script type="importmap">
  {
    "imports": {
      "three": "../three-155/build/three.module.js",
      "three/addons/": "../three-155/examples/jsm/"
    }
  }
</script>
<script type="module">
import * as THREE from 'three';
import Stats from 'three/addons/libs/stats.module.js';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
import { CSS2DRenderer, CSS2DObject } from 'three/addons/renderers/CSS2DRenderer.js';
let stats, labelRenderer;
let camera, scene, renderer, mesh, target, controls;
const group = new THREE.Group();

init();
initHelp();
initLight();
axesHelperWord();
animate();

function init() {
  camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 10, 2000 );
  camera.position.set(0, 500, 500);
  camera.up.set(0, 1, 0);
  camera.lookAt(0, 0, 0);

  scene = new THREE.Scene();
  scene.background = new THREE.Color( '#ccc' );
  
  renderer = new THREE.WebGLRenderer( { antialias: true } );
  renderer.setPixelRatio( window.devicePixelRatio );
  renderer.setSize( window.innerWidth, window.innerHeight );
  document.body.appendChild( renderer.domElement );

  labelRenderer = new CSS2DRenderer();
  labelRenderer.setSize( window.innerWidth, window.innerHeight );
  labelRenderer.domElement.style.position = 'absolute';
  labelRenderer.domElement.style.top = '0px';
  labelRenderer.domElement.style.pointerEvents = 'none';
  document.getElementById( 'container' ).appendChild( labelRenderer.domElement );

  window.addEventListener( 'resize', onWindowResize );

  controls = new OrbitControls( camera, renderer.domElement );
  controls.minDistance = 10;
  controls.maxDistance = 1000;
  // 设置为true可启用阻尼(惯性),可用于为控件提供重量感。默认值为false。
  // 请注意,如果启用了此选项,则必须在动画循环中调用.update()。
  controls.enableDamping = false;
  controls.screenSpacePanning = false; // 定义平移时如何平移相机的位置 控制不上下移动

  stats = new Stats();
  stats.setMode(1); // 0: fps, 1: ms
  document.body.appendChild( stats.dom );
  scene.add( group );
}

function initLight() {
  const light = new THREE.DirectionalLight(new THREE.Color('rgb(253,253,253)'));
  light.position.set(100, 100, -10);
  light.intensity = 3; // 光线强度
  const AmbientLight = new THREE.AmbientLight(new THREE.Color('rgb(255,255,255)'));
  scene.add( light );
  scene.add( AmbientLight );
}

function initHelp() {
  const size = 1000;
  const divisions = 20;
  const gridHelper = new THREE.GridHelper( size, divisions );
  scene.add( gridHelper );

  // The X axis is red. The Y axis is green. The Z axis is blue.
  const axesHelper = new THREE.AxesHelper( 500 );
  scene.add( axesHelper );
}

function axesHelperWord() {
  let xP = addWord('X轴');
  let yP = addWord('Y轴');
  let zP = addWord('Z轴');
  xP.position.set(200, 0, 0);
  yP.position.set(0, 200, 0);
  zP.position.set(0, 0, 200);
}

function addWord(word) {
  let name = `<span>${word}</span>`;
  let moonDiv = document.createElement( 'div' );
  moonDiv.className = 'label';
  // moonDiv.textContent = 'Moon';
  // moonDiv.style.marginTop = '-1em';
  moonDiv.innerHTML = name;
  const label = new CSS2DObject( moonDiv );
  group.add( label );
  return label;
}

function onWindowResize() {
  camera.aspect = window.innerWidth / window.innerHeight;
  camera.updateProjectionMatrix();
  renderer.setSize( window.innerWidth, window.innerHeight );
}

function animate() {
  requestAnimationFrame( animate );
  stats.update();
  controls.update();
  labelRenderer.render( scene, camera );
  renderer.render( scene, camera );
}
</script>
</body>
</html>

这是一个简单的3D场景,除了之前介绍的三大件,renderer,camera、scene,
stats.js
左上角是一个 Three.js 开发的辅助库,主要用于检测动画运行时的帧数。
stats.setMode(1); // 0: fps, 1: ms
设置为 0:检测的是画面每秒传输帧数(fps)
设置为 1:检测的是画面渲染的时间

OrbitControls.js
动态观察控件允许摄影机围绕目标动态观察。

GridHelper
是一个用于定义网格的对象。网格是二维的线阵列。这也是个辅助工具,帮我们看清3D场景

AxesHelper
一个轴对象,以一种简单的方式显示3个轴。X轴为红色,Y轴为绿色。Z轴为蓝色。这也是个辅助工具,可以清晰的让我们在3D场景中看清方向也就是 X、Y、Z轴在哪

CSS2DRenderer
图中的文案用到了CSS2DRenderer,当然对应的还有CSS3DRenderer,这两者的主要区别就是CSS2DRenderer会永远面向相机,且大小不会随意相机移动而变化。非常适合辅助AxesHelper指明X、Y、Z轴

light
当然还有一个非常重要的光源,这里用到了DirectionalLight 和 AmbientLight,其实还有一些比如:PointLight、SpotLight、RectAreaLight后面我们会介绍到

AmbientLight
该灯光在全局范围内平等地照亮场景中的所有对象。
该灯光不能用于投射阴影,因为它没有方向。

DirectionalLight
向特定方向发射的光。这种光的行为就像它是无限遥远的,并且从它产生的光线都是平行的。这方面的常见用例是模拟日光;太阳离得足够远,它的位置可以被认为是无限的,所有来自它的光线都是平行的。
此灯光可以投射阴影
具体用法参数大家可以官网查看下three官网

大家会发现现在3D场景中,除了一些辅助方法,就没别的了,其实这就是我经常用到的标准模版,有了它当我们需要测试或者学习某些效果时,这个就可以直接拿来用,然后我们往里添加需要的效果即可,后面案例中我会一一介绍。

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

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

相关文章

DAMO-YOLO训练KITTI数据集

1.KITTI数据集准备 DAMO-YOLO支持COCO格式的数据集&#xff0c;在训练KITTI之前&#xff0c;需要将KITTI的标注转换为KITTI格式。KITTI的采取逐个文件标注的方式确定的&#xff0c;即一张图片对应一个label文件。下面是KITTI 3D目标检测训练集的第一个标注文件&#xff1a;000…

基于springboot的小说阅读网站设计与实现【附源码】

基于以下技术实现&#xff1a;springbootmybatisplusjsoupmysql 媛麻&#xff1a;可代xie lun文,ding制作网站 在这里插入图片描述

图像处理与计算机视觉--第四章-图像滤波与增强-第二部分

目录 1.图像噪声化处理与卷积平滑 2.图像傅里叶快速变换处理 3.图像腐蚀和膨胀处理 4 图像灰度调整处理 5.图像抖动处理算法 学习计算机视觉方向的几条经验: 1.学习计算机视觉一定不能操之过急&#xff0c;不然往往事倍功半&#xff01; 2.静下心来&#xff0c;理解每一个…

前后端分离的计算机毕设之基于springboot+vue的课程设计选题管理系统(内含源码+文档+教程)

博主介绍&#xff1a;✌全网粉丝10W,前互联网大厂软件研发、集结硕博英豪成立工作室。专注于计算机相关专业毕业设计项目实战6年之久&#xff0c;选择我们就是选择放心、选择安心毕业✌ &#x1f345;由于篇幅限制&#xff0c;想要获取完整文章或者源码&#xff0c;或者代做&am…

vue_Delete `␍`eslint(prettier/prettier)

Delete ␍eslint(prettier/prettier) 错误的解决方案 问题背景 在Windows笔记本上新拉完代码&#xff0c;在执行pre-commit时&#xff0c;出现如下错误&#xff1a; Delete ␍eslint(prettier/prettier)问题根源 罪魁祸首是git的一个配置属性&#xff1a;core.autocrlf 由于…

Kafka数据可靠性保证

1.生产者发送数据到Topic partition的可靠性保证 为保证producer发送的数据&#xff0c;能可靠的发送到指定的topic&#xff0c;topic的每个partition收到producer发送的数据后&#xff0c;都需要向producer发送ack&#xff08;acknowledgement确认收到&#xff09;&#xff0c…

构建卓越语言模型应用的利器:LangChain | 开源日报 No.39

langchain-ai/langchain Stars: 61.3k License: MIT LangChain 是一个用于通过组合性构建 LLMs 应用程序的库。 LLMs 和 Prompts&#xff1a;包括 prompt 管理、prompt 优化、所有 LLM 的通用接口以及与 LLMs 一起使用的常见工具。Chains&#xff1a;超越单个 LLM 调用&…

nodejs+vue大学食堂订餐系统elementui

可以查看会员信息&#xff0c;录入新的会员信息&#xff0c;对会员的信息进行管理。 网站管理模块对整个网站中的信息进行管理&#xff0c;可以查看会员留在留言栏中的信息&#xff0c;设置网站中的参数等。用户管理模块主要实现用户添加、用户修改、用户删除等功能。 近年来&…

C++与数据结构面经(重中之重)

多线程 互斥锁 原子变量 自旋锁 C11新特性 智能指针 首先智能指针是一个类&#xff0c;超过类的作用域会进行析构&#xff0c;所以不用担心内存泄漏。Unique_ptr(独占指针):规定一个智能指针独占一块内存资源。当两个智能指针同时指向一块内存&#xff0c;编译报错。 不允…

华南理工大学电子与信息学院23年预推免复试面试经验贴

运气较好&#xff0c;复试分数90.24&#xff0c;电科学硕分数线84、信通83、专硕电子与信息74. 面试流程&#xff1a; 1&#xff1a;5min ppt的介绍。其中前2min用英语简要介绍基本信息&#xff0c;后3min可用英语也可用中文 介绍具体项目信息如大创、科研、竞赛等&#xff08…

ThrowableError in Arr.php line 380

欢迎关注我的公众号&#xff1a;夜说猫&#xff0c;每周新闻点评~ 前言 今天重装了宝塔之后重装php&#xff0c;遇到了一个问题&#xff0c;如下 ThrowableError in Arr.php line 380 Parse error: syntax error, unexpected 提示我语法错误。 报错原因 主要是thinkphp5.1…

【新版】系统架构设计师 - 软件架构的演化与维护

个人总结&#xff0c;仅供参考&#xff0c;欢迎加好友一起讨论 文章目录 架构 - 软件架构的演化与维护考点摘要软件架构演化和定义面向对象软件架构演化对象演化消息演化复合片段演化约束演化 软件架构演化方式静态演化动态演化 软件架构演化原则软件架构演化评估方法大型网站架…

JVM对象创建与内存分配机制

对象的创建 对象创建的主要流程: ​ 1.类加载检查 虚拟机遇到一条new指令时&#xff0c;首先将去检查这个指令的参数是否能在常量池中定位到一个类的符号引用&#xff0c;并且检查这个符号引用代表的类是否已被加载、解析和初始化过。如果没有&#xff0c;那必须先执行相应…

如何在Python中捕获异常

1. 写在前面 本文主要介绍 Python 捕获异常的各种技术。首先&#xff0c;回顾 Python 的异常处理机制&#xff0c;然后深入研究并学习如何识别捕获的异常内容&#xff0c;以及忽略异常。 公众号&#xff1a; 滑翔的纸飞机 2. Python 异常处理机制 Python 代码在运行的过程中&…

5-1.(OOP)初步分析MCV架构模式

组成&#xff1a;模型&#xff08;model&#xff09;、视图&#xff08;view&#xff09;、控制器&#xff08;controller&#xff09; view&#xff1a;界面、显示数据 model&#xff1a;数据管理、负责在数据库中存取数据以及数据合法性验证 controller&#xff1a;负责转…

uni-app:顶部标题栏的部分相关设置(标题更改, 加载效果)

一、标题更改 效果 方法一&#xff1a;在pages.json中进行修改 {"path": "pages/index/index","style": {"navigationBarTitleText": "自定义标题"} }, 方法二&#xff1a;在页面直接进行修改 onLoad() {// 设置页面的标…

Spring Boot 如何配置 CORS 支持

Spring Boot 如何配置 CORS 支持 跨域资源共享&#xff08;CORS&#xff09;是一种重要的网络安全策略&#xff0c;用于限制浏览器在不同域之间的HTTP请求。Spring Boot提供了简单而强大的方法来配置CORS支持&#xff0c;以确保您的应用程序能够与其他域的资源进行安全交互。本…

某高校的毕设

最近通过某个平台接的单子&#xff0c;最后Kali做的测试没有公开可以私聊给教程。 下面是规划与配置 1.vlan方面&#xff1a;推荐一个vlan下的所有主机为一个子网网段 连接电脑和http客户端的接口配置为access接口 交换机与交换机或路由器连接的接口配置为trunk接口---也可以…

电商项目高级篇-02 elasticsearch-下

电商项目高级篇-02 elasticsearch-下 4.2、QueryDSL返回指定字段 4.2、QueryDSL 返回指定字段 返回单个字段 GET bank/_search {"query": {"match_all": {}}, "sort": [{"balance": {"order": "desc"}}], &quo…

IoTDB 在国际数据库性能测试排行榜中位居第一?测试环境复现与流程详解第一弹!...

最近我们得知&#xff0c;Apache IoTDB 多项性能表现位居 benchANT 时序数据库排行榜&#xff08;Time Series: DevOps&#xff09;性能排行第一名&#xff01;&#xff08;榜单地址&#xff1a;https://benchANT.com/ranking/database-ranking&#xff09; benchANT 位于德国&…