修改模型的child(创建3D贺卡的案例)
- 加载模型后通过回调函数来设置模型
- 获取模型的场景
- 模型的缩放大小
- 遍历模型 – 这里能拿到模型的部件
- 注:Mesh是由几何体和材质组成的网格,而网格才能渲染在屏幕上
1 2 3 4 5 6
| model.traverse((child) => { child.Mesh child.name child.visible = true; })
|
- 把模型添加到场景中 – 最重要
基础语法
设置模型/网格在场景的位置(position)
1 2 3
| mesh.position.set(x,y,z) mesh.position.x = x mesh.position = new THREE.Vector3(x,y,z)
|
设置物体旋转(rotation)
- 表示的是绕x/y/z轴旋转的弧度
1 2 3
| mesh.rotation.set(x,y,z) mesh.rotation.x = x mesh.rotation = new THREE.Vector3(x,y,z)
|
设置模型/网格相对于原来位置的移动距离(translate) – 用法同position一样
直射光 — 场景中物理材质一定要有,模拟阳光
创建直射光
- const light = new THREE.DirectionalLight(灯光颜色, 强度默认1)
添加到场景中
点光源
作用类似于让屋子亮灯,屋子开了个门,门口会投射灯光
添加点光源
- const pointlight = new THREE.PointLight(光源的颜色, 光的强度)
适当调整位置
设置灯光投射阴影
- pointlight.castShadow = true
设置渲染器允许光源有阴影
- renderer.shadowMap.enabled = true
在模型中设置允许接受阴影和投射阴影
1 2 3 4
| if (child.Mesh) { child.receiveShadow = true child.castShadow = true }
|
创建一个点光源组
这是一个由球转载点光源的组
创建一个光源组
- const pointLightGroup = new THREE.Group()
调正光源组的位置
- pointLightGroup.position.set(2, 4, 2)
设置球体的半径
设置一个空数组
通过循环产生n个球体光源
- for (let i = 0; i< n; i++) {}
在循环中创建球体
- const sphereGeometry = new THREE.SphereGeometry(0.2, 32, 32)
创建球体的材质 — 物理材质(会通过周围的灯光映射颜色)
1 2 3 4 5
| const sphereMaterial = new THREE.MeshStandardMaterial({ color: 0xffffff, emissive: 0xffffff, emissiveIntensity: 10 })
|
创建网格
- const sphere = new THREE.Mesh(sphereGeometry, sphereMaterial)
创建点光源
- const pointLight = new THREE.PointLight(0xffffff, 10)
创建好的添加到数组中
- pointLightArr.push(sphere)
设置球体的位置
1 2 3 4 5
| sphere.position.set( radius * Math.cos((i * 2 * Math.PI) /3), Math.cos((i * 2 * Math.PI) / 3), radius * Math.sin((i * 2 * Math.PI) /3), )
|
在球体中添加点光源
将球体添加到组中
- pointLightGroup.add(sphere)
在场景中添加点光源组
- scene.add(pointLightGroup)
使用补间动画让光源组旋转,上下移动
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| let options = { angle: 0} gsap.to(options, { angle: 2 * Math.PI, duration: 10, repeat: -1, ease: "linear", onUpdate: () => { pointLightGroup.rotation.y = options.angle pointLightArr.forEach((item, index) => { item.position.set( radius * Math.cos((index * 2 * Math.PI) / 3), Math.cos((index * 2 * Math.PI) / 3 + options.angle *5), radius * Math.sin((index * 2 * Math.PI) / 3) ) }) } })
|
水面
引用水的模型包
- import { Water} from “three/examples/jsm/objects/Water2”
创建一个圆的平面
- const waterGeometry = new THREE.CircleGeometry(半径,分段默认32)
创建水面
1 2 3 4 5 6 7
| const water = new Water(waterGeometry, { textureWidth: 1024, textureHeight: 1024, color: 0xededed, flowDirection: new THREE.Vector2(1,1), scale:100, })
|
由于水面创造出来是垂直于模型,需旋转90度
- water.rotation.x = -Math.PI / 2
添加到场景中
色调映射
…renderer.xxx
相机位置与文字切屏
- 使用补间动画移动相机
- 封装一个相机移动函数,并使用这两个变量分别控制相机要移动的位置和聚焦,并设置xyz,duration和ease
- 写一个对象数组,其中包括文本信息和回调函数,回调函数中调用相机移动函数,并给予坐标
- 监听鼠标滚轮事件判断滚轮是否向下滚动,
- 是,变量+1并判断只有当变量小于对象数组的长度-1时,才加一,否则为0;
- 否,直接调用对象数组的第变量对象的回调函数。
- 建议增加防抖操作,防抖变量为true返回,鼠标滚动时,延时一定时间让防抖变量为false
- 最后在页面中通过遍历来展示文本,在最外层则通过
:style="{transform: 'translate3d(0, ${-index*100}vh, 0)'}"
来控制滚轮动时文本页跟着变。
创建漫天星星
通过InstancedMesh来创建100个以上的球的实例
随机分配到天上
- 创建开始位置和结束位置的空数组
- 通过for循环,获取随机的x,y,z 并添加到开始数组中
- 创建一个矩阵,并设置位置,然后设置实例的矩阵
添加到场景中,
使用贝塞尔曲线话爱心路径
根据路径获取点getPoint
- 通过for循环获取曲线的每一个点,并添加到结束数组,如果图形太大可以给x,y乘以一个小数
创建爱心动画
- 定义一个参数,设置时间为0
- 然后使用补间动画从0执行到1,更新时是实时获取开始数组的当前位置+ (结束位置-开始位置)* 参数的时间
- 创建一个矩阵,并设置位置,然后设置实例的矩阵
- 设置实例的矩阵需要更新
创建复原的函数
- 与爱心动画一样,只需要把开始数组替换为结束数组,结束数组替换为开始数据即可
在对象数组中需要呈现的回调函数中调用爱心动画函数
在监听事件中,当变量要设置为0 时添加复原函数