您的位置:首页 > 房产 > 家装 > 苏州服务器托管排名_海口网站提升排名_拉新项目官方一手平台_品牌软文范文

苏州服务器托管排名_海口网站提升排名_拉新项目官方一手平台_品牌软文范文

2025/4/21 20:55:45 来源:https://blog.csdn.net/wodownload2/article/details/147333701  浏览:    关键词:苏州服务器托管排名_海口网站提升排名_拉新项目官方一手平台_品牌软文范文
苏州服务器托管排名_海口网站提升排名_拉新项目官方一手平台_品牌软文范文

参考网址:

Unity MaterialPropertyBlock 正确用法(解决无法合批等问题)_unity_define_instanced_prop的变量无法srp合批-CSDN博客

URP | 基础CG和HLSL区别 - 哔哩哔哩 (bilibili.com)

【直播回放】Unity 批处理/GPU Instancing/SRP Batcher_哔哩哔哩_bilibili

合批分为四种:

静态合批

动态合批

gpu instance

srp batch

四个优先级排序:

按照出现的历史时间,可以大致这么排序:静态合批和动态合批较早;之后才有了gpu instance,srp batch

按照程序参与度来说:静态合批、动态合批、srp batch只需要勾选一下即可,而gpu instance则需要按照指定的约束编写shader,开启材质gpu instance功能。

从效率来说:静态合批是在build的时候,内存占用大,效率高;动态合批是在运行时的合批,消耗cpu;gpu instance是针对大量同mesh的物体的场景;而srp batch则是针对同shader的不同变体进行合批。

从优先级来说:srp batch》gpu instance

1)静态合批

静批条件:材质球相同+mesh可以不同

相同材质球、相同shader、勾选static、是在build的时候就合并为大的mesh。

mesh可以不同,在build成exe或者移动的可执行的文件的时候,就被合并成了一个大的mesh,在frame debugger中看不到合并结果,只有build之后,才能看到合并结果,通过render doc截帧才能看到。

在player settings的设置中,勾选静态合批。

2)动态合批

动批条件:材质球相同+mesh可以不同(但是必须顶点数小于300)

动态合批,在unity较早的版本,是可以在player settings中找到,并勾选,但是在新版本的unity中,urp的管线中,找不到这个勾选项了。而要在,管线配置中,勾选才行,默认是不勾选的。

默认是不勾选的原因是,dynamic batch是动态合批的,也就是在运行的时候,进行合并mesh操作。这个可能会对cpu有一定的损耗,故要权衡。

如上图所示,圆柱体和立方体,相同的材质球,相同的shader,不同的mesh可以动态合批。

但是动态合批有个特点是,当顶点数量超过300的时候,动批失败,比如将圆柱体改为胶囊体之后,动批失败。

3)gpu instance

instance条件:材质球相同+mesh相同

如下图所示,cube1和cube2是相同的mesh,相同的材质球才能被instance。

如果将cube2缓存是胶囊体,则和cube1不能被instance。

cube1和cube3无法instance,是因为他们使用的材质球不同,虽然shader相同。

shader更改为如下内容:

Shader "Unlit/xxxx"
{
Properties
{//_MainTex ("Texture", 2D) = "white" {}[PerRendererData] _BaseColor("Color", Color) = (1,1,1,1)
}
SubShader
{Tags { "RenderType"="Opaque" }LOD 100Pass{CGPROGRAM#pragma multi_compile_instancing#pragma enable_d3d11_debug_symbols#pragma vertex vert#pragma fragment frag// make fog work#pragma multi_compile_fog#include "UnityCG.cginc"//float4 _BaseColor;// 如果既要srp batch又要兼顾instance就得这么写// UNITY_INSTANCING_BUFFER_START(UnityPerMaterial)//     UNITY_DEFINE_INSTANCED_PROP(float4, _BaseColor)// UNITY_INSTANCING_BUFFER_END(Props)struct appdata{float4 vertex : POSITION;//float2 uv : TEXCOORD0;UNITY_VERTEX_INPUT_INSTANCE_ID};struct v2f{//float2 uv : TEXCOORD0;UNITY_FOG_COORDS(1)float4 vertex : SV_POSITION;UNITY_VERTEX_INPUT_INSTANCE_ID};//如果只支持instance,可以这么写UNITY_INSTANCING_BUFFER_START(Props)UNITY_DEFINE_INSTANCED_PROP(float4, _BaseColor)UNITY_INSTANCING_BUFFER_END(Props)// sampler2D _MainTex;// float4 _MainTex_ST;v2f vert (appdata v){v2f o;//setup instance idUNITY_SETUP_INSTANCE_ID(v);UNITY_TRANSFER_INSTANCE_ID(v, o);//calculate the position in clip space to render the objecto.vertex = UnityObjectToClipPos(v.vertex);return o;}float4 frag (v2f i) : SV_Target{//setup instance idUNITY_SETUP_INSTANCE_ID(i);//get _Color Property from bufferfixed4 color = UNITY_ACCESS_INSTANCED_PROP(Props, _BaseColor);//Return the color the Object is rendered inreturn color;}ENDCG}
}}

UNITY_INSTANCING_BUFFER_START(UnityPerMaterial)

UNITY_DEFINE_INSTANCED_PROP(float4, _BaseColor)

UNITY_INSTANCING_BUFFER_END(Props)

这个必须是UnityPerMaterial的常量buffer,否则不能同时支持srp batch功能。

加上:multi_compile_instancing

在顶点和片段中加上instance的宏处理才行。

从图上可以看出Cube1和Cube1_1被instance了,而另外两个cube因为深度的原因被instance的两个cube打断了。这里Cube1和Cube1_1使用的是相同的材质球,但是属性不一样。同时开启材质球的instace开关:

测试2使用的是:材质属性块

using UnityEngine;public class NewBehaviourScript : MonoBehaviour
{public GameObject m_cube1;public Color m_color;private Material m_material1;private MaterialPropertyBlock propertyBlock;void Start(){if (propertyBlock == null)propertyBlock = new MaterialPropertyBlock();propertyBlock.SetColor("_BaseColor", m_color);MeshRenderer meshRenderer = m_cube1.GetComponent<MeshRenderer>();meshRenderer.SetPropertyBlock(propertyBlock);}
}

这个脚本就是将黄色和蓝色的cube在Start中改变为黄色、蓝色,使用的是MaterialPropertyBlock这个方式。为啥要使用MaterialPropertyBlock呢?假如我们改为:

Instancing and Material Property Blocks | Ronja's tutorials (ronja-tutorials.com)

using UnityEngine;public class NewBehaviourScript : MonoBehaviour
{public GameObject m_cube1;public Color m_color;private Material m_material1;private MaterialPropertyBlock propertyBlock;void Start(){if (propertyBlock == null)propertyBlock = new MaterialPropertyBlock();propertyBlock.SetColor("_BaseColor", m_color);MeshRenderer meshRenderer = m_cube1.GetComponent<MeshRenderer>();//meshRenderer.SetPropertyBlock(propertyBlock);meshRenderer.material.SetColor("_BaseColor", m_color);}
}

则会看到Cube1和Cube1_1的这两个材质球是新创建的两个材质球,但是有个优点是四个cube都能srp batch了。

同一个材质球+不同属性+shader书写要求+开启gpu instance=》才能instance。

instance的功能不受srp batch开关的影响。

Unity三种合批方式和GPU Instance - 知乎 (zhihu.com)

Unity URP中的Static Batching、GPU Instancing、SRPBatcher简单介绍_gpu instancing 和 srp batcher区别-CSDN博客

gpu instancing开启的条件:

1、首先shader必须符合gpu instancing的书写规则,如上面的例子。

2、材质需要勾选enable gpu intancing。

3、srp batcher的优先级高于gpu instaning,对于game objects,如果srp batcher能被使用(shader兼容srp batcher,节点本身也兼容),则就会使用srp batcher,即便材质开启了enable gpu instancing也没用。

4、如果srp batcher的条件被破坏,例如使用了MaterialPropertyBlock,且开启了Enable GPU Instancing,则GPU Instancing则会启用。

4)srp batch

你太逗了吧

srp batch条件:材质球不同(shader须相同)+ mesh可以不同

条件:

shader要满足srp batch的条件,将属性包在常量buffer里面。

如下图:

cube1和capusle是同材质球;cube3和cube1是不同的材质球,但是shader相同。但他们都被srp batch了。

Shader "Unlit/xxxx"
{Properties{//_MainTex ("Texture", 2D) = "white" {}_BaseColor("Color", Color) = (1,1,1,1)}SubShader{Tags { "RenderType"="Opaque" }LOD 100Pass{CGPROGRAM#pragma enable_d3d11_debug_symbols#pragma vertex vert#pragma fragment frag// make fog work#pragma multi_compile_fog#include "UnityCG.cginc"//float4 _BaseColor; //_BaseColor作为单独变量声明,没有放置cb中CBUFFER_START(UnityPerMaterial)float4 _BaseColor;CBUFFER_ENDstruct appdata{float4 vertex : POSITION;float2 uv : TEXCOORD0;};struct v2f{UNITY_FOG_COORDS(1)float4 vertex : SV_POSITION;};sampler2D _MainTex;float4 _MainTex_ST;v2f vert (appdata v){v2f o;o.vertex = UnityObjectToClipPos(v.vertex);//o.uv = TRANSFORM_TEX(v.uv, _MainTex);UNITY_TRANSFER_FOG(o,o.vertex);return o;}float4 frag (v2f i) : SV_Target{// sample the texture//fixed4 col = tex2D(_MainTex, i.uv);// apply fogUNITY_APPLY_FOG(i.fogCoord, col);return _BaseColor;}ENDCG}}
}

1)srp batch原理

参考网址:

https://zhuanlan.zhihu.com/p/353687806

https://zhuanlan.zhihu.com/p/433222943

srp batcher使材质数据保留在gpu内存中。如果材质内容不变,srp batcher不需要设置缓冲区并将缓冲区上传到gpu。

2)兼容性

不是所有平台都支持常量缓冲区,所以unity用宏来定义区分什么时候使用。CBUFFER_START宏用来替代开始,CBUFFER_END 用来替代cbuffer的结束。

3)cbuffer

比如:unity_ObjectToWorld或者unity_SHAr。必须在一个名为UnityPerMaterial的cbuffer中声明所有材质属性。只要有一个不走常量buffer中,则合批失败。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com