• 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)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    在这里插入图片描述

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

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

    在这里插入图片描述

    创建地面网格模型:

    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)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    接收阴影:

    在这里插入图片描述

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

    在这里插入图片描述

    使用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)
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    在这里插入图片描述

    注意调用的时候异步调用

    最终涌泉效果:

    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
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

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

    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
    
    • 1
    • 2

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

    1. dirLight.shadow.camera.zoom = 2//?
  • 相关阅读:
    8. C#多线程基础概念
    C#导出本机Win32native dll
    二叉树题目:层数最深叶子结点的和
    TVM 中文站正式上线!最全机器学习模型部署「参考书」它来了
    Dotnet工具箱:开源、免费的纯前端工具网站,带你探索10大工具分类和73个实时在线小工具
    基于 Bresenham 算法画圆
    003.文件描述符、重定向
    ES6中set、map、DOM classList的基础用法
    python安装imblearn一直找不到包的解决方法
    python ToastNotifier TypeError got Nonetype
  • 原文地址:https://blog.csdn.net/lqiqil/article/details/126969868