Unity_同个材质多个颜色内存优化——使用MaterialPropertyBlock
Posted avi9111
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Unity_同个材质多个颜色内存优化——使用MaterialPropertyBlock相关的知识,希望对你有一定的参考价值。
其实例子网上已经很多了
但是Unity的廖信,你懂的,如果你能做出来,算我输
- 官方没说明
- 官方没跟进
- 只有国外论坛有很古老的讨论
- 国内踩坑了又不说
- 都是卖课的转发乱说
这样的环境,你还能做对,真见鬼了
.material 本身不是shareMateril,而且setColor() 这个方法是很老的方法了
当年的程序员怎么优化就不知道了
现在统一用 MaterialPropertyBlock 处理
(要深究原理,其实也不难,只要反推一下unity 渲染器源码)
这样的写法也确实可以的
void Start()
MaterialPropertyBlock mpb = new MaterialPropertyBlock();
for (int i = 0; i < transform.childCount; i++)
var render = transform.GetChild(i).GetComponentInChildren<Renderer>();
//render.material.SetColor("_Color",Color.red);
mpb.SetColor("_Color",Color.black);
render.SetPropertyBlock(mpb);
错误一,做做Demo场景还行
但是,哥肥肠幸运的,又踩到坑了
material死活就是占用很多,就是多了很多实例,最后发现问题
var renderer = newBall.transform.Find("Rotator/Skin").GetComponent<MeshRenderer>();
//var mat = renderer.material;//这行千万不能写,写了就出事
//renderer.GetPropertyBlock(mpb);//这行不写也,无所谓
mpb.SetColor("_Color", randomColor.RandomGet());
renderer.SetPropertyBlock(mpb);
错误二,OnEnterTrigger触发:
一开始以为 onEnterTrigger是在 Fixed 线程,和渲染 Update 线程不同的原因
后来查看了几个文章后得到启发
Material Property Blocks will still break batches - You're changing the data being sent to the GPU after all.
The benefit of using property blocks is to organize the data in a way that does not require creating new material instances for small changes.
https://forum.unity.com/threads/mat...09.1939402863.1578323465-101237914.1464905439
The magic of Material Property Blocks – Thomas Mountainborn
必须在 Shader 写上:PerRendererData
// Toony Colors Pro+Mobile 2
// (c) 2014-2019 Jean Moreno
Shader "Toony Colors Pro 2/User/SliderRamp"
Properties
[TCP2HeaderHelp(BASE, Base Properties)]
//TOONY COLORS
[PerRendererData]_Color ("Color", Color) = (1,1,1,1)
错误三:还是毫无作用,和网上根本说的不一样
一个是没有 GPU Instancing, 一个是有的
toon shader 中有这么一段代码
//Lighting-related variables
fixed4 _HColor;
fixed4 _SColor;
half _RampThreshold;
half _RampSmooth;
// Instancing support for this shader. You need to check 'Enable Instancing' on materials that use the shader.
// See https://docs.unity3d.com/Manual/GPUInstancing.html for more information about instancing.
// #pragma instancing_options assumeuniformscaling
UNITY_INSTANCING_BUFFER_START(Props)
// put more per-instance properties here
UNITY_INSTANCING_BUFFER_END(Props)
//TOONY COLORS
[PerRendererData]_Color ("Color", Color) = (1,1,1,1)
最终Shader关键代码
(shader 属性加 【PerRendererData】与否是没有干系的)
#ifdef UNITY_INSTANCING_ENABLED
UNITY_INSTANCING_BUFFER_START(PerDrawSprite)
UNITY_DEFINE_INSTANCED_PROP(fixed4, unity_SpriteRendererColorArray)
UNITY_DEFINE_INSTANCED_PROP(fixed4,_Color)
UNITY_INSTANCING_BUFFER_END(PerDrawSprite)
#define _RendererColor UNITY_ACCESS_INSTANCED_PROP(PerDrawSprite, unity_SpriteRendererColorArray)
#define _ColorX UNITY_ACCESS_INSTANCED_PROP(PerDrawSprite, _Color)
#endif
#ifndef UNITY_INSTANCING_ENABLED
fixed4 _RendererColor;
fixed4 _ColorX;
#endif
//然后就可以在Shader愉快地使用 _ColorX变量了,如
//OUT.color = IN.color * _ColorX * _RendererColor;
参考 出处:
MaterialPropertyBlock_阿赵3D的博客-CSDN博客
Non-instanced properties set for instanced shader - Unity Forum
以上是关于Unity_同个材质多个颜色内存优化——使用MaterialPropertyBlock的主要内容,如果未能解决你的问题,请参考以下文章