three.js操作笔记

第一步导入three,和轨道控制器

// 导入three
import * as THREE from "three";
// 导入轨道控制器
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";

第二步创建场景,相机,设置相机位置,场景中添加相机。

// 1、创建场景
const scene = new THREE.Scene();
// 2、创建相机
const camera = new THREE.PerspectiveCamera(
  75,
  window.innerWidth / window.innerHeight,
  0.1,
  1000
);
// 设置相机位置
camera.position.set(0,10, 10);
// 场景中添加相机
scene.add(camera);

第三步创建几何体,材质合成物体,设置位置,场景中添加物体,还能设置物体的放大,旋转

// 添加物体
// 创建几何体
const cubeGeometry = new THREE.BoxGeometry(1, 1, 1);
const cubeMaterial = new THREE.MeshBasicMaterial({ color: 0xffff00 });
// 根据几何体和材质创建物体
const cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
cube.position.set(0,0,0);
// 将几何体添加到场景中
scene.add(cube);
// 放大
cube.scale.set(1, 1, 1);
// 旋转
cube.rotation.x = -Math.PI/2

物体构建有点模型Points、线模型Line、网格模型Mesh,三种

第四步,初始化渲染器,设置渲染器大小,将渲染器的画面绑定到页面中

// 初始化渲染器
const renderer = new THREE.WebGLRenderer();
// 设置渲染的尺寸大小
renderer.setSize(window.innerWidth, window.innerHeight);
// 将webgl渲染的canvas内容添加到body
document.body.appendChild(renderer.domElement);

第五步,创建轨道控制器,监听鼠标的拖动,时时渲染页面

// 创建轨道控制器
const controls = new OrbitControls(camera, renderer.domElement);

function render() {
  // 使用渲染器,通过相机将场景渲染进来
  renderer.render(scene, camera);
  //   渲染下一帧的时候就会调用render函数
  requestAnimationFrame(render);
}

render();

副助功能:

1.跟踪事件处理动画

const clock = new THREE.Clock();
function render() {
  // 获取自时钟启动后的秒数。
  let time = clock.getElapsedTime();
  // console.log("时钟运行总时长:", time);
  //let deltaTime = clock.getDelta();
  //console.log("两次获取时间的间隔时间:", deltaTime);
  let t = time % 5;
  cube.position.x = t * 1;
 
  // 使用渲染器,通过相机将场景渲染进来
  renderer.render(scene, camera);
  //   渲染下一帧的时候就会调用render函数
  requestAnimationFrame(render);
}

2.导入动画库(单独动画,和组合动画)

// 导入动画库
import gsap from "gsap";
//物体单独的动画
gsap.to(
  cube.rotation, 
  { 
    x: 2 * Math.PI, //x轴旋转360
    duration: 5, //时间几秒
    ease: "power1.inOut" //运动方式
  }
);


//物体的组合动画(x轴来回移动,加旋转)
// 设置动画
var animate1 = gsap.to(cube.position, {
  x: 5,
  duration: 5,
  ease: "power1.inOut",
  //   设置重复的次数,无限次循环-1
  repeat: -1,
  //   往返运动
  yoyo: true,
  //   delay,延迟2秒运动
  delay: 2,
  onComplete: () => {
    console.log("动画完成");
  },
  onStart: () => {
    console.log("动画开始");
  },
});
gsap.to(cube.rotation, { x: 2 * Math.PI, duration: 5, ease: "power1.inOut" });

// 鼠标双击事件
window.addEventListener("dblclick", () => {
  // isActive判断动画的状态
  if (animate1.isActive()) {
    //   进行动画暂停
    animate1.pause();
  } else {
    //   进行动画恢复
    animate1.resume();
  }
});

3,控制场景全屏,和退出全屏

window.addEventListener("dblclick", () => {
  const fullScreenElement = document.fullscreenElement;
  if (!fullScreenElement) {
    //   双击控制屏幕进入全屏,退出全屏
    // 让画布对象全屏
    renderer.domElement.requestFullscreen();
  } else {
    //   退出全屏,使用document对象
    document.exitFullscreen();
  }
});

4.自适应屏幕大小

// 监听画面变化,更新渲染画面
window.addEventListener("resize", () => {
  //   console.log("画面变化了");
  // 更新摄像头
  camera.aspect = window.innerWidth / window.innerHeight;
  //   更新摄像机的投影矩阵
  camera.updateProjectionMatrix();

  //   更新渲染器
  renderer.setSize(window.innerWidth, window.innerHeight);
  //   设置渲染器的像素比
  renderer.setPixelRatio(window.devicePixelRatio);
});

5.创建物体(包含)

//BoxGeometry盒子几何体长宽高
const geometry = new THREE.BoxGeometry( 1, 1, 1 );
const material = new THREE.MeshBasicMaterial( {color: 0x00ff00} );
const cube = new THREE.Mesh( geometry, material );
scene.add( cube );

//SphereGeometry球面几何体 半径 ,水平分段数,竖直分段数
const geometry = new THREE.SphereGeometry( 15, 32, 16 );
const material = new THREE.MeshBasicMaterial( { color: 0xffff00 } );
const sphere = new THREE.Mesh( geometry, material );
scene.add( sphere );

//PlaneGeometry平面缓冲几何体(平面)
const geometry = new THREE.PlaneGeometry( 1, 1 );
const material = new THREE.MeshBasicMaterial( {color: 0xffff00, side: THREE.DoubleSide} );
const plane = new THREE.Mesh( geometry, material );
scene.add( plane );

//CircleGeometry圆形缓冲几何体(圆面,没有背面)
const geometry = new THREE.CircleGeometry( 5, 32 );
const material = new THREE.MeshBasicMaterial( { color: 0xffff00 } );
const circle = new THREE.Mesh( geometry, material );
scene.add( circle );

//ConeGeometry圆锥缓冲几何体  半径,高度,底部面数
const geometry = new THREE.ConeGeometry( 5, 20, 32 );
const material = new THREE.MeshBasicMaterial( {color: 0xffff00} );
const cone = new THREE.Mesh( geometry, material );
scene.add( cone );

//CylinderGeometry圆柱缓冲几何体 顶部半径,底部半径,高度,光滑成都
const geometry = new THREE.CylinderGeometry( 5, 5, 20, 32 );
const material = new THREE.MeshBasicMaterial( {color: 0xffff00} );
const cylinder = new THREE.Mesh( geometry, material );
scene.add( cylinder );

//DodecahedronGeometry十二面缓冲几何体
const radius = 7;  // ui: radius
const geometry = new THREE.DodecahedronGeometry(radius);

//EdgesGeometry边缘几何体
const geometry = new THREE.BoxGeometry( 100, 100, 100 );
const edges = new THREE.EdgesGeometry( geometry );
const line = new THREE.LineSegments( edges, new THREE.LineBasicMaterial( { color: 0xffffff } ) );
scene.add( line );

6.材质

MeshBasicMaterial 不受光照的影响。

MeshLambertMaterial 只在顶点计算光照,

而 MeshPhongMaterial 则在每个像素计算光照, 还支持镜面高光。

const material = new THREE.MeshPhongMaterial({
  color: 0xFF0000,    // 红色 (也可以使用CSS的颜色字符串)
  flatShading: true,
});

//另一种材质
const m1 = new THREE.MeshBasicMaterial({color: 0xFF0000});         // 红色
const m2 = new THREE.MeshBasicMaterial({color: 'red'});            // 红色
const m3 = new THREE.MeshBasicMaterial({color: '#F00'});           // 红色
const m4 = new THREE.MeshBasicMaterial({color: 'rgb(255,0,0)'});   // 红色
const m5 = new THREE.MeshBasicMaterial({color: 'hsl(0,100%,50%)'}); 

7,加载纹理

const loader = new THREE.TextureLoader();
const texture = loader.load('resources/images/flower-1.jpg');

8,加载模型

import {OBJLoader} from '/examples/jsm/loaders/OBJLoader.js';

const objLoader = new OBJLoader();
  objLoader.load('resources/models/windmill/windmill.obj', (root) => {
    scene.add(root);
  });

9,物体产生阴影(移动阴影贴图,有三种光可以投射阴影,分别为DirectionalLight 定向光、SpotLight 聚光灯,)

//告诉渲染器显示阴影贴图;
renderer.shadowMap.enabled = true;
//对需要投影的物体设置castShadow为true;
sphere.castShadow = true; 
//对需要接收投影的物体设置receiveShadow为true;
plane.receiveShadow = true; 
//最后,对可以产生阴影的光源设置castShadow为true;
light.castShadow = true;

10,光源

//1,环境光THREE.AmbientLight
颜色会应用到全局,该光源没有特别的来源方向,也不会产生阴影。通常,该光源不是场景中的唯一光源,因为它会将场景中的所有物体渲染为相同的颜色,它通常与其他光源同时使用,目的是弱化阴影或给场景中添加额外的颜色。使用该光源需要注意,着色一定要趋于保守,否则场景的颜色会过于饱和或者昏暗。
const AmbientLight = new THREE.AmbientLight('#606008')
 scene.add(AmbientLight)

//2,THREE.SpotLight聚光灯光源,是我们经常使用的光源之一。
该光源,是一种具有锥形光源的效果,你可以把它当作手电筒或者灯塔一样,该光源具有方向和角度。

const spotLight = new THREE.SpotLight(0xFFFFFF)
  spotLight.position.set(-40, 40, -15)
  spotLight.castShadow = true
  spotLight.shadow.mapSize = new THREE.Vector2(1024, 1024)
  spotLight.shadow.camera.far = 130
  spotLight.shadow.camera.near = 40
  spotLight.distance = 0
  spotLight.target = plane
  spotLight.angle = 0.4
  spotLight.shadow.camera.fov = 120
  scene.add(spotLight)

如何让聚光灯指向某个点呢?
const target = new THREE.Object3D()
target.position = new THREE.Vector(5, 0, 0)
spotLiht.target = target

//3,THREE.PointLight点光源,是一种单点发光,照射所有方向的光源。
点光源也有一些属性:
const pointLigh = new THREE.PointLight('#ccffcc')
  pointLigh.dispose = 100
  pointLigh.position.set(3, 0, 10)
  scene.add(pointLigh)

//4,THREE.HemisphereLight是一种特殊光源,它被称为自然光。因为大自然的光线很复杂,有的来自物体的折射等等,很难模拟。所以,THREE.HemisphereLight 的出现,很好的解决了这一问题。
// 自然光
  const hemiLight = new THREE.HemisphereLight(0x0000ff, 0x00f00, 0.6)
  hemiLight.position.set(0, 500, 0)
  scene.add(hemiLight)

//5. THREE.AreaLight
定义一个长方形发光区域。
const areaLight = new THREE.AreaLight(0xff0000, 500, 4, 10)
  areaLight.position.set(-10, 10, -35)
  scene.add(areaLight)
该对象三个参数为 颜色、光强度、宽度、高度。

//6,镜头光晕
当你对着太阳,或者非常明亮的光源拍照时,会出现镜头光晕。当然,Three.js 也支持这样的效果。首先,我们需要创造镜头光晕的对象。
import Lensflare from 'three/examples/jsm/objects/Lensflare'
const lensflare = new Lensflare(texture, size, distance, color)

补充详情,总结

2. THREE.SpotLight

  • 9
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值