Three管道漫游

<div id="webgl"></div>
  <script type="importmap">
    {
        "imports": {
          "three": "../../../three.js/build/three.module.js",
          "three/addons/": "../../../three.js/examples/jsm/"
        }
      }
    </script>
  <!-- 配置type="importmap",.html文件也能和项目开发环境一样方式引入threejs -->
  <script type="module" src="./index.js">
inde.js



// 引入gui.js

import { GUI } from "three/addons/libs/lil-gui.module.min.js";
const gui = new GUI();
gui.domElement.style.right = '0px';
gui.domElement.style.width = '300px';


import * as THREE from 'three'
import { OrbitControls } from "three/addons/controls/OrbitControls.js"

// 引入stats性能监视器
import Stats from "three/addons/libs/stats.module.js"

import { mesh, posintsArr } from "./mesh-modelDemo.js"


const stats = new Stats()
stats.setMode(1)//修改渲染模式,默认为0
document.getElementById("webgl").appendChild(stats.domElement);
// 创建一个三维场景
const scene = new THREE.Scene();

scene.add(mesh)


// 坐标格辅助对象. 坐标格实际上是2维线数组.
const gridHelper = new THREE.GridHelper(600, 50, 0x00ffffff);
scene.add(gridHelper);
gridHelper.position.y = -1;

// 创建辅助观察三维坐标
const axesHelper = new THREE.AxesHelper(300)
scene.add(axesHelper)//坐标轴对象添加到三维场景中

// 创建点光源
const pointLight = new THREE.PointLight(0xffffff, 1.0);
pointLight.decay = 0.0//不随距离的改变而衰减
pointLight.position.set(400, 200, 300)//设置光源位置
scene.add(pointLight)//点光源添加到场景中


// 添加一个环境光源
const ambient = new THREE.AmbientLight(0xffffff, 0.4)
scene.add(ambient)
console.log('光照强度', ambient.intensity);



// 添加一个平行光
const directionalLight = new THREE.DirectionalLight(0xffffff, 2)
directionalLight.position.set(50, 100, 60)
scene.add(directionalLight)




const obj = {
  color: 0x00ffff,//材质颜色
  specular: 0x111111//材质高光颜色

}

// 创建一个菜单
const mat = gui.addFolder('材质')
mat.close()

// 材质颜色
mat.addColor(obj, 'color').onChange((value) => {
  material.color.set(value)
})

// 材质高光颜色
mat.addColor(obj, 'specular').onChange((value) => {
  material.specular.set(value)
})



const ambientFolder = gui.addFolder('环境光')
ambientFolder.close()
// 环境光强度
ambientFolder.add(ambient, 'intensity', 0, 2)


const dirFolder = gui.addFolder('平行光')
dirFolder.close()
// 平行光强度
dirFolder.add(directionalLight, 'intensity', 0, 4)


const dirFolder2 = dirFolder.addFolder('位置')
dirFolder2.close()

// 平行光位置
dirFolder2.add(directionalLight.position, 'x', -400, 400)
dirFolder2.add(directionalLight.position, 'y', -400, 400)
dirFolder2.add(directionalLight.position, 'z', -400, 400)

// 定义相机输出画布的尺寸
const width = window.innerWidth
const height = window.innerHeight

// 创建一个透视投影相机对象
const camera = new THREE.PerspectiveCamera(60, width / height, 1, 3000);

// 设置相机位置
camera.position.set(450, 400, 400)

// 相机视线观察目标点坐标
camera.lookAt(0, 0, 0)//坐标原点


// 渲染器
// 创建一个WebGL渲染器
const renderer = new THREE.WebGLRenderer({
  antialias: true,//锯齿模糊
  logarithmicDepthBuffer: true,//设置对数深度缓冲区,优化深度冲突问题
});
renderer.setSize(width, height);//canvas画布宽高度
renderer.render(scene, camera)//执行一个渲染操作,类比相机拍照咔

// 告诉thressjs你的屏幕的设备像素比
renderer.setPixelRatio(window.devicePixelRatio);//pixel设备像素比
console.log('查看当前屏幕设备像素比', window.devicePixelRatio);

document.getElementById("webgl").appendChild(renderer.domElement);

// 设置编码方式和gltf贴图保持一致  解决渲染颜色偏差的问题
renderer.outputEncoding = THREE.sRGBEncoding


renderer.domElement.style.position = 'absolute'
renderer.domElement.style.top = '0px'
renderer.domElement.style.left = '0px'
renderer.domElement.style.zIndex = -1


let i = 0
function render() {
  if (i < posintsArr.length - 1) {
    camera.position.copy(posintsArr[i])
    camera.lookAt(posintsArr[i + 1])
    i++
  } else {
    i = 0
  }
  stats.update()
  renderer.render(scene, camera);//周期性执行相机的渲染功能,更新canvas画布上的内容
  requestAnimationFrame(render)
}
render()

// 创建一个相机控件对象
const controls = new OrbitControls(camera, renderer.domElement);
controls.target.copy(posintsArr[i + 1])
controls.update()

controls.addEventListener('change', function () {
  renderer.render(scene, camera)//执行一个渲染操作,类比相机拍照咔
})

// onresize事件会在窗口被调整大小时发生
window.onresize = function () {

  const width = window.innerWidth
  const height = window.innerHeight
  camera.aspect = width / height;//全屏情况下:设置观察范围长宽比aspect为窗口宽高比
  camera.updateProjectionMatrix();//相机属性发生变化,需要执行updateProjectionMatrix()方法更新
  renderer.setSize(width, height);//重置渲染器输出画布canvas尺寸
  renderer.render(scene, camera);

}



console.log('posintsArr', posintsArr);

mesh-modelDemo.js

import * as THREE from 'three';

// 三维样条曲线
const path = new THREE.CatmullRomCurve3([
  new THREE.Vector3(-50, 20, 90),
  new THREE.Vector3(-10, 40, 40),
  new THREE.Vector3(0, 0, 0),
  new THREE.Vector3(60, -60, 0),
  new THREE.Vector3(90, -40, 60),
  new THREE.Vector3(120, 30, 30),
]);


// 管道几何体
const geometry = new THREE.TubeGeometry(path, 200, 5, 30)

const texture = new THREE.TextureLoader().load("./model/diffuse.jpg");
texture.wrapS = THREE.RepeatWrapping;//UV坐标U方向阵列模式
texture.repeat.x = 10//纹理沿着管道阵列(UV坐标U方向)
const material = new THREE.MeshBasicMaterial({
  map: texture,
  // color: 0x00ff00,
  side: THREE.DoubleSide,
  // wireframe: true
})

const mesh = new THREE.Mesh(geometry, material)

// 从曲线上等间距获取一定数量的点
const posintsArr = path.getPoints(500)

export { mesh, posintsArr };
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值