banner
banner
banner
NEWS LETTER

threeJS-修改模型的child

Scroll down

创建3D贺卡的案例

  • 加载模型后通过回调函数来设置模型
  • 获取模型的场景
    1
    const model = gltf.scene 
  • 模型的缩放大小
    1
    model.scale.set(x,y,z)
  • 遍历模型 这里能拿到模型的部件
    • 注:Mesh是由几何体和材质组成的网格,而网格才能渲染在屏幕上
      1
      2
      3
      4
      5
      6
      model.traverse((child) => {
      child.Mesh // 获取部件的网格
      child.name // 获取部件的名称,可以用来控制对应部件要展示什么效果
      child.visible = true; // 设置部件是否渲染,false不渲染
      })

  • 把模型添加到场景中 最重要
    1
    scene.add(model) 

基础语法

设置模型/网格在场景的位置(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一样

直射光 — 场景中物理材质一定要有,模拟阳光

  • 创建直射光并添加到场景中
    1
    2
    const light = new THREE.DirectionalLight(灯光颜色, 强度默认1)
    scene.add(light)

点光源

作用类似于让屋子亮灯,屋子开了个门,门口会投射灯光

  • 添加点光源
    1
    const pointlight = new THREE.PointLight(光源的颜色, 光的强度)
  • 适当调整位置
  • 设置灯光投射阴影
    1
    pointlight.castShadow = true
  • 设置渲染器允许光源有阴影
    1
    renderer.shadowMap.enabled = true
  • 在模型中设置允许接受阴影和投射阴影并将光源添加到场景中
    1
    2
    3
    4
    5
    if (child.Mesh) { 
    child.receiveShadow = true
    child.castShadow = true
    }
    scene.add(pointlight)

创建一个点光源组

这是一个由球转载点光源的组

  • 创建一个光源组并调正光源组的位置
    1
    2
    const pointLightGroup = new THREE.Group()
    pointLightGroup.position.set(2, 4, 2)
  • 设置球体的半径, 空数组, 并通过循环产生n个球体光源
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    const radius = 3
    let pointLightArr = []
    for (let i = 0; i< n; i++) {
    const sphereGeometry = new THREE.SphereGeometry(0.2, 32, 32) // 创建球体
    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
    6
    7
    sphere.position.set(
    radius * Math.cos((i * 2 * Math.PI) /3), // x
    Math.cos((i * 2 * Math.PI) / 3), // y
    radius * Math.sin((i * 2 * Math.PI) /3), // z
    )
    sphere.add(pointLight)
    pointLightGroup.add(sphere)
  • 在场景中添加点光源组
    1
    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, // 旋转1周
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)
)
})
}
})

水面

  • 引用水的模型包
    1
    import { Water} from "three/examples/jsm/objects/Water2"
  • 创建一个圆的平面
    1
    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度, 然后添加到场景中
    1
    2
    water.rotation.x = -Math.PI / 2
    scene.add(water)

色调映射

…renderer.xxx

相机位置与文字切屏

  • 使用补间动画移动相机
    • 调用gasp的timeline()创建两个变量
  • 封装一个相机移动函数,并使用这两个变量分别控制相机要移动的位置和聚焦,并设置xyz,duration和ease
  • 写一个对象数组,其中包括文本信息和回调函数,回调函数中调用相机移动函数,并给予坐标
  • 监听鼠标滚轮事件判断滚轮是否向下滚动,
    • 是,变量+1并判断只有当变量小于对象数组的长度-1时,才加一,否则为0;
    • 否,直接调用对象数组的第变量对象的回调函数。
    • 建议增加防抖操作,防抖变量为true返回,鼠标滚动时,延时一定时间让防抖变量为false
  • 最后在页面中通过遍历来展示文本,在最外层则通过修改 translate3d 来控制滚轮动时文本页跟着变。
    1
    :style="{transform: 'translate3d(0, ${-index*100}vh, 0)'}"

创建漫天星星

  • 通过InstancedMesh来创建100个以上的球的实例
  • 随机分配到天上
  • `创建开始位置和结束位置的空数组
  • 通过for循环,获取随机的x,y,z 并添加到开始数组中
  • 创建一个矩阵,并设置位置,然后设置实例的矩阵
  • 添加到场景中,
  • 使用贝塞尔曲线话爱心路径
  • 根据路径获取点getPoint
    • 通过for循环获取曲线的每一个点,并添加到结束数组,如果图形太大可以给x,y乘以一个小数

  • 创建爱心动画
    • 定义一个参数,设置时间为0
      • 然后使用补间动画从0执行到1,更新时是实时获取开始数组的当前位置+ (结束位置-开始位置)* 参数的时间
      • 创建一个矩阵,并设置位置,然后设置实例的矩阵
    • 设置实例的矩阵需要更新
  • 创建复原的函数
    • 与爱心动画一样,只需要把开始数组替换为结束数组,结束数组替换为开始数据即可
  • 在对象数组中需要呈现的回调函数中调用爱心动画函数
  • 在监听事件中,当变量要设置为0 时添加复原函数
其他文章
cover
TS-实用类 Utility Types
  • 24/11/01
  • 11:40
  • TypeScript
cover
threeJS-物体的水晶效果
  • 24/11/01
  • 11:01
  • ThreeJS
目录导航 置顶
  1. 1. 创建3D贺卡的案例
    1. 1.1. 基础语法
      1. 1.1.1. 设置模型/网格在场景的位置(position)
      2. 1.1.2. 设置物体旋转(rotation)
      3. 1.1.3. 设置模型/网格相对于原来位置的移动距离(translate) – 用法同position一样
    2. 1.2. 直射光 — 场景中物理材质一定要有,模拟阳光
    3. 1.3. 点光源
    4. 1.4. 创建一个点光源组
    5. 1.5. 使用补间动画让光源组旋转,上下移动
    6. 1.6. 水面
    7. 1.7. 色调映射
    8. 1.8. 相机位置与文字切屏
    9. 1.9. 创建漫天星星
请输入关键词进行搜索