[3.8.6]3d场景透明贴图有问题

透明部分变成了黑色

这张图 也没有正确的显示透明部分

以下为正常: 3.8.5版本…


要怎么处理呀? 还是先不升级呀?

升级好没有安全感… :sob: :sob: :sob: :sob: :sob: :sob: :sob: :sob: :sob:

更新:

需要 暂停一下运行, 再回到游戏 透明贴图才会显示正确:

运行后 透明贴图有黑边


这个时候. 暂停一下运行

发现透明显示又正常了

再回到游戏运行状态, 透明贴图也显示正常了

这里是视频显示:
cocos386_transparent_texture_Bug.zip (3.0 MB)

有官方的朋友给看一下吗?
模型使用的材质是这个

并且会在运行时, 根据材质的名称, 动态修改材质是否需要透明

这个方式, 在3.8.5及以前都是符合预期的.

昨天刚升级到3.8.6 就不起作用了. .
不知道是这个材质的shader发生了改变? 还是动态修改shader的方式不再起作用了. 不懂…
求解惑. :cold_face:

难到是 mr.setSharedMaterial(mat, index) 这段代码, 没有正常的更新材质?

纹理的环绕格式是不是选择了edge,几个格式切换一下看看

找到了原因, 但没有找到一个比较好的解决方案

原因:
meshRenderer.setSharedMaterial(mat, index) 方法, 在3.8.6版本中没有触发材质的更新, 在3.8.5中会正常的触发材质的更新

临时想到的解决方法:
先将meshRenderer.enabled设置为false 再设置为true,来触发材质的更新
meshRenderer.enabled = false; meshRenderer.enabled = true;

有朋友知道更科学一点的更新材质的方法吗?

需求是这样的:
在游戏运行时, 会动态的修改一些材质的参数, 3.8.6之前是通过
meshRenderer.setSharedMaterial(mat, index) 来触发材质的更新的. 3.8.6这个方法失效了

找到了 3.8.53.8.6 setSharedMaterial 方法的实现区别

385

    public setSharedMaterial (material: Material | null, index: number): void {
        if (material && material instanceof MaterialInstance) {
            errorID(12012);
        }
        this._materials[index] = material;
        const inst = this._materialInstances[index];
        if (inst) {
            inst.destroy();
            this._materialInstances[index] = null;
        }
        this._onMaterialModified(index, this._materials[index]);
    }

386

    public setSharedMaterial (material: Material | null, index: number): void {
        if (material && material instanceof MaterialInstance) {
            errorID(12012);
        }

        if (this._materials[index] === material) return;

        this._materials[index] = material;
        const inst = this._materialInstances[index];
        if (inst) {
            inst.destroy();
            this._materialInstances[index] = null;
        }
        this._onMaterialModified(index, this._materials[index]);
    }

386实现中, 多了 if (this._materials[index] === material) return; 这样一个判断

因为我们是在原材质上进行的修改. 所以被这句判断屏蔽掉了.

:cold_sweat:

这个改动是之前解决 2D 粒子崩溃的问题的修复:

设置给 setSharedMaterial 的 material 和 index 都没有变化的情况下,去触发 _onMaterialModified 是不对的,因为 material 对象都没变。

我们考虑一下,提供一个方式(新接口或者为 setSharedMaterial 加个 forceUpdate 的参数)用于触发 _onMaterialModified 内的逻辑。

感谢解惑~ , 不太清楚cocos 中material的实现, 感觉实现的逻辑有些复杂, 之前用threejs的时候 . 修改material的一些参数, 是可以直接看到效果的. 应该是低层实现的思想是不一样的.
但是在3d游戏中, 修改一些材质的参数应该是非常常见的. 而不需要每次调整一个参数都进行销毁与重建. 感觉会很影响效率.
希望可以设计一种简单高效的控制材质参数的接口

添加了forceUpdate参数,设置为true时,会强制刷新materialInstance。

材质这块为了兼容性,3.8.x不会大改了。使用时确实容易犯错,之后会想办法简化下。

1赞