Unity CanvasRenderer的光照与显示异常问题求助
Unity World Space Canvas 网格渲染问题解决方案
问题1:CanvasRenderer 光照不生效
- 原因:CanvasRenderer 属于UI渲染管线,默认适配无光照的UI Shader,普通3D材质的光照逻辑无法兼容UI渲染流程。
- 解决办法:
- 使用Unity内置的UI/Lit Shader:创建材质时选择
UI/Lit,该Shader专门支持UI元素接收光照。 - 确保Canvas的Render Mode为World Space,场景中存在有效光源(如平行光),同时检查材质的光照参数(如Albedo、法线贴图等)配置正确。
- 注意:CanvasRenderer的光照表现和MeshRenderer存在差异,复杂光照效果可能需要自定义适配UI管线的Shader。
- 使用Unity内置的UI/Lit Shader:创建材质时选择
问题2:添加第二个UI对象后自定义网格消失
- 原因:UI元素的渲染顺序由Canvas的
Sorting Layer和Order in Layer控制,同时CanvasRenderer的材质渲染队列可能与其他UI元素冲突,脚本中频繁创建Mesh也会导致渲染异常。 - 解决办法:
- 调整渲染层级:
- 选中自定义网格的GameObject,在Inspector面板顶部设置
Sorting Layer和Order in Layer,确保它的层级高于其他UI元素(例如将自身Order in Layer设为1,其他UI设为0)。
- 选中自定义网格的GameObject,在Inspector面板顶部设置
- 优化脚本Mesh逻辑:
- 避免在
Update中反复创建新Mesh,改为在Start中初始化Mesh,仅在Canvas尺寸变化时更新顶点数据,修改后的脚本如下:
- 避免在
- 调整渲染层级:
using UnityEngine; public class MeshCanvas : MonoBehaviour { public Material material; Mesh mesh; Vector3[] vertices; int[] triangles; RectTransform canvasRect; private void Start() { canvasRect = FindObjectOfType<Canvas>().GetComponent<RectTransform>(); // 初始化Mesh基础数据 mesh = new Mesh(); vertices = new Vector3[4]; triangles = new int[] { 0, 1, 2, 2, 3, 0 }; mesh.triangles = triangles; var cr = GetComponent<CanvasRenderer>(); cr.materialCount = 1; cr.SetMaterial(material, 0); cr.SetMesh(mesh); } private void Update() { UpdateMeshVertices(); } private void UpdateMeshVertices() { float canvasHeight = canvasRect.rect.height; float canvasWidth = canvasRect.rect.width; vertices[0] = new Vector3(0, 0); vertices[1] = new Vector3(0, canvasHeight); vertices[2] = new Vector3(canvasWidth, canvasHeight); vertices[3] = new Vector3(canvasWidth, 0); mesh.vertices = vertices; mesh.RecalculateNormals(); GetComponent<CanvasRenderer>().SetMesh(mesh); } }
- 统一材质渲染队列:
- 打开材质Inspector面板,将
Render Queue设置为3000(UI默认渲染队列),若需要优先渲染可设为2999,避免与其他UI元素的渲染顺序冲突。
- 打开材质Inspector面板,将
- 检查RectTransform配置:
- 确保自定义网格GameObject的RectTransform锚点、位置设置正确,保证其处于Canvas可视范围内,不会被其他元素遮挡。
内容的提问来源于stack exchange,提问作者ZoKi Mo
相关产品推荐
相关产品推荐

