Quick3D技术问题:纹理与颜色独立设置及动态加载优化
解决思路
1. 拆分材质,按需分配
既然仅200个对象需要纹理,不要给全部5000个对象绑定带纹理的材质。直接在Repeater3D中根据模型数据判断,给需要纹理的对象使用带纹理的材质,其余使用纯颜色材质:
Repeater3D { model: <QAbstractListModel> Model { materials: [ model.needsTexture ? DefaultMaterial { diffuseColor: "green" diffuseMap: Texture { sourceItem: Rectangle { color: "red"; text: "A" } } } : DefaultMaterial { diffuseColor: "green" } ] } }
这种方式下,仅200个对象会创建纹理资源,剩余4800个对象用纯颜色材质,性能会显著提升,且纯颜色材质的diffuseColor可正常生效。
2. 修复State写法,动态切换纹理
你之前用diffuseMap: {}清空纹理的写法错误,Qt Quick 3D中需将其设为null。同时复用同一个纹理实例,通过模型条件控制纹理的启用/禁用:
Repeater3D { model: <QAbstractListModel> Model { id: pieceModel materials: [ DefaultMaterial { id: pieceMaterial diffuseColor: "green" diffuseMap: model.needsTexture ? pieceTexture : null } ] Texture { id: pieceTexture sourceItem: Rectangle { color: "red"; text: "A" } } } }
也可以用State实现更复杂的切换逻辑:
Repeater3D { model: <QAbstractListModel> Model { id: pieceModel materials: [ DefaultMaterial { id: pieceMaterial diffuseColor: "green" } ] Texture { id: pieceTexture sourceItem: Rectangle { color: "red"; text: "A" } } states: [ State { name: "hasTexture" when: model.needsTexture PropertyChanges { target: pieceMaterial diffuseMap: pieceTexture } }, State { name: "noTexture" when: !model.needsTexture PropertyChanges { target: pieceMaterial diffuseMap: null } } ] } }
当diffuseMap设为null时,diffuseColor会正常生效;需要纹理时再绑定回纹理对象。
3. 复用纹理实例,减少资源开销
如果多个需要纹理的对象使用相同的纹理内容(比如都是"A"标签),不要给每个对象创建新的Texture实例,将纹理提出来作为共享资源:
// 全局共享纹理 Texture { id: sharedLabelTexture sourceItem: Rectangle { color: "red"; text: "A" } } Repeater3D { model: <QAbstractListModel> Model { materials: [ DefaultMaterial { diffuseColor: "green" diffuseMap: model.needsTexture ? sharedLabelTexture : null } ] } }
这种方式下无论多少个对象需要纹理,都只创建一个纹理实例,内存占用和初始化时间会大幅降低。
内容的提问来源于stack exchange,提问作者Heiko Tietze
相关产品推荐
相关产品推荐

