#if defined(UNITY_SUPPORT_INSTANCING) && defined(INSTANCING_ON) #define UNITY_INSTANCING_ENABLED #endif #if defined(UNITY_SUPPORT_INSTANCING) && defined(PROCEDURAL_INSTANCING_ON) #define UNITY_PROCEDURAL_INSTANCING_ENABLED #endif #if defined(UNITY_SUPPORT_INSTANCING) && defined(DOTS_INSTANCING_ON) #define UNITY_DOTS_INSTANCING_ENABLED #endif #if defined(UNITY_SUPPORT_STEREO_INSTANCING) && defined(STEREO_INSTANCING_ON) #define UNITY_STEREO_INSTANCING_ENABLED #endif #if defined(UNITY_INSTANCING_ENABLED) || defined(UNITY_PROCEDURAL_INSTANCING_ENABLED) || defined(UNITY_DOTS_INSTANCING_ENABLED) || defined(UNITY_STEREO_INSTANCING_ENABLED) #define UNITY_ANY_INSTANCING_ENABLED 1 #else #define UNITY_ANY_INSTANCING_ENABLED 0 #endif
#if UNITY_ANY_INSTANCING_ENABLED // A global instance ID variable that functions can directly access. static uint unity_InstanceID; // Don't make UnityDrawCallInfo an actual CB on GL #if !defined(SHADER_API_GLES3) && !defined(SHADER_API_GLCORE) UNITY_INSTANCING_CBUFFER_SCOPE_BEGIN(UnityDrawCallInfo) #endif int unity_BaseInstanceID; int unity_InstanceCount; #if !defined(SHADER_API_GLES3) && !defined(SHADER_API_GLCORE) UNITY_INSTANCING_CBUFFER_SCOPE_END #endif #ifdef SHADER_API_PSSL #define DEFAULT_UNITY_VERTEX_INPUT_INSTANCE_ID uint instanceID; #define UNITY_GET_INSTANCE_ID(input) _GETINSTANCEID(input) #else #define DEFAULT_UNITY_VERTEX_INPUT_INSTANCE_ID uint instanceID : SV_InstanceID; #define UNITY_GET_INSTANCE_ID(input) input.instanceID #endif #else #define DEFAULT_UNITY_VERTEX_INPUT_INSTANCE_ID #endif // UNITY_INSTANCING_ENABLED || UNITY_PROCEDURAL_INSTANCING_ENABLED || UNITY_STEREO_INSTANCING_ENABLED #if !defined(UNITY_VERTEX_INPUT_INSTANCE_0ID) # define UNITY_VERTEX_INPUT_INSTANCE_ID DEFAULT_UNITY_VERTEX_INPUT_INSTANCE_ID #endif
static uint unity_InstanceID;
Don't make UnityDrawCallInfo an actual CB on GL
DEFAULT_UNITY_VERTEX_INPUT_INSTANCE_ID 对没有定义UNITY_ANY_INSTANCING_ENABLED的情况置空
//////////////////////////////////////////////////////// // - UNITY_SETUP_INSTANCE_ID Should be used at the very beginning of the vertex shader / fragment shader, // so that succeeding code can have access to the global unity_InstanceID. // Also procedural function is called to setup instance data. // - UNITY_TRANSFER_INSTANCE_ID Copy instance ID from input struct to output struct. Used in vertex shader.
#if UNITY_ANY_INSTANCING_ENABLED void UnitySetupInstanceID(uint inputInstanceID) { #ifdef UNITY_STEREO_INSTANCING_ENABLED #if !defined(SHADEROPTIONS_XR_MAX_VIEWS) || SHADEROPTIONS_XR_MAX_VIEWS <= 2 #if defined(SHADER_API_GLES3) // We must calculate the stereo eye index differently for GLES3 // because otherwise, the unity shader compiler will emit a bitfieldInsert function. // bitfieldInsert requires support for glsl version 400 or later. Therefore the // generated glsl code will fail to compile on lower end devices. By changing the // way we calculate the stereo eye index, we can help the shader compiler to avoid // emitting the bitfieldInsert function and thereby increase the number of devices we // can run stereo instancing on. unity_StereoEyeIndex = round(fmod(inputInstanceID, 2.0)); unity_InstanceID = unity_BaseInstanceID + (inputInstanceID >> 1); #else // stereo eye index is automatically figured out from the instance ID unity_StereoEyeIndex = inputInstanceID & 0x01; unity_InstanceID = unity_BaseInstanceID + (inputInstanceID >> 1); #endif #else unity_StereoEyeIndex = inputInstanceID % _XRViewCount; unity_InstanceID = unity_BaseInstanceID + (inputInstanceID / _XRViewCount); #endif #else unity_InstanceID = inputInstanceID + unity_BaseInstanceID; #endif }
#ifdef UNITY_PROCEDURAL_INSTANCING_ENABLED #ifndef UNITY_INSTANCING_PROCEDURAL_FUNC #error "UNITY_INSTANCING_PROCEDURAL_FUNC must be defined." #else void UNITY_INSTANCING_PROCEDURAL_FUNC(); // forward declaration of the procedural function #define DEFAULT_UNITY_SETUP_INSTANCE_ID(input) { UnitySetupInstanceID(UNITY_GET_INSTANCE_ID(input)); UNITY_INSTANCING_PROCEDURAL_FUNC();} #endif #else #define DEFAULT_UNITY_SETUP_INSTANCE_ID(input) { UnitySetupInstanceID(UNITY_GET_INSTANCE_ID(input));} #endif
#define UNITY_TRANSFER_INSTANCE_ID(input, output) output.instanceID = UNITY_GET_INSTANCE_ID(input)
#else #define DEFAULT_UNITY_SETUP_INSTANCE_ID(input) #define UNITY_TRANSFER_INSTANCE_ID(input, output) #endif
#if !defined(UNITY_SETUP_INSTANCE_ID) #define UNITY_SETUP_INSTANCE_ID(input) DEFAULT_UNITY_SETUP_INSTANCE_ID(input) #endif
//////////////////////////////////////////////////////// // instanced property arrays #if defined(UNITY_INSTANCING_ENABLED) || defined(UNITY_DOTS_INSTANCING_ENABLED) #ifdef UNITY_FORCE_MAX_INSTANCE_COUNT #define UNITY_INSTANCED_ARRAY_SIZE UNITY_FORCE_MAX_INSTANCE_COUNT #elif defined(UNITY_INSTANCING_SUPPORT_FLEXIBLE_ARRAY_SIZE) #define UNITY_INSTANCED_ARRAY_SIZE 2 // minimum array size that ensures dynamic indexing #elif defined(UNITY_MAX_INSTANCE_COUNT) #define UNITY_INSTANCED_ARRAY_SIZE UNITY_MAX_INSTANCE_COUNT #else #if (defined(SHADER_API_VULKAN) && defined(SHADER_API_MOBILE)) || defined(SHADER_API_SWITCH) #define UNITY_INSTANCED_ARRAY_SIZE 250 #else #define UNITY_INSTANCED_ARRAY_SIZE 500 #endif #endif
#if defined(UNITY_DOTS_INSTANCING_ENABLED) #define UNITY_INSTANCING_BUFFER_START(buf) UNITY_INSTANCING_CBUFFER_SCOPE_BEGIN(UnityInstancing_##buf) #define UNITY_INSTANCING_BUFFER_END(arr) UNITY_INSTANCING_CBUFFER_SCOPE_END #define UNITY_DEFINE_INSTANCED_PROP(type, var) type var; #define UNITY_ACCESS_INSTANCED_PROP(arr, var) var #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/UnityDOTSInstancing.hlsl" #else #define UNITY_INSTANCING_BUFFER_START(buf) UNITY_INSTANCING_CBUFFER_SCOPE_BEGIN(UnityInstancing_##buf) struct{ #define UNITY_INSTANCING_BUFFER_END(arr) } arr##Array[UNITY_INSTANCED_ARRAY_SIZE]; UNITY_INSTANCING_CBUFFER_SCOPE_END #define UNITY_DEFINE_INSTANCED_PROP(type, var) type var; #define UNITY_ACCESS_INSTANCED_PROP(arr, var) arr##Array[unity_InstanceID].var #define UNITY_DOTS_INSTANCING_START(name) #define UNITY_DOTS_INSTANCING_END(name) #define UNITY_DOTS_INSTANCED_PROP(type, name) #define UNITY_ACCESS_DOTS_INSTANCED_PROP(type, var) var #define UNITY_ACCESS_DOTS_INSTANCED_PROP_FROM_MACRO(type, metadata_underscore_var) This_macro_cannot_be_called_without_UNITY_DOTS_INSTANCING_ENABLED #define UNITY_ACCESS_DOTS_AND_TRADITIONAL_INSTANCED_PROP(type, arr, var) UNITY_ACCESS_INSTANCED_PROP(arr, var) #endif
// Put worldToObject array to a separate CB if UNITY_ASSUME_UNIFORM_SCALING is defined. Most of the time it will not be used. #ifdef UNITY_ASSUME_UNIFORM_SCALING #define UNITY_WORLDTOOBJECTARRAY_CB 1 #else #define UNITY_WORLDTOOBJECTARRAY_CB 0 #endif #if defined(UNITY_INSTANCED_LOD_FADE) && (defined(LOD_FADE_PERCENTAGE) || defined(LOD_FADE_CROSSFADE)) #define UNITY_USE_LODFADE_ARRAY #endif #if defined(UNITY_INSTANCED_RENDERING_LAYER) #define UNITY_USE_RENDERINGLAYER_ARRAY #endif #ifdef UNITY_INSTANCED_LIGHTMAPSTS #ifdef LIGHTMAP_ON #define UNITY_USE_LIGHTMAPST_ARRAY #endif #ifdef DYNAMICLIGHTMAP_ON #define UNITY_USE_DYNAMICLIGHTMAPST_ARRAY #endif #endif #if defined(UNITY_INSTANCED_SH) && !defined(LIGHTMAP_ON) #if !defined(DYNAMICLIGHTMAP_ON) #define UNITY_USE_SHCOEFFS_ARRAYS #endif #if defined(SHADOWS_SHADOWMASK) #define UNITY_USE_PROBESOCCLUSION_ARRAY #endif #endif
#if !defined(UNITY_DOTS_INSTANCING_ENABLED) UNITY_INSTANCING_BUFFER_START(PerDraw0) #ifndef UNITY_DONT_INSTANCE_OBJECT_MATRICES UNITY_DEFINE_INSTANCED_PROP(float4x4, unity_ObjectToWorldArray) #if UNITY_WORLDTOOBJECTARRAY_CB == 0 UNITY_DEFINE_INSTANCED_PROP(float4x4, unity_WorldToObjectArray) #endif #endif #if defined(UNITY_USE_LODFADE_ARRAY) && defined(UNITY_INSTANCING_SUPPORT_FLEXIBLE_ARRAY_SIZE) UNITY_DEFINE_INSTANCED_PROP(float2, unity_LODFadeArray) #define unity_LODFade UNITY_ACCESS_INSTANCED_PROP(unity_Builtins0, unity_LODFadeArray).xyxx #endif #if defined(UNITY_USE_RENDERINGLAYER_ARRAY) && defined(UNITY_INSTANCING_SUPPORT_FLEXIBLE_ARRAY_SIZE) UNITY_DEFINE_INSTANCED_PROP(float, unity_RenderingLayerArray) #define unity_RenderingLayer UNITY_ACCESS_INSTANCED_PROP(unity_Builtins0, unity_RenderingLayerArray).xxxx #endif // TODO: Hybrid V1 compatibility, remove once Hybrid V1 is removed #if defined(UNITY_HYBRID_V1_INSTANCING_ENABLED) && defined(HYBRID_V1_CUSTOM_ADDITIONAL_MATERIAL_VARS) HYBRID_V1_CUSTOM_ADDITIONAL_MATERIAL_VARS #endif UNITY_INSTANCING_BUFFER_END(unity_Builtins0)
UNITY_INSTANCING_BUFFER_START(PerDraw1) #if !defined(UNITY_DONT_INSTANCE_OBJECT_MATRICES) && UNITY_WORLDTOOBJECTARRAY_CB == 1 UNITY_DEFINE_INSTANCED_PROP(float4x4, unity_WorldToObjectArray) #endif #if defined(UNITY_USE_LODFADE_ARRAY) && !defined(UNITY_INSTANCING_SUPPORT_FLEXIBLE_ARRAY_SIZE) UNITY_DEFINE_INSTANCED_PROP(float2, unity_LODFadeArray) #define unity_LODFade UNITY_ACCESS_INSTANCED_PROP(unity_Builtins1, unity_LODFadeArray).xyxx #endif #if defined(UNITY_USE_RENDERINGLAYER_ARRAY) && !defined(UNITY_INSTANCING_SUPPORT_FLEXIBLE_ARRAY_SIZE) UNITY_DEFINE_INSTANCED_PROP(float, unity_RenderingLayerArray) #define unity_RenderingLayer UNITY_ACCESS_INSTANCED_PROP(unity_Builtins1, unity_RenderingLayerArray).xxxx #endif UNITY_INSTANCING_BUFFER_END(unity_Builtins1)
UNITY_INSTANCING_BUFFER_START(PerDraw2) #ifdef UNITY_USE_LIGHTMAPST_ARRAY UNITY_DEFINE_INSTANCED_PROP(float4, unity_LightmapSTArray) UNITY_DEFINE_INSTANCED_PROP(float4, unity_LightmapIndexArray) #define unity_LightmapST UNITY_ACCESS_INSTANCED_PROP(unity_Builtins2, unity_LightmapSTArray) #endif #ifdef UNITY_USE_DYNAMICLIGHTMAPST_ARRAY UNITY_DEFINE_INSTANCED_PROP(float4, unity_DynamicLightmapSTArray) #define unity_DynamicLightmapST UNITY_ACCESS_INSTANCED_PROP(unity_Builtins2, unity_DynamicLightmapSTArray) #endif #ifdef UNITY_USE_SHCOEFFS_ARRAYS UNITY_DEFINE_INSTANCED_PROP(half4, unity_SHArArray) UNITY_DEFINE_INSTANCED_PROP(half4, unity_SHAgArray) UNITY_DEFINE_INSTANCED_PROP(half4, unity_SHAbArray) UNITY_DEFINE_INSTANCED_PROP(half4, unity_SHBrArray) UNITY_DEFINE_INSTANCED_PROP(half4, unity_SHBgArray) UNITY_DEFINE_INSTANCED_PROP(half4, unity_SHBbArray) UNITY_DEFINE_INSTANCED_PROP(half4, unity_SHCArray) #define unity_SHAr UNITY_ACCESS_INSTANCED_PROP(unity_Builtins2, unity_SHArArray) #define unity_SHAg UNITY_ACCESS_INSTANCED_PROP(unity_Builtins2, unity_SHAgArray) #define unity_SHAb UNITY_ACCESS_INSTANCED_PROP(unity_Builtins2, unity_SHAbArray) #define unity_SHBr UNITY_ACCESS_INSTANCED_PROP(unity_Builtins2, unity_SHBrArray) #define unity_SHBg UNITY_ACCESS_INSTANCED_PROP(unity_Builtins2, unity_SHBgArray) #define unity_SHBb UNITY_ACCESS_INSTANCED_PROP(unity_Builtins2, unity_SHBbArray) #define unity_SHC UNITY_ACCESS_INSTANCED_PROP(unity_Builtins2, unity_SHCArray) #endif #ifdef UNITY_USE_PROBESOCCLUSION_ARRAY UNITY_DEFINE_INSTANCED_PROP(half4, unity_ProbesOcclusionArray) #define unity_ProbesOcclusion UNITY_ACCESS_INSTANCED_PROP(unity_Builtins2, unity_ProbesOcclusionArray) #endif UNITY_INSTANCING_BUFFER_END(unity_Builtins2) #endif
#if defined(UNITY_DOTS_INSTANCING_ENABLED) #undef UNITY_MATRIX_M #undef UNITY_MATRIX_I_M #ifdef MODIFY_MATRIX_FOR_CAMERA_RELATIVE_RENDERING #define UNITY_MATRIX_M ApplyCameraTranslationToMatrix(LoadDOTSInstancedData_float4x4_from_float3x4(UNITY_DOTS_INSTANCED_METADATA_NAME_FROM_MACRO(float3x4, Metadata_unity_ObjectToWorld))) #define UNITY_MATRIX_I_M ApplyCameraTranslationToInverseMatrix(LoadDOTSInstancedData_float4x4_from_float3x4(UNITY_DOTS_INSTANCED_METADATA_NAME_FROM_MACRO(float3x4, Metadata_unity_WorldToObject))) #else #define UNITY_MATRIX_M LoadDOTSInstancedData_float4x4_from_float3x4(UNITY_DOTS_INSTANCED_METADATA_NAME_FROM_MACRO(float3x4, Metadata_unity_ObjectToWorld)) #define UNITY_MATRIX_I_M LoadDOTSInstancedData_float4x4_from_float3x4(UNITY_DOTS_INSTANCED_METADATA_NAME_FROM_MACRO(float3x4, Metadata_unity_WorldToObject)) #endif #else #ifndef UNITY_DONT_INSTANCE_OBJECT_MATRICES #undef UNITY_MATRIX_M #undef UNITY_MATRIX_I_M // Use #if instead of preprocessor concatenation to avoid really hard to debug // preprocessing issues in some cases. #if UNITY_WORLDTOOBJECTARRAY_CB == 0 #define UNITY_BUILTINS_WITH_WORLDTOOBJECTARRAY unity_Builtins0 #else #define UNITY_BUILTINS_WITH_WORLDTOOBJECTARRAY unity_Builtins1 #endif #ifdef MODIFY_MATRIX_FOR_CAMERA_RELATIVE_RENDERING #define UNITY_MATRIX_M ApplyCameraTranslationToMatrix(UNITY_ACCESS_INSTANCED_PROP(unity_Builtins0, unity_ObjectToWorldArray)) #define UNITY_MATRIX_I_M ApplyCameraTranslationToInverseMatrix(UNITY_ACCESS_INSTANCED_PROP(UNITY_BUILTINS_WITH_WORLDTOOBJECTARRAY, unity_WorldToObjectArray)) #else #define UNITY_MATRIX_M UNITY_ACCESS_INSTANCED_PROP(unity_Builtins0, unity_ObjectToWorldArray) #define UNITY_MATRIX_I_M UNITY_ACCESS_INSTANCED_PROP(UNITY_BUILTINS_WITH_WORLDTOOBJECTARRAY, unity_WorldToObjectArray) #endif #endif #endif
// in procedural mode we don't need cbuffer, and properties are not uniforms #ifdef UNITY_PROCEDURAL_INSTANCING_ENABLED #define UNITY_INSTANCING_BUFFER_START(buf) #define UNITY_INSTANCING_BUFFER_END(arr) #define UNITY_DEFINE_INSTANCED_PROP(type, var) static type var; #else #define UNITY_INSTANCING_BUFFER_START(buf) CBUFFER_START(buf) #define UNITY_INSTANCING_BUFFER_END(arr) CBUFFER_END #define UNITY_DEFINE_INSTANCED_PROP(type, var) type var; #endif #define UNITY_ACCESS_INSTANCED_PROP(arr, var) var
UNITY_INSTANCING_BUFFER_START(buf) UNITY_DEFINE_INSTANCED_PROP(type, var) UNITY_DEFINE_INSTANCED_PROP(type, var) UNITY_INSTANCING_BUFFER_END(arr) UNITY_INSTANCING_CBUFFER_SCOPE_BEGIN(UnityInstancing_##buf) struct{ type var; type var; } arr##Array[UNITY_INSTANCED_ARRAY_SIZE]; UNITY_INSTANCING_CBUFFER_SCOPE_END [非GL平台] CBUFFER_START(UnityInstancing_##buf) struct{ type var; type var; } arr##Array[UNITY_INSTANCED_ARRAY_SIZE]; CBUFFER_END 例子: UNITY_INSTANCING_BUFFER_START(Props) UNITY_DEFINE_INSTANCED_PROP(float4, _TestColor) UNITY_INSTANCING_BUFFER_END(Props) name of arr=buf=Props [非GL平台] CBUFFER_START(UnityInstancing_Props) struct{ float4 _TestColor; } PropsArray[UNITY_INSTANCED_ARRAY_SIZE]; CBUFFER_END
UNITY_ACCESS_INSTANCED_PROP(arr, var) =>arrArray[unity_InstanceID].var 例子: UNITY_ACCESS_INSTANCED_PROP(Props, _TestColor) =>PropsArray[unity_InstanceID]._TestColor
- UNITY_SETUP_INSTANCE_ID(input) => DEFAULT_UNITY_SETUP_INSTANCE_ID =>1.Procedural UnitySetupInstanceID(UNITY_GET_INSTANCE_ID(input)); UNITY_INSTANCING_PROCEDURAL_FUNC(); =>2.非Procedural UnitySetupInstanceID(UNITY_GET_INSTANCE_ID(input)); [非PS平台] UnitySetupInstanceID(input.instanceID); unity_InstanceID = input.instanceID + unity_BaseInstanceID; - UNITY_TRANSFER_INSTANCE_ID(input, output) =>output.instanceID = UNITY_GET_INSTANCE_ID(input) =>output.instanceID = input.instanceID