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.对比

特性 material sharedMaterial MaterialPropertyBlock
是否实例化材质 是,自动实例化 否,共享材质 不实例化材质,仅覆盖属性
是否影响所有物体 否,只影响当前 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();
        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();
        // 共享同一个 MPB 数据,SRPBatcher 可合批
        renderer.SetPropertyBlock(mpb);
    }

本篇完

你可能感兴趣的:(unity,材质,游戏引擎)