ThreeJs学习之旅(四)

一、需求:让画布充满屏幕

camera.aspect

.aspect : Float

摄像机视锥体的长宽比,通常是使用画布的宽/画布的高。默认值是1(正方形画布)        

camera.updateProjectionMatrix()

属性

请参阅其基类 Camera 来查看共有属性。
请注意,在大多数属性发生改变之后,你将需要调用.updateProjectionMatrix来使得这些改变生效。

.updateProjectionMatrix () : null

更新摄像机投影矩阵。在任何参数被改变以后必须被调用。

方法通过监听 window中resize属性来观测窗口大小从而改变画布大小

const sizes = {
  width: window.innerWidth,
  height: window.innerHeight,
};
window.addEventListener('resize',function(event){
  sizes.width=window.innerWidth;
  sizes.height=window.innerHeight;
  camera.aspect=sizes.width/sizes.height;    //改变摄像机比例
  camera.updateProjectionMatrix()            //更新摄像机属性
  renderer.setSize(sizes.width,sizes.height)    //设置画布大小
})

二、设备像素比

window属性:devicePixelRatio

2018-04-03 10:54 更新

devicePixelRatio属性

该 Window 属性 devicePixelRatio 能够返回当前显示设备的物理像素分辨率与 CSS 像素分辨率的比率。此值也可以解释为像素大小的比率:一个 CSS 像素的大小与一个物理像素的大小的比值。简单地说,这告诉浏览器应该使用多少个屏幕的实际像素来绘制单个 CSS 像素。

这在处理标准显示与 HiDPI 或 Retina 显示之间的差异时很有用,它使用更多屏幕像素绘制相同对象,从而产生更清晰的图像。

当此值发生变化时(例如,如果用户将 window 拖到具有不同像素密度的显示器上),则无法通知该值。由于没有可用于检测像素密度变化的回调或事件,因此唯一的方法是定期检查其 devicePixelRatio 值是否已更改。不要经常这样做,否则会影响性能。

设置 像素比相同

 renderer.setPixelRatio(Math.min(window.devicePixelRatio,2));

三、双击全屏 

兼容写法

window.addEventListener('dblclick',function(){
  const fullscreenElement=document.fullscreen || document.mozFullScreen || document.webkitIsFullScreen ||document.webkitFullScreen|| document.msFullScreen 
  if(!fullscreenElement){
    if (canvas.RequestFullScreen) {
      canvas.RequestFullScreen()
        //兼容Firefox
    } else if (canvas.mozRequestFullScreen) {
      canvas.mozRequestFullScreen()
        //兼容Chrome, Safari and Opera等
    } else if (canvas.webkitRequestFullScreen) {
      canvas.webkitRequestFullScreen()
        //兼容IE/Edge
    } else if (canvas.msRequestFullscreen) {
      canvas.msRequestFullscreen()
    }
  }else{
    console.log('取消')
    if(document.exitFullScreen) {
        document.exitFullScreen();
    //兼容Firefox
    } else if(document.mozCancelFullScreen) {
        document.mozCancelFullScreen();
    //兼容Chrome, Safari and Opera等
    } else if(document.webkitExitFullscreen) {
        document.webkitExitFullscreen();
    //兼容IE/Edge
    } else if(element.msExitFullscreen) {
        element.msExitFullscreen();
    }
  }
})

四、立方几何体(BoxGeometry)

BoxGeometry是四边形的原始几何类,它通常使用构造函数所提供的“width”、“height”、“depth”参数来创建立方体或者不规则四边形。

构造器

BoxGeometry(width : Float, height : Float, depth : Float, widthSegments : Integer, heightSegments : Integer, depthSegments : Integer)

width — X轴上面的宽度,默认值为1。
height — Y轴上面的高度,默认值为1。
depth — Z轴上面的深度,默认值为1。
widthSegments — (可选)宽度的分段数,默认值是1。
heightSegments — (可选)宽度的分段数,默认值是1。
depthSegments — (可选)宽度的分段数,默认值是1。

例:

const geometry = new THREE.BoxGeometry(1, 1, 1,2,1,1);
const material = new THREE.MeshBasicMaterial({ color: 0xff0000,wireframe:true });

基础网格材质(MeshBasicMaterial)

一个以简单着色(平面或线框)方式来绘制几何体的材质。

.wireframe : Boolean

将几何体渲染为线框。默认值为false(即渲染为平面多边形)。

 

 

立方缓冲几何体(BoxBufferGeometry)

这是BoxGeometry中的BufferGeometry接口。

构造器

BoxBufferGeometry(width : Float, height : Float, depth : Float, widthSegments : Integer, heightSegments : Integer, depthSegments : Integer)

width — X轴上面的宽度,默认值为1。
height — Y轴上面的高度,默认值为1。
depth — Z轴上面的深度,默认值为1。
widthSegments — (可选)宽度的分段数,默认值是1。
heightSegments — (可选)宽度的分段数,默认值是1。
depthSegments — (可选)宽度的分段数,默认值是1。

*  最好去使用 bufferGeometry 有更好的性能优化 *

Face3

在 Geometry 中被使用到的三角面片。这些三角面片会为所有标准几何体自动创建。 然而,如果你正在构建一个自定义几何体,你需要手动创建这些三角面片。

构造函数

Face3( a : Integer, b : Integer, c : Integer, normal : Vector3, color : Color, materialIndex : Integer )

a — 顶点 A 的索引。
b — 顶点 B 的索引。
c — 顶点 C 的索引。

normal — (可选) 面的法向量 (Vector3) 或顶点法向量队列。 如果参数传入单一矢量,则用该量设置面的法向量 .normal,如果传入的是包含三个矢量的队列, 则用该量设置 .vertexNormals

color — (可选) 面的颜色值 color 或顶点颜色值的队列。 如果参数传入单一矢量,则用该量设置 .color,如果传入的是包含三个矢量的队列, 则用该量设置 .vertexColors

materialIndex — (可选) 材质队列中与该面对应的材质的索引。

 

 

const faces=new THREE.Face3(0,1,2)

利用buffer来创建 网状物 

BufferAttribute

这个类用于存储与BufferGeometry相关联的 attribute(例如顶点位置向量,面片索引,法向量,颜色值,UV坐标以及任何自定义 attribute )。 利用 BufferAttribute,可以更高效的向GPU传递数据。详情和例子见该页。

在 BufferAttribute 中,数据被存储为任意长度的矢量(通过itemSize进行定义),下列函数如无特别说明, 函数参数中的index会自动乘以矢量长度进行计算。

构造函数

BufferAttribute( array : TypedArray, itemSize : Integer, normalized : Boolean )

array -- 必须是 TypedArray. 类型,用于实例化缓存。
该队列应该包含:itemSize * numVertices个元素,numVertices 是 BufferGeometry中的顶点数目

itemSize -- 队列中与顶点相关的数据值的大小。举例,如果 attribute 存储的是三元组(例如顶点空间坐标、法向量或颜色值)则itemSize的值应该是3。 

normalized -- (可选) 指明缓存中的数据如何与GLSL代码中的数据对应。例如,如果array是 UInt16Array类型,且normalized的值是 true,则队列中的值将会从 0 - +65535 映射为 GLSL 中的 0.0f - +1.0f。 如果array是 Int16Array (有符号),则值将会从 -32767 - +32767 映射为 -1.0f - +1.0f。若 normalized 的值为 false,则数据映射不会归一化,而会直接映射为 float 值,例如,32767 将会映射为 32767.0f.

const bufferGeometry=new BufferGeometry()
const positionsArray=new Float32Array([
  0,0,0,
  0,1,0,
  1,0,0
])
const positionsAttribute=new THREE.BufferAttribute(positionsArray,3)
bufferGeometry.setAttribute('position',positionsAttribute)

const mesh = new THREE.Mesh(bufferGeometry, material);
scene.add(mesh);

 通过 new Float32Array创建两个

const bufferGeometry=new BufferGeometry()
const positionsArray=new Float32Array([
  0,0,0,
  0,1,0,
  1,0,0,
  0.5,0.1,0.2,
  0.8,0.1,0.3,
  0.4,0.2,0.1,
])
const positionsAttribute=new THREE.BufferAttribute(positionsArray,3)
bufferGeometry.setAttribute('position',positionsAttribute)

创建多个(50) 

const bufferGeometry=new BufferGeometry()
const count=50;

const positionsArray=new Float32Array(count*3*3);
for(let i=0;i<count*3*3;i++){
  positionsArray[i]=Math.random()
}
const positionsAttribute=new THREE.BufferAttribute(positionsArray,3)
bufferGeometry.setAttribute('position',positionsAttribute)

 完整代码

import "./style.css";
import * as THREE from "three";
import {OrbitControls} from 'three/examples/jsm/controls/OrbitControls'
import gsap from 'gsap'
import { BufferGeometry } from "three";
const scene = new THREE.Scene();
// const geometry = new THREE.BoxGeometry(1, 1, 1,2,1,1);
const geometry = new THREE.Geometry();

const material = new THREE.MeshBasicMaterial({ color: 0xff0000,wireframe:true });
const sizes = {
  width: window.innerWidth,
  height: window.innerHeight,
};
// const vertex1=new THREE.Vector3(0,0,0);
// geometry.vertices.push(vertex1)
// const vertex2=new THREE.Vector3(0,1,0);
// geometry.vertices.push(vertex2)
// const vertex3=new THREE.Vector3(1,0,0);
// geometry.vertices.push(vertex3)
// const faces=new THREE.Face3(0,1,2)
// geometry.faces.push(faces)

const bufferGeometry=new BufferGeometry()
const count=50;

const positionsArray=new Float32Array(count*3*3);
for(let i=0;i<count*3*3;i++){
  positionsArray[i]=Math.random()
}
const positionsAttribute=new THREE.BufferAttribute(positionsArray,3)
bufferGeometry.setAttribute('position',positionsAttribute)

const camera = new THREE.PerspectiveCamera(75, sizes.width / sizes.height);
camera.position.z = 3;


const mesh = new THREE.Mesh(bufferGeometry, material);
scene.add(mesh);

scene.add(camera);
const canvas = document.querySelector("canvas.webgl");

const renderer = new THREE.WebGLRenderer({
  canvas,
});
renderer.setSize(sizes.width, sizes.height);
const controls =new OrbitControls( camera, canvas );
controls.enableDamping=true
window.addEventListener('resize',function(event){
  sizes.width=window.innerWidth;
  sizes.height=window.innerHeight;
  camera.aspect=sizes.width/sizes.height;
  camera.updateProjectionMatrix()
  renderer.setSize(sizes.width,sizes.height)
  renderer.setPixelRatio(Math.min(window.devicePixelRatio,2));
})
window.addEventListener('dblclick',function(){
  const fullscreenElement=document.fullscreen || document.mozFullScreen || document.webkitIsFullScreen ||document.webkitFullScreen|| document.msFullScreen 
  if(!fullscreenElement){
    if (canvas.RequestFullScreen) {
      canvas.RequestFullScreen()
        //兼容Firefox
    } else if (canvas.mozRequestFullScreen) {
      canvas.mozRequestFullScreen()
        //兼容Chrome, Safari and Opera等
    } else if (canvas.webkitRequestFullScreen) {
      canvas.webkitRequestFullScreen()
        //兼容IE/Edge
    } else if (canvas.msRequestFullscreen) {
      canvas.msRequestFullscreen()
    }
  }else{
    console.log('取消')
    if(document.exitFullScreen) {
        document.exitFullScreen();
    //兼容Firefox
    } else if(document.mozCancelFullScreen) {
        document.mozCancelFullScreen();
    //兼容Chrome, Safari and Opera等
    } else if(document.webkitExitFullscreen) {
        document.webkitExitFullscreen();
    //兼容IE/Edge
    } else if(element.msExitFullscreen) {
        element.msExitFullscreen();
    }
  }
})
// gsap.to(mesh.rotation,{duration:1,delay:1,y:2})
const tick=()=>{
 
  controls.update();
  renderer.render(scene, camera);
  window.requestAnimationFrame(tick)
}
tick()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值