three.js使用问题记录

1,透明球体嵌套外层球体需要开启 depthWrite: false, 不然无法看到内层透明球体

       // 球1
        const sphereGeom1 = new THREE.SphereGeometry(4 + baseData.warningDistance, 32, 32)
        const material1 = new THREE.MeshBasicMaterial({
          color: 0xf49b25,
          transparent: true,
          opacity: 0.1,
          depthWrite: false
        })
        const sphere1 = new THREE.Mesh(sphereGeom1, material1)
        sphere1.position.set(0, -9.5, 0)
        scene.add(sphere1)
        // 球2
        const sphereGeom2 = new THREE.SphereGeometry(4 + baseData.prohibitedDistance, 32, 32)
        const material2 = new THREE.MeshBasicMaterial({
          color: 0xa20215,
          transparent: true,
          opacity: 0.1,
          depthWrite: false
        })
        const sphere2 = new THREE.Mesh(sphereGeom2, material2)
        sphere2.position.set(0, -9.5, 0)
       scene.add(sphere2)

 

2,控制相机controls存在时 ,camera.lookAt() 不起作用

解决办法: 设置controls.target = new THREE.Vector3(300, 300, 0) 代替camera.lookAt()

 

3,计算向量的夹角

v1 = new THREE.Vector3(5,0,0);

v2 = new THREE.Vector3(5,5,0);

v1.angleTo(v2); //0.7853981633974484

v2.angleTo(v1); //0.7853981633974484

可见,向量的夹角是没有方向的。但是有时候,又需要计算夹角的方向,可以使用下面的方法:

从那个向量转向那个向量首先要确定是用左手坐标系还是右手坐标系
​
要确定角度的方向,就用叉乘
​
用opengl作为例子,opengl是右手坐标系,z轴朝向屏幕外。比如有向量v1,和v2。
​
确定角度的方向用叉乘
​
v1×v2 得到的向量朝向屏幕外的话,说明就是角度就是逆时针方向,否则为顺时针方向。左手坐标系则相反。
​
在threejs中,Vector3类已经定义了叉乘方法:
​
let v1 = new THREE.Vector3(3,4,0);
let v2 = new THREE.Vector3(7,11,0);
v1.cross(v2);
if(v1.z>0){
  //角度是逆时针方向的
}else{
 //角度是顺时针方向的
}
​

 

4,threeJs 场景为渐变色或者图片

注意不能设置scene的颜色

①设置渲染器的背景透明显示:

renderer = new THREE.WebGLRenderer({
​
   alpha: true // canvas是否包含alpha (透明度) 默认为 false
​
  })

②使用css设置渲染器元素所在dom背景:

#container {
    width: 100%;
    height: 600px;
    outline: none;
    background-image: linear-gradient(rgb(0, 0, 1), rgb(119, 119, 237));
}

 

5,场景中有些角度看到球体变形为椭圆

调整camera的视野范围fov ,太大了会变形

 

6,画有宽度的虚线(也可画实线,但是画透明实线会有那些点的颜色无法透明)

  import { LineMaterial } from 'three/examples/jsm/lines/LineMaterial.js'
  import { LineGeometry } from 'three/examples/jsm/lines/LineGeometry.js'
  import { Line2 } from 'three/examples/jsm/lines/Line2.js'
// 虚线
    const positionArr: number[] = [1,1,1,2,2,2]
    const geometry = new LineGeometry()
    geometry.setPositions(positionArr)
    dashMatLine = new LineMaterial({
      color: 0x2cae75,
      linewidth: 0.001,
      dashed: true,
      dashOffset: 0,
      alphaToCoverage: true
    })
    const line1 = new Line2(geometry, dashMatLine)
    line1.computeLineDistances()
    scene.add(line1)

7, 画有宽度的线(three.meshline插件)

npm i three.meshline  复制代码
import { MeshLine, MeshLineMaterial, MeshLineRaycast } from 'meshline'; 复制代码
介绍
1.MeshLine主要方法
setPoints
​
setPoints(points: Float32Array | Array<number>, wcb?: (p: number) => any): void; 复制代码
根据传入的顶点数据生成几何体
​
setGeometry
​
setGeometry(g: THREE.BufferGeometry, c: (p: number) => any): void; 复制代码
根据一个THREE.BufferGeometry来获取顶点数据生成几何体
​
2.MeshLineMaterial主要属性介绍
MeshLineMaterial继承自ShaderMaterial,所以ShaderMateria上的有些属性也是可以用的(比如 wireframe: true)
​
export class MeshLineMaterial extends THREE.ShaderMaterial  复制代码
map - 贴图 THREE.Texture
​
useMap - 是否使用贴图 (0 - 不使用,用color中的颜色, 1 - 使用)
​
alphaMap - 一张灰度纹理,用于控制整个表面的不透明度 THREE.Texture
​
useAlphaMap - 是否使用灰度贴图 (0-不使用, 1-使用)
​
repeat -  设置纹理的重复 THREE.Vector2
​
color - 线的颜色
​
opacity - 透明度 (transparent 需要透明设置为 true`)
​
alphaTest - 透明度测试,设置一个0-1的值,透明度小于这值的就不会显示
​
dashArray - 通俗解释为 一组虚线(有颜色部分跟间隔部分加起来)占总长度的比例,决定绘制多少组虚线(详见后面示例)
​
dashOffset - 一组虚线中间隔开始的位置,改变其位置用来实现动画 (详见后面示例)
​
dashRatio - 定义一组虚线中无颜色的间隔部分占比为多少 0-1(详见后面示例)
​
resolution - 指定画布大小THREE.Vector2 
​
sizeAttenuation - 线的大小是否会受相机影响。(0 - 不会, 1 - 会)
​
lineWidth - 线宽
​
3.MeshLineRaycast使线可以被选中
mesh.raycast = MeshLineRaycast 复制代码
把线模型这样设置后,raycaster.intersectObjects([线模型])的时候,就能捕捉到线模型了
​
// 例子
// 画线-使用插件
    const positionArr: number[] = [1,1,1,2,2,2]
    const line = new MeshLine()
    line.setPoints(positionArr)
    const material = new MeshLineMaterial({
      color: 0x2cae75, // 线条颜色
      lineWidth: 0.04, // 线条的宽度
      transparent: true, // 设置透明度
      opacity: 0.15, // 设置透明度
      sizeAttenuation: 0 // 线的大小是否会受相机影响(0不会, 1会)
    })
​
    const meshLine = new THREE.Mesh(line, material)
    scene.add(meshLine)

 

7,计算模型的大小

const getModelSize = (obj: any): void => {
    const box = new THREE.Box3().expandByObject(obj)
    const v3 = new THREE.Vector3()
    box.getSize(v3)
    console.log('size', v3)
  }
 
posted @ 2022-10-28 17:34  北巷听雨  阅读(297)  评论(0编辑  收藏  举报
返回顶端