Threejs学习笔记 二

简介: 在我第一集的笔记中,我们实现了在react中创建简单三维模型,接下来,我们在此基础上学习材质贴图,并实现一个简单的vr看房。

在上一章节中,我们实现了一个简单的三维场景,在此基础上,我们进行一些小小的改造。
我们了解一个网格模型由几何体和材质模型组成,我们可以对材质进行贴图处理,用我们想要的图片作为几何体材质覆盖到几何体中。
下面是一个简单示例

import React, { Component } from 'react'
import Earth from './Earth.png'
import * as THREE from 'three';
import {OrbitControls} from 'three/examples/jsm/controls/OrbitControls'

export default class index extends Component {
componentDidMount(){
  /**
   * 
   * 创建场景对象Scene
   */
   const scene = new THREE.Scene();
   /**
    * 创建网格模型
    */
   
    const geometry = new THREE.SphereGeometry(60, 100, 100); //球体
   // TextureLoader创建一个纹理加载器对象,可以加载图片作为几何体纹理
   const textureLoader = new THREE.TextureLoader();
   // 执行load方法,加载纹理贴图成功后,返回一个纹理对象Texture
  const texture=  textureLoader.load(Earth)
   const material = new THREE.MeshLambertMaterial({
    // color: 0x0000ff,
    // 设置纹理贴图:Texture对象作为材质map属性的属性值
    map: texture,  
   // wireframe:true//线框渲染方式
  }); //材质对象Material 
   const mesh = new THREE.Mesh(geometry, material); //网格模型对象Mesh
   scene.add(mesh); //网格模型添加到场景中
   //纹理贴图加载成功后,调用渲染函数执行渲染操作
  
   /**
    * 光源设置
    */
   //点光源
   const point = new THREE.PointLight(0xffffff);
   point.position.set(400, 200, 300); //点光源位置
   scene.add(point); //点光源添加到场景中
   //环境光
   const ambient = new THREE.AmbientLight(0x444444);
   scene.add(ambient);
   /**
    * 相机设置
    */
   const width = window.innerWidth; //窗口宽度
   const height = window.innerHeight; //窗口高度
   const k = width / height; //窗口宽高比
   const s = 150; //三维场景显示范围控制系数,系数越大,显示的范围越大
   //创建相机对象
   const camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 1000);
   camera.position.set(200, 300, 200); //设置相机位置
   camera.lookAt(scene.position); //设置相机方向(指向的场景对象)
   /**
    * 创建渲染器对象
    */
   const renderer = new THREE.WebGLRenderer();
   renderer.setSize(width, height); //设置渲染区域尺寸
   renderer.setClearColor(0x000000, 1); //设置背景颜色
   document.getElementById("Earth").appendChild(renderer.domElement); //body元素中插入canvas对象
 
   // 渲染函数
   function render() {
     renderer.render(scene, camera); //执行渲染操作
      mesh.rotation.y+=0.01;//转动方向
      
     requestAnimationFrame(render);//请求再次执行渲染函数render,渲染下一帧
   }
   render();
   //创建控件对象  相机对象camera作为参数   控件可以监听鼠标的变化,改变相机对象的属性
  const controls = new OrbitControls(camera,renderer.domElement);
  //controls.addEventListener('change',render);
}
render() {
  return (
    <div>
      <div id="Earth"/>
    </div>
  )
}
}
这个代码中的重点代码是下面这段
 // TextureLoader创建一个纹理加载器对象,可以加载图片作为几何体纹理
   const textureLoader = new THREE.TextureLoader();
   // 执行load方法,加载纹理贴图成功后,返回一个纹理对象Texture
  const texture=  textureLoader.load(Earth)
   const material = new THREE.MeshLambertMaterial({
    // color: 0x0000ff,
    // 设置纹理贴图:Texture对象作为材质map属性的属性值
    map: texture,  
   // wireframe:true//线框渲染方式
  }); //材质对象Material 
   const mesh = new THREE.Mesh(geometry, material); //网格模型对象Mesh
   scene.add(mesh); //网格模型添加到场景中  

效果如下
image-20210802114310379.png
第二个例子,这次我们以正方体为例,正方体六个面。
按照上面的方法,我们会发现,正方体六个面都会被同一张图片覆盖,此时,我们可以进行材质数组的创建,为正方体的六个面分别创建不同的材质数组
我们将上述的代码进行一些小小的改动

//声明一个正方体
const geometry = new THREE.BoxGeometry(100,100,100);
//声明材质数组
const material_1 = new THREE.MeshPhongMaterial({
    color:0xffff3f
});
const textureLoader = new THREE.TextureLoader();
const texture = textureLoader.load(Earth);
const material_2 = new THREE.MeshLambertMaterial({
    map:texture
 });

const materialArr = [material_1, material_1, material_1, material_1, material_2, material_1];
 const mesh = new THREE.Mesh(geometry,materialArr);
 console.log("数组详情",geometry.groups)
 scene.add(mesh);

效果如下
image-20210802155704048.png

经过上面的铺垫,我们开始实现一个简单的vr看房,实现思路如下,
1.以正方形为例
我们选取一个室内的前后左右,上下的六张图片分别赋值给材质数组,大家可以自行搜索贴图资源,具体效果如下
image-20210802161627227.png
但此时我们只是成功了一半,我们要实现想要的效果还差一点,首先,图片向内翻转180度,然后将摄像机的位置放在内部的中心点中。
只需要一个小小的改动,将网格模型的gemoetry对象进行缩放,当为负数的时候,就会进行翻转,然后设置相机坐标就大功告成了

mesh.geometry.scale(1, 1, -1);

圆形的几何体也可以,而且只需要加载一张图片,不过需要特殊的全景图片,这里给出一个效果图片
D6808EB2-3151-41AA-8863-2EDB60D43A75.png

相关文章
|
网络协议 前端开发 Java
SpringBoot 整合 WebSocket
WebSocket是基于TCP协议的一种网络协议,它实现了浏览器与服务器全双工通信,支持客户端和服务端之间相互发送信息。在有WebSocket之前,如果服务端数据发生了改变,客户端想知道的话,只能采用定时轮询的方式去服务端获取,这种方式很大程度上增大了服务器端的压力,有了WebSocket之后,如果服务端数据发生改变,可以立即通知客户端,客户端就不用轮询去换取,降低了服务器的压力。目前主流的浏览器都已经支持WebSocket协议了。
SpringBoot 整合 WebSocket
|
6月前
|
数据采集 供应链 物联网
RFID仓库进出入与盘点采集精细化管理
RFID技术赋能仓库智能化管理,实现入库、出库、盘点全流程自动化采集与实时校验。替代人工扫码记账,提升作业效率5–10倍,杜绝错发漏发与盘点误差,确保库存数据精准、实时、可溯,助力仓储精细化、数字化升级。(238字)
|
6月前
|
存储 人工智能 缓存
企业模型成本治理:从“任务分层”到“AI网关”,5个结构抓手告别账单失控
企业大模型成本失控,根源常在任务混用、上下文冗余、失败无界等结构性问题。本文提出五大治理抓手:任务分层路由、上下文复用、失败预算管控、Batch批处理、统一观测体系,并强调需通过标准化治理层实现成本从“月底追溯”到“日常可控”的转变。
321 5
|
存储 运维 安全
SaaS多租户和单租户的区别解析
SaaS多租户的系统维护成本低,多租户系统在升级时,只需要更新一次,维护人员不需要对每个用户更新,节省了很大的运维成本,这对于所有客户都在做同样事情的系统来说是很有用的。
1093 3
|
6月前
|
人工智能 JSON 运维
做邮箱自动化两个月后,我对 Email MCP Tool 和 DMXAPI 的看法
Email MCP Tool 是被严重低估的高价值场景:邮件信息密度高、结构混乱、上下文分散。它并非“让AI发邮件”,而是为大模型提供安全、规范、可审计的邮件操作接口(如读线程、提附件、建草稿),将非结构化输入转化为可执行语义,显著提升分拣、摘要与协同效率。
|
7月前
|
移动开发 前端开发 JavaScript
【HTML】HTML所有标签的用法及示例(二)
本文系统梳理HTML全部标签功能与用法,涵盖文档结构、语义化分区、文本格式、内联语义、多媒体、表单、脚本等11大类,搭配基础代码示例,有效帮助开发者准确理解标签语义与适用场景。
|
8月前
|
数据采集 人工智能 监控
2026年企业数据系统建设方案指南
《2020–2026企业数据系统建设指南》聚焦数据资产化、AI原生架构与隐私合规三大趋势,以瓴羊Dataphin为智能治理核心,提供覆盖标准定义、建模规范、质量监控到AI就绪输出的全链路方案,助力企业实现从“数据资源”到“数据资产”的战略跃迁。(239字)
|
10月前
|
人工智能 自然语言处理 供应链
破局跨境电商运营困境,构建未来核心竞争力
全球跨境电商迅猛发展,企业面临数据孤岛、供应链脆弱、合规风险等挑战。本报告剖析大型卖家在“人、货、场、管”中的核心痛点,提出以一体化数字中台为核心的解决方案,涵盖主数据管理、全链路协同、业财融合与AI赋能,助力企业实现精细化运营与智能决策,构建全球化竞争壁垒。
破局跨境电商运营困境,构建未来核心竞争力
|
10月前
|
缓存 运维 Prometheus
别再半夜敲命令了:用 LLM + 自动化脚本,把 Runbook 变成“会思考的运维同事”
别再半夜敲命令了:用 LLM + 自动化脚本,把 Runbook 变成“会思考的运维同事”
412 5

热门文章

最新文章