#ifndef GPU_INSTANCER_INCLUDED #define GPU_INSTANCER_INCLUDED #ifdef UNITY_PROCEDURAL_INSTANCING_ENABLED uniform uint gpui_InstanceID; uniform float4x4 gpuiTransformOffset; uniform float LODLevel; // -1 if crossFade disabled, 0-7 if cross fade enabled uniform float fadeLevelMultiplier; // 1 no animation #if GPUI_MHT_COPY_TEXTURE uniform sampler2D gpuiTransformationMatrixTexture; uniform sampler2D gpuiInstanceLODDataTexture; uniform float bufferSize; uniform float maxTextureSize; #elif GPUI_MHT_MATRIX_APPEND uniform StructuredBuffer gpuiTransformationMatrix; #else uniform StructuredBuffer gpuiTransformationMatrix; uniform StructuredBuffer gpuiInstanceData; uniform StructuredBuffer gpuiInstanceLODData; #endif #ifdef unity_ObjectToWorld #undef unity_ObjectToWorld #endif #ifdef unity_WorldToObject #undef unity_WorldToObject #endif #endif // UNITY_PROCEDURAL_INSTANCING_ENABLED void setupGPUI() { #ifdef UNITY_PROCEDURAL_INSTANCING_ENABLED #if GPUI_MHT_COPY_TEXTURE uint textureWidth = min(bufferSize, maxTextureSize); float indexX = ((unity_InstanceID % maxTextureSize) + 0.5f) / textureWidth; float rowCount = ceil(bufferSize / maxTextureSize) * 4.0f; float rowIndex = floor(unity_InstanceID / maxTextureSize) * 4.0f + 0.5f; float4x4 transformData = float4x4( tex2Dlod(gpuiTransformationMatrixTexture, float4(indexX, (0.0f + rowIndex) / rowCount, 0.0f, 0.0f)), // row0 tex2Dlod(gpuiTransformationMatrixTexture, float4(indexX, (1.0f + rowIndex) / rowCount, 0.0f, 0.0f)), // row1 tex2Dlod(gpuiTransformationMatrixTexture, float4(indexX, (2.0f + rowIndex) / rowCount, 0.0f, 0.0f)), // row2 tex2Dlod(gpuiTransformationMatrixTexture, float4(indexX, (3.0f + rowIndex) / rowCount, 0.0f, 0.0f)) // row3 ); gpui_InstanceID = uint(transformData._44); transformData._44 = 1.0f; unity_ObjectToWorld = mul(transformData, gpuiTransformOffset); #elif GPUI_MHT_MATRIX_APPEND unity_ObjectToWorld = mul(gpuiTransformationMatrix[unity_InstanceID], gpuiTransformOffset); #else gpui_InstanceID = gpuiTransformationMatrix[unity_InstanceID]; unity_ObjectToWorld = mul(gpuiInstanceData[gpui_InstanceID], gpuiTransformOffset); #endif // SHADER_API // inverse transform matrix // taken from richardkettlewell's post on // https://forum.unity3d.com/threads/drawmeshinstancedindirect-example-comments-and-questions.446080/ float3x3 w2oRotation; w2oRotation[0] = unity_ObjectToWorld[1].yzx * unity_ObjectToWorld[2].zxy - unity_ObjectToWorld[1].zxy * unity_ObjectToWorld[2].yzx; w2oRotation[1] = unity_ObjectToWorld[0].zxy * unity_ObjectToWorld[2].yzx - unity_ObjectToWorld[0].yzx * unity_ObjectToWorld[2].zxy; w2oRotation[2] = unity_ObjectToWorld[0].yzx * unity_ObjectToWorld[1].zxy - unity_ObjectToWorld[0].zxy * unity_ObjectToWorld[1].yzx; float det = dot(unity_ObjectToWorld[0].xyz, w2oRotation[0]); w2oRotation = transpose(w2oRotation); w2oRotation *= rcp(det); float3 w2oPosition = mul(w2oRotation, -unity_ObjectToWorld._14_24_34); unity_WorldToObject._11_21_31_41 = float4(w2oRotation._11_21_31, 0.0f); unity_WorldToObject._12_22_32_42 = float4(w2oRotation._12_22_32, 0.0f); unity_WorldToObject._13_23_33_43 = float4(w2oRotation._13_23_33, 0.0f); unity_WorldToObject._14_24_34_44 = float4(w2oPosition, 1.0f); #ifdef UNITY_PREV_MATRIX_M unity_MatrixPreviousM = unity_ObjectToWorld; #endif #endif // UNITY_PROCEDURAL_INSTANCING_ENABLED } #endif // GPU_INSTANCER_INCLUDED // GPUInstancerInclude.cginc [do not delete needed for IsShaderInstanced check]