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 定位技术
Threejs路径规划案例V1
这篇文章详细介绍了使用Three.js进行三维路径规划的实现方法,包括设置三维场景、实现车辆避障以及展示规划路径等内容。
343 1
ThreeJs通过射线获取自己的点击位置坐标
这篇文章详细说明了如何使用Three.js来绘制线条,包括创建线几何体、设置材质以及将线条添加到3D场景中的具体步骤。
584 1
ThreeJs通过射线获取自己的点击位置坐标
|
vr&ar
Threejs制作虚拟房间效果
这篇文章详细说明了如何使用Three.js创建一个虚拟房间的3D模型,通过将六个方向的照片作为立方体的纹理,从而实现一个类似于天空盒的室内场景,让用户能够探索房间的不同角落。
439 0
|
Java Apache Maven
Java/Spring项目的包开头为什么是com?
本文介绍了 Maven 项目的初始结构,并详细解释了 Java 包命名惯例中的域名反转规则。通过域名反转(如 `com.example`),可以确保包名的唯一性,避免命名冲突,提高代码的可读性和逻辑分层。文章还讨论了域名反转的好处,包括避免命名冲突、全球唯一性、提高代码可读性和逻辑分层。最后,作者提出了一个关于包名的问题,引发读者思考。
979 0
Java/Spring项目的包开头为什么是com?
|
移动开发 编解码 JavaScript
h5页面在移动端实现禁止缩放、双击放大和双指放大
h5页面在移动端实现禁止缩放、双击放大和双指放大
|
JavaScript
vue中使用echarts绘制双Y轴图表时,刻度没有对齐的两种解决方法
vue中使用echarts绘制双Y轴图表时,刻度没有对齐的两种解决方法
3722 0
|
负载均衡 网络协议 前端开发
一文快速上手 Nacos 注册中心+配置中心!
一文快速上手 Nacos 注册中心+配置中心!
9023 0
|
存储 Java API
【JavaSE】java基本概念总结Ⅰ
jdk:JDK(Java Development Kit)称为Java开发包或Java开发工具, 是一个编写Java应用程序的程序开发环境。JDK是整个Java的核心,包括了Java运行环境(Java Runtime Environment),一些Java工具和Java的核心类库(Java API) jre:Java运行环境(Java Runtime Environment)是支持Java程序运行的标准环境 jvm(java Virtual Machine) java虚拟机。