You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity建筑AR应用:门窗导出后材质纹理全白问题求助

问题描述

我们正在开发一款支持用户创建建筑房屋模型,并导出至移动端AR应用进行实景展示的程序。目前遇到问题:当门窗附着于墙体时,导出前模型显示正常,但在AR端查看时门窗的材质与纹理完全变白。

效果对比

  • 导出前:门窗与墙体的材质、纹理显示正常,贴合墙体呈现正确视觉效果
  • 导出后:门窗的材质与纹理完全丢失,仅显示白色模型轮廓

相关代码

SetRenderQueue.cs

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Linq;

[AddComponentMenu("Rendering/SetRenderQueue")]

public class SetRenderQueue : MonoBehaviour {

    public Shader wallShader;
    List<Renderer> walls = new List<Renderer>();

    [SerializeField]
    //protected int[] m_queues = new int[] { 3000 };

    protected void Awake() {
        Material[] materials = (from renderer in GetComponentsInChildren<Renderer>() select renderer.materials).SelectMany(i => i).ToArray();
        for (int i = 0; i < materials.Length; i++) {
            materials[i].renderQueue = 2500;
        }
    }

    private void FixedUpdate() {
        if (walls.Count != 0) {
            foreach (Renderer renderer in walls) {
                Material[] materials = renderer.materials;
                for (int i = 0; i < materials.Length; i++) {
                    materials[i].renderQueue = 2502;
                    //materials[i].shader = wallShader;
                }
            }
        }
    }
    void OnTriggerEnter(Collider other) {
        if (other.gameObject.tag == "Wall" || other.gameObject.tag == "RoofWall") {
            foreach (Renderer renderer in other.gameObject.GetComponentsInChildren<Renderer>()) {
                walls.Add(renderer);
                Material[] materials = renderer.materials;
                for (int i = 0; i < materials.Length; i++) {
                    materials[i].renderQueue = 2502;
                    //materials[i].shader = wallShader;
                }
            }
            other.gameObject.layer = 10;
            foreach(Transform wall in other.gameObject.transform) {
                wall.gameObject.layer = 10;
            }
        }
    }

}

Door_Window.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[RequireComponent(typeof(BoxCollider))]
[RequireComponent(typeof(CreateDepthMask))]
[RequireComponent(typeof(SetRenderQueue))]
public class Door_Window : Item
{
    public bool onFloor;
    public bool onWall;
    public bool onObject;
    public bool onCeiling;

    public DWType dwType;
    public Vector3 position;

    // Use this for initialization
    void Start() {

    }
    private void OnCollisionEnter(Collision collision) {
        if (collision.gameObject.tag == "Player") {
            gameObject.GetComponent<Collider>().enabled = false;
        }
    }

    private void OnCollisionExit(Collision collision) {
        if (collision.gameObject.tag == "Player") {
            gameObject.GetComponent<Collider>().enabled = true;
        }
    }
}
public enum DWType { Door, Window };

问题排查与解决方案

1. RenderQueue动态修改导致的序列化异常

代码中FixedUpdate持续修改墙体材质的RenderQueue,会导致材质实例反复被修改,导出时无法正确序列化材质状态,AR端加载时丢失纹理引用。

修复:

  • 删除FixedUpdate中的RenderQueue修改逻辑,仅在OnTriggerEnter中设置一次即可
  • 若必须动态设置RenderQueue,修改后调用materials[i].SetDirty();确保Unity序列化材质变更

2. 材质实例化导致资源丢失

调用renderer.materials会创建材质的临时实例,这些实例未被纳入导出资源包,AR端无法加载对应的纹理。

修复:

  • 改用renderer.sharedMaterials修改原始材质(注意:会影响所有使用该材质的对象)
  • 或确保动态创建的材质实例被添加到AssetBundle的依赖列表中

3. Shader兼容性问题

门窗使用的Shader可能不支持移动端AR环境,导致纹理采样失败。

修复:

  • 将门窗材质的Shader替换为Unity内置的Mobile/Standard或AR平台推荐的Shader(如AR Foundation对应的Shader)
  • 检查Shader中是否有仅支持桌面平台的特性(如某些光照模型),替换为移动端兼容版本

4. 组件冲突排查

Door_Window同时挂载SetRenderQueue和CreateDepthMask,可能存在深度渲染逻辑冲突。

修复:

  • 暂时禁用CreateDepthMask组件,导出模型测试AR端显示是否正常,确认是否为该组件导致的问题
  • 若CreateDepthMask是必要组件,检查其是否修改了门窗材质的ZWrite、ZTest或AlphaTest属性,调整这些属性确保纹理正常渲染

5. 导出资源完整性检查

  • 检查导出设置,确保门窗的纹理、材质资源被包含在导出包内
  • 使用Unity的AssetBundle Browser工具检查资源依赖,确认所有关联资源都被正确打包

内容的提问来源于stack exchange,提问作者ferb

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 09:35:17