要令一个GameObject与GPU Resident Drawer兼容,请检查以下条件:
MaterialPropertyBlock API。OnRenderObject
默认情况下,GPU Resident Drawer会收集场景中所有带有Mesh Renderer组件的物体,且仅在这些物体的数量发生变动或物体的属性发生改变时才会触发从CPU端上传数据到GPU端的操作。
要从 GPU GPU Resident Drawer中排除GameObject,请按一下步骤操作:
添加 Instancing 宏定义
在 Shader 代码中添加 #pragma multi_compile_instancing,以启用 Instancing 变体支持。
包含 DOTS 相关头文件
添加以下代码以引入 Unity 的 DOTS Instancing 支持:
#include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DOTS.hlsl"
使用 Instancing 宏
在 Shader 中添加以下 Instancing 相关宏,确保正确处理实例化数据:
UNITY_VERTEX_INPUT_INSTANCE_ID:在顶点输入结构体中声明实例 ID。
UNITY_SETUP_INSTANCE_ID(v):在顶点着色器中设置实例 ID。
其他相关宏(如 UNITY_TRANSFER_INSTANCE_ID 等)根据需要使用。
引擎自动处理 DOTS Instancing
当 Shader 变体启用了 DOTS_INSTANCING 宏时,引擎会自动将实例化逻辑替换为支持 DOTS Instancing 的实现,从而无缝支持 GPU Resident Drawer 功能。
通过以上步骤,自定义 Shader 可快速适配 GPU Resident Drawer。若需更精细的控制和优化,开发者可自行实现 DOTS Instancing 的相关逻辑。
以下是一个简单的URP Shader示例,包含注释部分,展示了如何添加对GPU Resident Drawer的支持。其实现方式与支持Instance的修改方法基本一致。
Shader "Custom/example"
{
Properties
{
_BaseColor("Color", Color) = (1.0, 1.0, 1.0, 1.0)
}
SubShader
{
Pass
{
HLSLPROGRAM
#pragma vertex vert
#pragma fragment frag
// 这里添加instancing和DOTS的引用
#pragma multi_compile_instancing
#include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DOTS.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
UNITY_VERTEX_INPUT_INSTANCE_ID // 添加instance的使用
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
UNITY_VERTEX_INPUT_INSTANCE_ID // 添加instance的使用
UNITY_VERTEX_OUTPUT_STEREO // 添加instance的使用
};
CBUFFER_START(UnityPerMaterial)
float4 _BaseColor;
CBUFFER_END
v2f vert (appdata v)
{
v2f o;
UNITY_SETUP_INSTANCE_ID(v); // 添加instance的使用
UNITY_TRANSFER_INSTANCE_ID(v, o); // 添加instance的使用
o.vertex = TransformObjectToHClip(v.vertex.xyz);
o.uv = v.uv;
return o;
}
float4 frag (v2f i) : SV_Target
{
UNITY_SETUP_INSTANCE_ID(i); // 添加instance的使用
return _BaseColor;
}
ENDHLSL
}
}
}