Three使用OimoPhysics实现物体相关物理特性实例

基础环境搭建:

在这里插入图片描述

InstancedMesh()创建的立方体物品集合:

    boxes = new THREE.InstancedMesh(
        new THREE.BoxGeometry(0.1, 0.1, 0.1),
        new THREE.MeshLambertMaterial(),
        100
    )
    const matrix = new THREE.Matrix4()
    const color = new THREE.Color()
    for (let i = 0; i < boxes.count; i++) {
        matrix.setPosition(
            Math.random() - 0.5,//x:-0.5~0.5
            Math.random() * 2,//y:0~2
            Math.random() - 0.5//z:0.5~0.5F
        )
        boxes.setMatrixAt(i, matrix)
        boxes.setColorAt(i, color.setHex(Math.random() * 0xffffff))
    }
    scene.add(boxes)

在这里插入图片描述

加入平行光能显示明显的阴暗面:

平行光是沿着特定方向发射的光。这种光的表现像是无限远,从它发出的光线都是平行的。常常用平行光来模拟太阳光的效果;太阳足够远,因此我们可以认为太阳的位置是无限远,所以我们认为从太阳发出的光线也都是平行的。

在这里插入图片描述

创建地面网格模型:

ShadowMaterial材质可以接收阴影,但在其他方面完全透明。
.color : Color
设置接收阴影的颜色,默认为黑色 (0x000000).

    floor = new THREE.Mesh(
        new THREE.BoxGeometry(10, 1, 10),
        new THREE.ShadowMaterial({ color: 0x111111 })
    )
    floor.position.set(0, -1, 0)
    scene.add(floor)

接收阴影:

在这里插入图片描述

同样的方法创建球体物品集合:

在这里插入图片描述

使用OimoPhysics.js实现物体的自由落体及物体间的相互作用

OimoPhysics是一个轻量级的 3D 物理引擎,网上相关资料好像不是很多。https://www.mianshigee.com/project/lo-th-Oimo-js

import { OimoPhysics } from 'three/examples/jsm/physics/OimoPhysics'
...
async function enablePhysics() {
    physics = await OimoPhysics()
    physics.addMesh(floor)
    physics.addMesh(boxes, 1)
    physics.addMesh(spheres, 1)
}

在这里插入图片描述

注意调用的时候异步调用。

最终涌泉效果:

let position = new THREE.Vector3()
...
    let index = Math.floor(Math.random() * boxes.count)
    position.set(0, Math.random() + 1, 0)
    physics.setMeshPosition(boxes, position, index)
    index = Math.floor(Math.random() * spheres.count)
    position.set(0, Math.random() + 1, 0)
    physics.setMeshPosition(spheres, position, index)

在这里插入图片描述
改进:

  1. 初始化渲染器加入renderer.outputEncoding = THREE.sRGBEncoding,颜色会变浅。

.outputEncoding : number
定义渲染器的输出编码。默认为THREE.LinearEncoding

可能的解释:By setting renderer.outputEncoding = THREE.sRGBEncoding you tell the renderer to convert the final color value in the fragment shader from linear to sRGB color space. Consequently, you also have to tell the renderer when textures hold sRGB encoded data. You do this by assigning THREE.sRGBEncoding to the encoding property of textures. THREE.GLTFLoader does this automatically for all color textures. But when loading textures manually, you have to do this by yourself.
相关链接

在这里插入图片描述

  1. 提高画质和性能
    boxes.instanceMatrix.setUsage(THREE.DynamicDrawUsage)//update every frame
    spheres.instanceMatrix.setUsage(THREE.DynamicDrawUsage)//update every frame

.instanceMatrix : InstancedBufferAttribute
表示所有实例的本地变换。 如果你要通过 .setMatrixAt() 来修改实例数据,你必须将它的 needsUpdate 标识为 true 。
OpenGL相关好像有点复杂:
在这里插入图片描述

  1. dirLight.shadow.camera.zoom = 2//?
  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值