当前位置: 首页 > news >正文

Unity知识点-Renderer常用材质变量

        本篇总结了Unity中renderer的3种常用的材质相关的变量:renderer.material,renderer.sharedMaterial,renderer.MaterialPropertyBlock。以及三者对SRPBatcher的影响。

一.介绍及对比

1.概念介绍

1.material

定义:material 是Render组件(如MeshRenderer)的实例化材质。

特点

访问renderer.material会自动复制一份材质实例(如果之前是共享的),这样你修改这个材质只影响当前物体,不会影响其他使用同一材质的物体。适合给单个物体做特定修改,比如改颜色、贴图等。

性能:实例化材质会额外占用内存,修改频繁会增加GC压力。

2. sharedMaterial

定义:sharedMaterial 是Render使用的共享材质资源,多个物体可以共用同一份材质实例。

特点

修改sharedMaterial会影响所有使用该材质的物体。适合修改全局材质,比如编辑场景中统一的材质。

性能:不会产生额外实例,节省内存。

3.materialPropertyBlock

定义:materialPropertyBlock(简称MPB)是用于临时覆盖材质属性的一个工具,可以在不实例化材质的情况下,给单个 Renderer 设置不同的材质属性(如颜色、纹理、浮点参数等)。

特点

不会创建新的材质实例,也不会修改共享材质本身。

只影响当前 Renderer 的渲染效果,方便批处理且性能友好。

适用于需要大量物体同用一个材质,但表现出不同属性(颜色、亮度等)时使用。

var mpb = new MaterialPropertyBlock();
renderer.GetPropertyBlock(mpb);
mpb.SetColor("_Color", Color.green);
renderer.SetPropertyBlock(mpb);

2.对比

特性materialsharedMaterialMaterialPropertyBlock
是否实例化材质是,自动实例化否,共享材质不实例化材质,仅覆盖属性
是否影响所有物体否,只影响当前 Renderer是,影响所有使用该材质物体否,只影响当前 Renderer
适用场景单独修改某个物体的材质属性修改所有使用该材质的物体时(全局修改)

大批量物体不同属性但共用材质的场景

单个物体临时修改材质参数,且避免实例化材质

性能影响较大,可能导致内存和GC开销较小较小,性能友好
数据存储位置独立材质实例资源文件临时GPU参数覆盖
注意避免频繁使用,适合少量特殊对象慎用,通常用于编辑器或者全局风格调整尽量让共享一组参数的物体使用相同 MPB 数据,避免每个物体都用不同数据

二.分别对SRPBatcher的影响

1.render.material

访问render.material 会实例化材质(clone),导致该物体的材质不再是共享的。

实例化材质意味着该物体拥有自己独立的材质状态,哪怕其他物体材质完全一样,也不再视为“同一材质”。

renderer.material.color = Color.red;

访问 render.material会自动给该 Renderer 创建一份新的材质实例(也就是材质的“实例化”),然后返回这份实例。

因此,SRPBatcher 无法将该物体与使用共享材质的物体合批,会破坏批处理。

底层原因:SRPBatcher 判断材质是否相同通常基于材质实例(Material instance)是否完全匹配。实例化后材质地址不同,状态不一致,批处理被打断

2. render.sharedMaterial

多个物体共享同一个sharedMaterial,材质状态完全一致。

这符合 SRPBatcher 的批处理条件,有利于批处理的实现。(也是一种享元思想在资源内存方面的体现)

因此,使用sharedMaterial是保证 SRPBatcher 批处理有效的前提之一。

3.MaterialPropertyBlock 

MaterialPropertyBlock可以在不实例化材质的前提下,临时覆盖单个 Renderer 的材质参数

Unity 的 SRPBatcher 对部分类型的属性(例如可批处理的常量缓冲区参数)支持合批处理,即使有不同的MaterialPropertyBlock。

但如果 MPB 修改了不能合批的参数(比如部分纹理资源),也可能导致批处理失败。

总体来说,合理使用 MPB 能最大化利用 SRPBatcher 性能优势,同时实现物体个性化表现。

不合理用法:多个物体使用不同的MPB

 foreach (var cube in cubes){var renderer = cube.GetComponent<Renderer>();var mpb = new MaterialPropertyBlock();// 每个物体颜色不同,都会生成不同的MPB数据mpb.SetColor("_Color", Random.ColorHSV());  renderer.SetPropertyBlock(mpb);}

合理用法:统一MPB数据

   var mpb = new MaterialPropertyBlock();mpb.SetColor("_Color", color);  // 所有物体共享同一个颜色参数foreach (var cube in cubes){var renderer = cube.GetComponent<Renderer>();// 共享同一个 MPB 数据,SRPBatcher 可合批renderer.SetPropertyBlock(mpb);}

本篇完

相关文章:

  • 《Effective Python》第十章 健壮性——显式链接异常,让错误追踪更清晰的艺术
  • C#语言入门-task4 :C#语言的高级应用
  • 神经网络的概念和案例
  • Django导入错误:`from django.conf.urls import url` 的终极解决方案
  • ssh -T git@github.com失败后解决方案
  • Vulkan模型查看器设计:相机类与三维变换
  • 贪心算法之集合覆盖问题
  • 代码随想录|图论|08孤岛的总面积
  • Webpack 自定义插件开发指南:构建流程详解与实战开发全攻略
  • Apache Kafka 面试应答指南
  • 《人间词话》PPT课件
  • 免费无广告PDFCreator:虚拟打印软件一键转 PDF/PNG/JPG
  • K8s port、targetPort和nodePort区别
  • AI歌手Yuri出道:GenAI,透露着新的AI产业机遇?
  • 【水印论文阅读1】将水印规则的定义域从离散的符号空间转移到连续的语义空间
  • 在shell中直接调用使用R
  • Vite 打包原理详解 + Webpack 对比
  • 电子电气架构 --- 涵盖“诊断与 ECU 平台”领域特有项目要求(下)
  • FPGA 40G到100G光纤数据传输QSFP
  • Netty入门案例:简单Echo服务器(同步)