three.js教程学习初始化配置

记录一下学习three.js历程,我用的全是class,这里配置一下基础的class文件,由于目前也在学习ts就用了ts了

文件目录大概如下:common中写基础的配置,objects中写具体实例, scene中写具体逻辑创建调用

 Base.ts

import { Scene } from "three"

export default class Base {
  instance:any
  
  constructor(){}
  // 修改位置
  setPosition (x:number,y:number,z:number) {
    this.instance.position.set(x,y,z)
  }
  // 修改旋转
  setRotation (x:number,y:number,z:number) {
    this.instance.rotation.x = x
    this.instance.rotation.y = y
    this.instance.rotation.z = z
  }
  // 修改缩放
  setScale (x:number,y:number,z:number) {
    this.instance.scale.set(x,y,z); //缩放
  }
  // 修改名称
  setName (name:string) {
    this.instance.name = name; // 命名
  }
  // 添加到scene
  addToScene (scene:Scene) {
    scene.add(this.instance)
  }

}

 Template.ts

import {Scene, PerspectiveCamera, WebGLRenderer, Vector3, Color,
  Vector2, AmbientLight, DirectionalLight, AxesHelper, Mesh, Raycaster,GridHelper
} from 'three'
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls"
import { CSS3DRenderer } from "three/examples/jsm/renderers/CSS3DRenderer.js";

import { EffectComposer } from "three/examples/jsm/postprocessing/EffectComposer.js"
import { RenderPass } from "three/examples/jsm/postprocessing/RenderPass.js"
import { OutlinePass } from "three/examples/jsm/postprocessing/OutlinePass.js"
import { ShaderPass } from "three/examples/jsm/postprocessing/ShaderPass.js"
import { FXAAShader } from "three/examples/jsm/shaders/FXAAShader.js"

interface PCamera{
  fov:number
  aspect:number
  near:number
  far:number
}
export default class Template {
  scene: Scene = new Scene()
  camera?: PerspectiveCamera
  renderer?: WebGLRenderer
  sceneBox: Scene = new Scene()
  renderBox?: CSS3DRenderer
  axesHelper?:AxesHelper
  gridHelper?:GridHelper
  ele:any = null
  PCamera:PCamera = {
    fov: 45,
    aspect: 0,
    near: 1,
    far: 1000
  }
  cameraPostion:Vector3 = new Vector3(0, 0, 0)
  cameraLookAt:Vector3 = new Vector3(0,0,0)
  rendererColor:Color = new Color(0x000000)
  rendererWidth:number = 0
  rendererHeight:number = 0
  intersects:any = []
  meshList:any = []
  composer?:EffectComposer
  outlinePass?:OutlinePass
  renderPass?:RenderPass

  constructor () {
  }
  // 初始化scene
  init <T>(ele:T) {
    this.ele = ele
    this.PCamera.aspect = this.ele.offsetWidth / this.ele.offsetHeight
    this.rendererWidth = this.ele.offsetWidth
    this.rendererHeight = this.ele.offsetHeight
    this.initPerspectiveCamera()
    this.initRenderer()
  }
  // 初始化弹窗scene
  initBox () {
    this.sceneBox = new Scene();

    const renderBox = new CSS3DRenderer();
    renderBox.setSize(this.rendererWidth, this.rendererHeight);
    renderBox.domElement.style.position = "absolute";
    renderBox.domElement.style.top = '0';
    this.ele.appendChild(renderBox.domElement);
    this.renderBox = renderBox
  }
  // 初始化相机
  initPerspectiveCamera () {
    const camera = new PerspectiveCamera(
      this.PCamera.fov,
      this.PCamera.aspect,
      this.PCamera.near,
      this.PCamera.far
    )
    camera.position.copy(this.cameraPostion)
    camera.lookAt(this.cameraLookAt)
    this.camera = camera
    this.scene.add(camera)
  }
  // 初始化render
  initRenderer () {
    const renderer = new WebGLRenderer({
      antialias: true
    })
    renderer.setClearColor(this.rendererColor)
    renderer.setSize(this.rendererWidth, this.rendererHeight)
    this.ele.appendChild(renderer.domElement)
    this.renderer = renderer
  }
    // 添加光照
  addAmbientLight (color:any) {
    this.scene.add( new AmbientLight( color ) )
  }
    // 添加方向光照
  addDirectionalLight (color:any,pos:{x:number,y:number,z:number},power?:number,castShadow?:boolean) {
    const light = new DirectionalLight( color, power?power:1 )
    light.position.set( pos.x, pos.y, pos.z )
    light.castShadow = castShadow?castShadow:false
    this.scene.add( light )
  }
    // 添加鼠标控制
  addOrbitControls (camera:PerspectiveCamera, el:any) {
    const controls = new OrbitControls( camera, el );
    controls.maxPolarAngle = Math.PI * 0.45;
    controls.enablePan = false  
  }
    // 辅助坐标轴
  addAxesHelper (num:number) {
    this.axesHelper = new AxesHelper( num )
    this.scene.add( this.axesHelper )
  }
    // 辅助网格
  addGridHelper (w:number,h:number) {
    this.gridHelper = new GridHelper( w,h )
    this.scene.add( this.gridHelper )
  }

  // 高亮效果
  outlineObj (selectedObjects:any) {
    if(this.renderer && this.camera){
    // 创建一个EffectComposer(效果组合器)对象,然后在该对象上添加后期处理通道。
    this.composer = new EffectComposer(this.renderer)
    // 新建一个场景通道  为了覆盖到原理来的场景上
    this.renderPass = new RenderPass(this.scene, this.camera)
    this.composer.addPass(this.renderPass);
    // 物体边缘发光通道
    this.outlinePass = new OutlinePass(new Vector2(this.ele.offsetWidth, this.ele.offsetHeight), this.scene, this.camera, selectedObjects)
    this.outlinePass.selectedObjects = selectedObjects
    this.outlinePass.edgeStrength = 10.0 // 边框的亮度
    this.outlinePass.edgeGlow = 1// 光晕[0,1]
    this.outlinePass.usePatternTexture = false // 是否使用父级的材质
    this.outlinePass.edgeThickness = 1.0 // 边框宽度
    this.outlinePass.downSampleRatio = 1 // 边框弯曲度
    this.outlinePass.pulsePeriod = 5 // 呼吸闪烁的速度
    this.outlinePass.visibleEdgeColor.set("#ffffff") // 呼吸显示的颜色
    this.outlinePass.hiddenEdgeColor = new Color(0, 0, 0) // 呼吸消失的颜色
    this.outlinePass.clear = true
    this.composer.addPass(this.outlinePass)
    // 自定义的着色器通道 作为参数
    var effectFXAA = new ShaderPass(FXAAShader)
    effectFXAA.uniforms.resolution.value.set(1 / this.ele.offsetWidth, 1 / this.ele.offsetHeight)
    effectFXAA.renderToScreen = true
    this.composer.addPass(effectFXAA)
    }
  }
  // 鼠标点击
  onMouseDown(callback:any){
    // 监听鼠标点击
    window.addEventListener('click', (event)=>{
      if(this.camera){
        let vector = new Vector3(
          ((event.clientX-this.ele.getBoundingClientRect().x) / this.ele.offsetWidth) * 2 - 1,
          -((event.clientY-this.ele.getBoundingClientRect().y) /  this.ele.offsetHeight) * 2 + 1,
          0.5
        )
        vector = vector.unproject(this.camera)
        const raycaster = new Raycaster(
          this.camera.position,
          vector.sub(this.camera.position).normalize()
        )
        this.intersects = raycaster.intersectObjects(this.meshList)
        callback && callback()
      }
    })
  }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值