threejs在iso上闪退解决方案

iOS 的 WebGL 实现相对严格,某些特性可能不兼容,需要特殊处理,以下是一些优化项

一、设置renderer

this.renderer = new THREE.WebGLRenderer({
    antialias: true, // 启用抗锯齿。设置为 true 可以减少图形锯齿现象,默认值为 false
    alpha: true, // 启用透明背景。设置为 true 时,背景为透明,默认值为 false
    logarithmicDepthBuffer: true, // 启用对数深度缓冲区,以便改善远处物体的深度精度,尤其在场景中有大范围深度差异时。默认值为 false
})
this.renderer.setPixelRatio(2) // 一般均设置为window.devicePixelRatio,但在iso上建议不要设置为window.devicePixelRatio

二、及时释放资源

disposeResources(model) {
    if (!model) return;

    // 1. 从场景移除
    this.scene.remove(model);

    // 2. 遍历所有子对象
    model.traverse((child) => {
        // 释放几何体
        if (child.geometry) {
            child.geometry.dispose();
        }

        // 释放材质 & 纹理
        if (child.material) {
            if (Array.isArray(child.material)) {
                child.material.forEach((material) => {
                    for (const key in material) {
                        if (material[key] && material[key].isTexture) {
                            material[key].dispose(); // 释放纹理
                        }
                    }
                    material.dispose();
                });
            } else {
                for (const key in child.material) {
                    if (child.material[key] && child.material[key].isTexture) {
                        child.material[key].dispose();
                    }
                }
                child.material.dispose();
            }
        }

        // 释放骨骼
        if (child.isSkinnedMesh) {
            child.skeleton.dispose();
        }
    });

    // 3. 删除对象
    model = null;

    // 4. 清理 WebGL 缓存
    if (typeof this.renderer !== "undefined") {
        this.renderer.renderLists.dispose();
    }
}

三、如果使用了png等图片,转成ktx2压缩纹理。

转换方法参考:png图片压缩成ktx2-优快云博客

import { KTX2Loader } from 'three/examples/jsm/loaders/KTX2Loader.js'

this.ktx2Loader = new KTX2Loader()
    .setTranscoderPath('./threelib/basis/')
    .detectSupport(this.renderer)

this.ktx2Loader.loadAsync(url)

四、压缩使用到的glb模型。压缩方法参考 glb压缩方案-优快云博客

import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js'
import { KTX2Loader } from 'three/examples/jsm/loaders/KTX2Loader.js';
import { MeshoptDecoder } from 'three/examples/jsm/libs/meshopt_decoder.module.js';

const dracoLoader = new DRACOLoader()
dracoLoader.setDecoderPath('./threelib/draco/') // 设置解码器的路径,解码器可以在 Three.js 示例中找到

const ktx2Loader = new KTX2Loader()
    .setTranscoderPath('./threelib/basis/') // BasisU 转码器路径
    .detectSupport(this.renderer);

this.loader = new GLTFLoader()
this.loader.setDRACOLoader(dracoLoader) // 将 DracoLoader 设置到 GLTFLoader
this.loader.setKTX2Loader(ktx2Loader);  // 确保在加载前调用 setKTX2Loader
this.loader.setMeshoptDecoder(MeshoptDecoder);  // 确保在加载前调用 setMeshoptDecoder

this.loader.load(url, (obj) => {
    this.scene.add(obj.scene)
})

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值