Search Unity

[RELEASED] GPU Instancer

Discussion in 'Assets and Asset Store' started by LouskRad, May 3, 2018.

  1. browne11

    browne11

    Joined:
    Apr 30, 2015
    Posts:
    138
    Upgraded from 1.5.4 to 1.72 imported fine, but receiving this error. I've deleted SO and recompiled but the console spews hundreds of these out. Any suggestions?

    For now I just replaced the GPU folder with my old version and it's working fine again. Let me know.
    upload_2022-5-7_19-28-34.png
     
    Last edited: May 8, 2022
  2. Querke

    Querke

    Joined:
    Feb 21, 2013
    Posts:
    54
    Hello! I love your asset!
    But would it be possible to group all terrains into the same gameobject in the detail rendering component? I see that with the tree rendering component, the additional terrains is grouped under the same game object. This makes it much simpler to adjust settings. I got 16 terrain tiles and if I want to change a setting for my details, I have to do that change 16 times.
    Anyway, keep up the great work.
     
    marcell123455 likes this.
  3. Claytonious

    Claytonious

    Joined:
    Feb 16, 2009
    Posts:
    904
    Is there any way to use trees as Addressables with the GPUITreeManager? This would require somehow loading the tree prefabs as Addressable assets and then "setting" them on the tree manager.
     
  4. MonkeyPuzzle

    MonkeyPuzzle

    Joined:
    Jan 17, 2016
    Posts:
    119
    Trying to figure out GPU Instancer and Vegetation Engine. My scene has about 5 plant prefabs, which I have gotten set up in Vegetation Engine with the materials and animation that I want.

    I added the GPUI, prefab manager and added my prefabs. Most are in the 5000-10000 range, one in the 20+k.

    I have 9 standard Unity terrains, each with one type of non-billboard grass. I also added the detail manager. I was asked to "generate" prototypes.

    I have one camera "Main Camera" and camera auto detect on, which I have confirmed at runtime.

    It seems like everything is working in that it doesn't throw any errors, frustrum culling is working, but I don't see any performance increase. I have tried on my PC with a RTX 3050 TI and a 2020 Macbook Pro.

    Any thoughts on how I can best integrate GPUI is appreciated!
     
  5. GurhanH

    GurhanH

    Joined:
    Apr 24, 2017
    Posts:
    539
    Hi there,
    I am not sure what is causing this issue. We will need to debug to find out. If you can email us a sample project, we can investigate.

    Hi there,
    and thanks for your kind words.
    We are looking into improving the Detail Manager. I shared a simple script in this post which can help as a temporary solution to this problem.

    It should be possible, as long as you load the prefabs before the manager. But we do not currently have demos or documentations specific to Addressables.

    Hi there,
    Since you have high instance counts, there should be some benefit. However there are cases where the application is bound by another process or setting. Some examples:
    - Frame rate capped to monitor's refresh rate or limited max FPS
    - Very high vertex counts causing the application to be GPU bound by vertex processing
    - Some unoptimized visual effects multiplying the draw calls

    As for the Detail Manager, I recommend reading the Best Practices documentation, since it has features (such as shadows, cross-quads) that adversely affect performance.

    If these does not help, you can email us detailed information (including frame rate comparison, profiler data), we can investigate it.
     
  6. MonkeyPuzzle

    MonkeyPuzzle

    Joined:
    Jan 17, 2016
    Posts:
    119
    Thanks for the prompt reply. I will set up some simple tests with just my main character, a terrain and one prototype instanced multiple times and see if that helps. As far as the Vegetation Engine and the custom shaders that they create, is there a way to check that GPUI shaders are being added properly?
     
  7. browne11

    browne11

    Joined:
    Apr 30, 2015
    Posts:
    138
    That will take a long time to prepare. I've googled the issue and see others with the same error message. Can you at least offer a few suggestions before I spent an entire day compiling a mini project? I've reverted back to your older version and it's working fine again. Here is the same error as mine asked before. Perhaps they sent in the sample project as you asked them as well.
    upload_2022-5-10_9-35-55.png
     
  8. GurhanH

    GurhanH

    Joined:
    Apr 24, 2017
    Posts:
    539
    When there is an error on the shader usually the instances would not render correctly, so it would be obvious. But to make sure that they are rendered with GPUI, you can check the Registered Instances section of the manager at runtime, and see if you see the number of instances there.

    These are two completely different errors (one is IndexOutOfRangeException, other one is NullReferenceException). Also UpdateGPUBuffer is the main method which makes all the Compute Shader and Draw Call operations. So it does not give much information about what might be the problem. If you can not create a sample project, email us the full error log with the other information requested here and we will try to help.
     
  9. TanselAltinel

    TanselAltinel

    Joined:
    Jan 7, 2015
    Posts:
    190
    Hi,

    This is a little bit of an edge case but I was wondering if it's already supported with GPUI.

    There is Material Property Override component from Unity: https://github.com/Unity-Technologies/FPSSample/tree/master/Assets/Tools/MaterialPropertyOverride

    It basically creates a variant of the base shader with one or two difference.

    Is GPUI capable of getting prefab variants with this component into a single call?

    My use case would be like this:
    I have one mesh and 6 different base textures. I have one prefab and 5 prefab variants, each of them using a different material due to having different base texture (rest of the properties of this material is the same). If I am to use material variant, I can gather all 6 different object (same mesh, one base material, 5 material variants) into same GPU Instancing through material Enable Instancing checkbox.

    Color variant demo is not usable for me as all of my objects are manually placed in the scene, so I was wondering if a workflow like this would be better.
     
  10. Bakedman

    Bakedman

    Joined:
    Aug 7, 2015
    Posts:
    5
    Does this work with WebGL?
     
  11. GurhanH

    GurhanH

    Joined:
    Apr 24, 2017
    Posts:
    539
    Hi there,

    As described in Unity's documentation Material Variants can not be used for optimization. So the draw calls for material variants are not batched.
    You can however use GPUI's Material Variations in combination with Unity's Material Property Blocks to see them with their variant properties in edit mode. We will look into providing a demo with some helper scripts to make it easier to understand.

    For now you can check this partial code to get an idea:
    C# part which should run in a script with ExecuteInEditMode attribute:
    Code (CSharp):
    1. GPUInstancerPrefab gpuInstancerPrefab = GetComponent<GPUInstancerPrefab>();
    2. if (gpuInstancerPrefab.state == PrefabInstancingState.Instanced)
    3. {
    4.     GPUInstancerAPI.UpdateVariation(prefabManager, gpuInstancerPrefab, "textureUVBuffer", instanceUV);
    5. }
    6. else
    7. {
    8.     MeshRenderer[] meshRenderers = GetComponentsInChildren<MeshRenderer>();
    9.     foreach (MeshRenderer mr in meshRenderers)
    10.     {
    11.         MaterialPropertyBlock mpb = new MaterialPropertyBlock();
    12.         mpb.SetVector("textureUV", instanceUV);
    13.         mr.SetPropertyBlock(mpb);
    14.     }
    15. }
    Shader property definition:
    Code (CSharp):
    1. #ifdef UNITY_PROCEDURAL_INSTANCING_ENABLED
    2.         StructuredBuffer<float4> textureUVBuffer;
    3. #else
    4.         UNITY_INSTANCING_BUFFER_START(Props)
    5.             UNITY_DEFINE_INSTANCED_PROP(float4, textureUV)
    6.         UNITY_INSTANCING_BUFFER_END(Props)
    7. #endif
    Shader property access:
    Code (CSharp):
    1. #ifdef UNITY_PROCEDURAL_INSTANCING_ENABLED
    2.             float4 texUV = textureUVBuffer[gpui_InstanceID];
    3. #else
    4.             float4 texUV = UNITY_ACCESS_INSTANCED_PROP(Props, textureUV);
    5. #endif
    Hi there,

    Unfortunately GPUI does not support WebGL because of its dependence on Compute Shaders. You can see the list of supported graphics APIs and platforms from the Minimum Requirements.
     
    TanselAltinel likes this.
  12. diccon

    diccon

    Joined:
    Sep 13, 2013
    Posts:
    22
    Hello,
    we are finding that GPUInstancerDetailManager uses an excessive amount of memory as we try to scale our project and I wonder if you have any advice. We are using it to put 4 vegetation prototypes onto a island with Terrain approximately 3000x3000 and our full game has 22 of these, so when we create the world the memory profiler shows an increase of around 1Gb, including 700mb of arrays of ints and floats.
    I have tried a naive approach of disabling the detail manager on each island and turning it on when the player is close enough, this is successful in reducing the memory but causes a frame rate spike when the manager initializes (even with the threaded option).
    I am thinking that the best approach would be a custom solution would be to serialize the instance transforms in the editor and stream them in from an asset at runtime. Since our detail instances are fairly sparse this might only be a few hundred or low thousands. Can you tell me if the API would allow me to do something like this, and maybe point me in the right direction?

    Thanks for your help.
     
  13. madhh

    madhh

    Joined:
    Jan 1, 2014
    Posts:
    2
    Hey guys

    I noticed there are shadows on the GPUI generated billboards. Can someone tell me how they work? No matter what I do, the shadow direction is always wrong. When I move the sun around, the shadows change direction, but their direction is never the one the sun position implies.
     
  14. marcell123455

    marcell123455

    Joined:
    Jun 18, 2014
    Posts:
    275
    Hi,

    I run into a problem with my tree manager. I simply switched from open GL 3.1 to direct x 11 as graphics engine, and the GPU instancer tree manager stopped working. It shows me these errors when pressing play:

    Kernel 'CSInstancedRenderingVisibilityKernelLOD0' not found
    0x00007ff60d5df46c (Unity) StackWalker::GetCurrentCallstack
    0x00007ff60d5e6a69 (Unity) StackWalker::ShowCallstack
    0x00007ff60e378d4c (Unity) GetStacktrace
    0x00007ff60eddb497 (Unity) DebugStringToFile
    0x00007ff60d30b5ce (Unity) ComputeShader::FindKernel
    0x00007ff60d0a506c (Unity) ComputeShaderScripting::FindKernel
    0x00007ff60d615261 (Unity) ComputeShader_CUSTOM_FindKernel
    0x000001ac60f2fac6 (Mono JIT Code) (wrapper managed-to-native) UnityEngine.ComputeShader:FindKernel (UnityEngine.ComputeShader,string)
    0x000001ac60f2ebbb (Mono JIT Code) [GPUInstancerManager.cs:148] GPUInstancer.GPUInstancerManager:Awake ()
    0x000001ac60f2e763 (Mono JIT Code) [GPUInstancerPrefabManager.cs:34] GPUInstancer.GPUInstancerPrefabManager:Awake ()
    0x000001ac60791490 (Mono JIT Code) (wrapper runtime-invoke) object:runtime_invoke_void__this__ (object,intptr,intptr,intptr)
    0x00007ffd5175f1e0 (mono-2.0-bdwgc) [mini-runtime.c:2849] mono_jit_runtime_invoke
    0x00007ffd516e2ac2 (mono-2.0-bdwgc) [object.c:2921] do_runtime_invoke
    0x00007ffd516ebb1f (mono-2.0-bdwgc) [object.c:2968] mono_runtime_invoke
    0x00007ff60d5239c4 (Unity) scripting_method_invoke
    0x00007ff60d51eb81 (Unity) ScriptingInvocation::Invoke
    0x00007ff60d51ecde (Unity) ScriptingInvocation::InvokeChecked
    0x00007ff60d5777d6 (Unity) SerializableManagedRef::CallMethod
    0x00007ff60d4ebfa4 (Unity) MonoBehaviour::CallAwake
    0x00007ff60d4eafb0 (Unity) MonoBehaviour::AwakeFromLoad
    0x00007ff60d5b803f (Unity) AwakeFromLoadQueue::InvokePersistentManagerAwake
    0x00007ff60d5b89d2 (Unity) AwakeFromLoadQueue::persistentManagerAwakeFromLoad
    0x00007ff60d5b8b43 (Unity) AwakeFromLoadQueue::persistentManagerAwakeFromLoad
    0x00007ff60d27b21e (Unity) LoadSceneOperation::CompleteAwakeSequence
    0x00007ff60d27e9ab (Unity) LoadSceneOperation::playerLoadSceneFromThread
    0x00007ff60d27cb03 (Unity) LoadSceneOperation::IntegrateMainThread
    0x00007ff60d280376 (Unity) PreloadManager::UpdatePreloadingSingleStep
    0x00007ff60d27ffbd (Unity) PreloadManager::UpdatePreloading
    0x00007ff60d2563e3 (Unity) `InitPlayerLoopCallbacks'::`2'::EarlyUpdateUpdatePreloadingRegistrator::Forward
    0x00007ff60d23e4ac (Unity) ExecutePlayerLoop
    0x00007ff60d23e583 (Unity) ExecutePlayerLoop
    0x00007ff60d245259 (Unity) PlayerLoop
    0x00007ff60df11e81 (Unity) PlayerLoopController::UpdateScene
    0x00007ff60df100a9 (Unity) Application::TickTimer
    0x00007ff60e37f201 (Unity) MainMessageLoop
    0x00007ff60e3833a1 (Unity) WinMain
    0x00007ff60fa25f3e (Unity) __scrt_common_main_seh
    0x00007ffdb73f54e0 (KERNEL32) BaseThreadInitThunk
    0x00007ffdb76a485b (ntdll) RtlUserThreadStart
    ArgumentException: Kernel 'CSInstancedRenderingVisibilityKernelLOD0' not found.
    GPUInstancer.GPUInstancerManager.Awake () (at Assets/GPUInstancer/Scripts/Core/Contract/GPUInstancerManager.cs:148)
    GPUInstancer.GPUInstancerPrefabManager.Awake () (at Assets/GPUInstancer/Scripts/GPUInstancerPrefabManager.cs:32)

    When I switch back to open GL it works again. Any idea how to fix this or what it could be caused by?

    Thanks ;)
     
  15. marcell123455

    marcell123455

    Joined:
    Jun 18, 2014
    Posts:
    275
    Forget it, fixed it by switching build plattform from android to windows pc.
     
    GurhanH likes this.
  16. GurhanH

    GurhanH

    Joined:
    Apr 24, 2017
    Posts:
    539
    Hi there,
    The memory cost and initial spikes mainly come from the data structure of the detail layers of the Unity Terrain API. It is only provided as a 2D int array.
    There are multiple options you can choose from especially if you have sparse vegetation:
    - Use the Tree Manager instead of Detail Manager. Unlike details, trees are stored in an instance based data structure. So the loaded data size will be equal to the instance count, instead of being based on terrain detail resolution.
    - Use the No-GameObject workflow with Prefab Manager. With this approach you can have full control over when the instances are loaded and how they are stored.

    Hi there,
    Normally billboards do not cast shadows, so I am not sure what happened here. If you can send us a sample project (e.g. a scene with minimum amount of content to show the problem), we can investigate.
     
  17. Marco-Playable

    Marco-Playable

    Joined:
    Nov 12, 2020
    Posts:
    53
    I am trying to write a detail spawner similar to what you have in CSInstancedRenderingGrassInstantiationKernel, but without a terrain - just placing grass instances on a mesh after querying GetTransformDataBuffer(). My code is working , but the performance I am getting is underwhelming.

    To see if I messed anything up I looked at your Boids demo instead. If I crank the spawn count up to 100k, the stats window in Unity tells me that the CPU thread takes 150ms per frame (on an RTX 2060 Super). This is where it gets interesting: when I disable the GPUI Instancer Prefab Manager at runtime- the CPU thread usage goes down to 2ms. Likewise, if I disable the BoidsController at runtime then the CPU thread usage goes down to 3ms.

    So I am guessing the Boids kernel is dispatched and writing to the transformationMatrixVisibilityBuffer. Then it's time for GPUI's Update call and it tries to dispatch a kernel that uses the transformationMatrixVisibilityBuffer so the system becomes blocked until that compute buffer is no longer used by Boids?

    Given the 2ms from spawning and 3ms from culling I was hoping to see a total frame time of around 5ms and instead it's 30 times as much.

    Do you have any recommendations on how to achieve better performance?
     
  18. madhh

    madhh

    Joined:
    Jan 1, 2014
    Posts:
    2
    Hi, sorry, I try to explain it better.
    I did not mean the shadows cast by the billboard, but the shadows on the billboard.
    https://www.dropbox.com/s/7g6d8zh19atybse/tree-billboard-shadow.jpg?dl=0
    On this picture you can see the actual tree models in the foreground, and the generated billboards a bit further away and also in the background. As you can see they both have a lit side, and the other side is in shadow, but they don't match, it looks like it's completly the opposite. I just don't know how to set it up, so the lit sides match up, and i don't find anything about this in the documentation.
    I can see that these shadows get baked into the billboard, because when I'm rotating a tree, the shadow rotates with it. I can actually rotate the trees by hand so the shadows match, I just can't seem to be able to instantiate them that way.
    https://www.dropbox.com/s/b0ydrdtoji7f685/tree-bilboard-shadows-all-over.jpg?dl=0
    On the picture all the trees have the same rotation. If i place the trees with random rotations, the billboard shadows are all over the place, like on this second picture.
    In this scene I'm using the prefab manager. I'm instancing the prefabs in runtime, then registering them with the prefab manager. Is there a way to regenerate the billboards in runtime? What sun direction is used, when the billboards are generated?
    I also tried using the tree manager, but I still can't seem to be able to make the billboards shadow match the shadow on the actual model.
     
    Last edited: May 16, 2022
  19. Grigler_f

    Grigler_f

    Joined:
    May 14, 2020
    Posts:
    24
    Hello, are there any plans for adding API support for using NativeArrays in PrefabVariationData rather than managed arrays? We use the no GameObject pipeline with large numbers of instances and make heavy usage of the JobSystem, being able to populate a NativeArray for the data in an IJob rather than a manage array would be largely benficial for us
     
  20. roundyyy

    roundyyy

    Joined:
    Dec 23, 2019
    Posts:
    112
    Hi, Was there any change how cross fade on trees is handled on recent update? It's not fading correctly now after update, before it was less noticeable, so transition was very smooth, now there is moment where you can badly see dithering . Thanks

    Edit : just reverted from backup to previous version and transition is correct again

    Please also add SceneName to billboard prototype data name or some additional folders for each scene, so billboard of the same trees from other scenes are not overwritten (this is very annoying)
     
    Last edited: May 18, 2022
  21. GurhanH

    GurhanH

    Joined:
    Apr 24, 2017
    Posts:
    539
    The CPU thread taking 150ms, is caused by the GPU thread. When you add 100k instances of a mesh that has 2k vertices, that sums up to 200M vertices which is a lot to process.
    Additionally for each instance the Boids compute shader loops through all of the other instances to make its calculations, so the time it takes would increase exponentially when the instance counts increase. This would not be true for your grass placement compute shader. Also, Boids compute shader has to run every frame, while a grass placement shader does not need to.

    As for recommendations:
    - Don't use a mesh with 2k vertices for your grass, if you do, have LODs or billboards for distant objects to reduce the vertex amount.
    - Every compute shader is different. Don't use ones performance to get an idea about the other ones.

    Hi there,
    Can you please make a bug report following this guide, and provide the information that is requested there, so we can try and reproduce the issue?

    Hi there,
    and thank you for the feedback. We will look into adding new API methods for this.

    Hi there,
    If you can make a bug report following this guide, we can investigate the issue.
     
  22. Ladrik

    Ladrik

    Joined:
    Mar 22, 2015
    Posts:
    20
    Hi, I've started implementing GPUI into my project and I'm using it to render trees right now. I'm trying to figure out how to get the lighting on the trees to look right. The trees look nice with light probe enabled but when the player walks around the shading of the entire forest shifts around to different values. I have a day/night cycle so when I disable light probes the trees look like they are glowing in the dark.

    Any advice on this situation? If I could set the light probes to match something static other than the main camera that would work.
     
  23. Grigler_f

    Grigler_f

    Joined:
    May 14, 2020
    Posts:
    24
    Brilliant, looking forward to seeing that.
     
  24. theepicmixer

    theepicmixer

    Joined:
    Jan 18, 2015
    Posts:
    7
    Hello,
    I recently bought gpu instancer. The details were working on the first terrain i tested it on, but when I tried it in fresh scene on a fresh terrain the details come up covered in red (they have a texture, but it's red for some reason)
     
  25. mrCharli3

    mrCharli3

    Joined:
    Mar 22, 2017
    Posts:
    976
    How do I do the equivalent of:

    - get material property block
    - set material property block float
    - apply material property block

    using GPUI?
     
  26. GurhanH

    GurhanH

    Joined:
    Apr 24, 2017
    Posts:
    539
    Hi there,
    GPU Instancer does not support light probes, you can see the lighting limitations from here.
    By default all instances share the same probe value, however there is an option on the manager to disable it completely.
    Disable Light Probes: While using Indirect GPU Instancing, by default all the instances share the same probe value. You can disable light probe usage by enabling this option.
    In this case I would recommend disabling the light probe usage and editing the shader/material to solve the glowing issue.


    Hi there,
    I would suggest checking the Healty/Dry colors on the prototypes, they might be set to red.

    You can not use material property blocks to make instance based variations while using indirect GPU instancing. All of the instances share a single material property block. For using instance based variations with GPUI, please see Material Variations documentation.
     
  27. marcell123455

    marcell123455

    Joined:
    Jun 18, 2014
    Posts:
    275
    Hi,

    I need some help. I am using a self written pooling system for street props like a streetlamp in my example. I want to use The prefab manager to render these streetlamps instanced. I created a prototype of the prefab and enabled:
    Enable Runtime Modifications, Add/Remove Instances At Runtime, Auto. Add/Remove Instances, Auto Update Transform Data (since they are destroyable have a rigidbody and can move and rotate then).

    When I now press play, I get this error
    Code (CSharp):
    1. ArgumentNullException: Value cannot be null.
    2. Parameter name: key
    3. System.Collections.Generic.Dictionary`2[TKey,TValue].FindEntry (TKey key) (at <695d1cc93cca45069c528c15c9fdd749>:0)
    4. System.Collections.Generic.Dictionary`2[TKey,TValue].TryGetValue (TKey key, TValue& value) (at <695d1cc93cca45069c528c15c9fdd749>:0)
    5. GPUInstancer.GPUInstancerPrefabRuntimeHandler.GetPrefabManager () (at Assets/GPUInstancer/Scripts/GPUInstancerPrefabRuntimeHandler.cs:67)
    6. GPUInstancer.GPUInstancerPrefabRuntimeHandler.OnEnable () (at Assets/GPUInstancer/Scripts/GPUInstancerPrefabRuntimeHandler.cs:41)
    7. UnityEngine.GameObject:SetActive(Boolean)
    8. PropPoolSpawner:OnTriggerEnter(Collider) (at Assets/My Assets/Breakable Props/Prefabs/PropPoolSpawner.cs:38)
    9.  

    My player has a sphere trigger and I have triggers in my scene. If the player trigger enters the scene prop triggers it will take a gameobject (Streetlamp) from the object pool that was initiated at the start at the scene and will search for a disabled object. If it found one, it will move and rotate the streetlamp at the prop triggers position and does SetActive(true) to enable it. If it leaves the player it disables that streetlamp. I assume I would have to register and unregister the streetlamp manually before it get enabled or disabled, right? How do I do that!

    Thanks ;)
     
  28. GurhanH

    GurhanH

    Joined:
    Apr 24, 2017
    Posts:
    539
    Hi there,
    Auto. Add/Remove Instances should work in your setup when you enable/disable instances. However from the error it looks like one or more of the prefabs lost their prototype references, which is causing the ArgumentNullException. There might be some prefab prototypes that you deleted, but the components are still attached (this might happen when you delete them manually instead of from the manager).

    Please check your prefabs and remove the "GPU Instancer Prefab" and "GPU Instancer Prefab Runtime Handler" components only on the prefabs that has no prototype reference. You can see the Prototype SO under GPU Instancer Prefab script.
    upload_2022-5-24_10-12-36.png
     
  29. marcell123455

    marcell123455

    Joined:
    Jun 18, 2014
    Posts:
    275
    Hi Gurhan,

    Thanks for the quick answer. But I never deleted any of these components. So I was searching and I guess I found the actual problem. Something is going wrong when it creates the prototype of my prefab, after the drag and drop.
    Code (CSharp):
    1. NullReferenceException: Object reference not set to an instance of an object
    2. GPUInstancer.GPUInstancerUtility.DetermineTreePrototypeType (GPUInstancer.GPUInstancerPrototype prototype) (at Assets/GPUInstancer/Scripts/Core/Static/GPUInstancerUtility.cs:1544)
    3. GPUInstancer.GPUInstancerUtility.GeneratePrefabPrototype (UnityEngine.GameObject go, System.Boolean forceNew, System.Boolean attachScript) (at Assets/GPUInstancer/Scripts/Core/Static/GPUInstancerUtility.cs:1348)
    4. GPUInstancer.GPUInstancerUtility.SetPrefabInstancePrototypes (UnityEngine.GameObject gameObject, System.Collections.Generic.List`1[T] prototypeList, System.Collections.Generic.List`1[T] prefabList, System.Boolean forceNew) (at Assets/GPUInstancer/Scripts/Core/Static/GPUInstancerUtility.cs:1299)
    5. GPUInstancer.GPUInstancerPrefabManager.GeneratePrototypes (System.Boolean forceNew) (at Assets/GPUInstancer/Scripts/GPUInstancerPrefabManager.cs:118)
    6. GPUInstancer.GPUInstancerPrefabManagerEditor.AddPickerObject (GPUInstancer.GPUInstancerPrefabManager _prefabManager, UnityEngine.Object pickerObject, GPUInstancer.GPUInstancerPrototype overridePrototype) (at Assets/GPUInstancer/Scripts/Editor/GPUInstancerPrefabManagerEditor.cs:203)
    7. GPUInstancer.GPUInstancerPrefabManagerEditor.AddPickerObject (UnityEngine.Object pickerObject, GPUInstancer.GPUInstancerPrototype overridePrototype) (at Assets/GPUInstancer/Scripts/Editor/GPUInstancerPrefabManagerEditor.cs:74)
    8. GPUInstancer.GPUInstancerManagerEditor+<>c__DisplayClass35_0.<DrawGPUInstancerPrototypeAddButton>b__1 (UnityEngine.Object o) (at Assets/GPUInstancer/Scripts/Editor/GPUInstancerManagerEditor.cs:484)
    9. GPUInstancer.GPUInstancerEditorConstants.DrawColoredButton (UnityEngine.GUIContent guiContent, UnityEngine.Color backgroundColor, UnityEngine.Color textColor, UnityEngine.FontStyle fontStyle, UnityEngine.Rect buttonRect, UnityEngine.Events.UnityAction clickAction, System.Boolean isRichText, System.Boolean dragDropEnabled, UnityEngine.Events.UnityAction`1[T0] dropAction, UnityEngine.GUIStyle style) (at Assets/GPUInstancer/Scripts/Editor/GPUInstancerEditorConstants.cs:573)
    10. GPUInstancer.GPUInstancerManagerEditor.DrawGPUInstancerPrototypeAddButton () (at Assets/GPUInstancer/Scripts/Editor/GPUInstancerManagerEditor.cs:474)
    11. GPUInstancer.GPUInstancerManagerEditor.DrawGPUInstancerPrototypesBox () (at Assets/GPUInstancer/Scripts/Editor/GPUInstancerManagerEditor.cs:412)
    12. GPUInstancer.GPUInstancerPrefabManagerEditor.OnInspectorGUI () (at Assets/GPUInstancer/Scripts/Editor/GPUInstancerPrefabManagerEditor.cs:54)
    13. UnityEditor.UIElements.InspectorElement+<>c__DisplayClass59_0.<CreateIMGUIInspectorFromEditor>b__0 () (at <d4fb0f5bc2524ac39bb755624e6a18e7>:0)
    14. UnityEngine.GUIUtility:ProcessEvent(Int32, IntPtr, Boolean&)

    thanks
     
  30. GurhanH

    GurhanH

    Joined:
    Apr 24, 2017
    Posts:
    539
    Please check the LOD Group component on your prefab and see if there are any missing renderer references or empty levels. If not, try removing and re-adding the LOD Group component. Also check the Mesh Renderers if there are any missing mesh/material references.
     
  31. marcell123455

    marcell123455

    Joined:
    Jun 18, 2014
    Posts:
    275
    Hi Gurhan,

    removing a empty LOD group fixed the errors. Thanks you! Just one last thing. My streetlamps are destroyable. When I now destroy them, the mesh won´t move / rotate with the colliders/ rigidbodys anymore even though I have "update transform data" enabled.

    https://imgur.com/tAw9OKQ

    What transform exactly gets updated? my colliders and rigidbody are on a child gameobject of that gameobject that holds the mesh. is that a problem?

    thanks
     
    Last edited: May 24, 2022
  32. richard-firehose

    richard-firehose

    Joined:
    May 31, 2019
    Posts:
    15
    Hello!

    I was looking through the forum and documentation to see if there's a way to use both the game objectless workflow and the material variation systems together. From what I can tell, the variation system relies on the gpuInstancerID that only exists on prefab instances. Is there a way to go game objectless and still have the variations?

    Thanks!

    Richard
     
  33. GurhanH

    GurhanH

    Joined:
    Apr 24, 2017
    Posts:
    539
    Hi there,

    Only the parent GameObject of a prefab prototype can be added/removed or moved. If you have child renderers that also needs to be added/removed or moved, they need to be also defined as prototypes.

    Hi there,

    There are also API methods that takes arrays for variation: DefineAndAddVariationFromArray and UpdateVariationFromArray
    The game objectless instances will use the variations that are on the same index of the array.
     
  34. jarrednorris

    jarrednorris

    Joined:
    Aug 8, 2020
    Posts:
    5
    Hello,

    I am having a weird issue in GPUInstancer where one of the spawned instances is rendering at the camera position and seems to be in some way linked to the camera as it is moving through the scene with the camera, when the intention is for all the instances of the prototype to have a static position. All of the assets are being added at runtime to the prefab manager and then a JSON file with the position for individual assets is being read and then used to build a TRS matrix4x4 for each instance which is then spawned without gameObjects with the following code

    Code (CSharp):
    1.  
    2. var prefabPrototype = GPUInstancerAPI.DefineGameObjectAsPrefabPrototypeAtRuntime(prefabManager, assetPrefab);
    3. GPUInstancerAPI.InitializeWithMatrix4x4Array(prefabManager, prefabPrototype, matrix4X4Array);
    4. GPUInstancerAPI.SetInstanceCount(prefabManager, prefabPrototype, instanceCount);
    5.  

    To debug this myself I attempted to compare the original JSON positions with the Instance positions in GPUI by using

    Code (CSharp):
    1.  
    2. var runtimeData = prefabManager.GetRuntimeData(prefabPrototype);
    3. for (var i = 0; i < runtimeData.instanceTransformAccessArray.length; i++)
    4. {
    5.  
    6.      var runtimePosition = runtimeData.instanceTransformAccessArray[i].position;
    7.      var distance  = Vector3.Distance(runtimePosition, jsonPosition)
    8.      if (distance > 0.1f)
    9.      {
    10.           Debug.LogWarning($"actual GPUI: {position} \n " + $"actual json position: {jsonPosition} \n" +  $"distance: {distance}");
    11.      }
    12.  
    13. }
    14.  
    but I am given an object uninitialised error when trying to accessruntimeData.instance TransformAccessArray. Is there a way I can initialise these values? or a different way I'm meant to go about accessing the transform data when using no gameObjects?
    (I also tried accessing runtimeData.instanceDataNativeArray but hit the same error)

    As it is parenting to the camera, I thought maybe it could have something to do with me using the code

    Code (CSharp):
    1.  
    2. GPUInstancerAPI.SetCamera(cameraComponent);
    3.  
     
    Last edited: May 26, 2022
  35. richard-firehose

    richard-firehose

    Joined:
    May 31, 2019
    Posts:
    15
    Oh perfect, thank you!
     
  36. GurhanH

    GurhanH

    Joined:
    Apr 24, 2017
    Posts:
    539
    Hi there,

    Instances following camera position means that the shader you are using does not have a correct gpu instancing setup. Specifically, it is missing the UNITY_SETUP_INSTANCE_ID call in the vertex method.
    You can see detailed information about shader setup from this documentation.
     
    SteveKouts likes this.
  37. Spikebor

    Spikebor

    Joined:
    May 30, 2019
    Posts:
    281
    @GurhanH Hello bro, do you check out HDRP with Unity 2022.1f1 yet ?

    Something is very wrong going on. As I remember in your demo scenes, there is very HUGE fps improve if we toggle GPUI on compared to off.
    But now, when on it's 70 fps, and off it's 55 fps.
    Not so much improvement. I remember it's night and day, like I get about 400 fps or something.
    For any demo scene the result is the same, but if you want to look at a specific scene, try TreeInstancingDemo.
    At the moment I don't know if it's Unity 2022 or your new version update has something wrong, but it's like that.
     
  38. DigitalChaotics

    DigitalChaotics

    Joined:
    Dec 18, 2013
    Posts:
    25
    Issues with rendering to a cubemap?

    In the code below, if 'manager' is non-null (a valid PrefabManager), then nothing appears in the final render (OutputTexture), except for the background skybox.

    Conversely, if 'manager' is null (telling the code "do not use GPUI"), then everything works fine.

    NOTE:
    It fails for both mono and stereo recording.
    "TRS" is just a Transform lookalike.
    The 'Cubemap' is actually a RenderTexture whose dimension is Cube.

    Code (CSharp):
    1.    
    2.  
    3. // Copy the proto camera settings into the CubemapCamera
    4. var camera = CubemapCamera;
    5. camera.CopyFrom(protoCamera);
    6.  
    7. // Make sure the CubemapCamera is set up
    8. camera.cameraType = CameraType.Game;
    9. camera.usePhysicalProperties = true;
    10. camera.fieldOfView = 90;
    11. camera.sensorSize = new Vector2(64, 64);
    12. camera.focalLength = 32;
    13. camera.aspect = 1f;
    14. camera.allowHDR = true;
    15. camera.allowMSAA = true;
    16. camera.stereoSeparation = stereo ? EyeSeparation : float.Epsilon;
    17.  
    18. // Move to position
    19. camera.gameObject.SetPlace(new TRS(protoCamera.transform));
    20.  
    21. if (manager) {
    22.     GPUInstancerAPI.SetCamera(manager, camera);
    23. }
    24.  
    25. // Capture the frame into a cubemap & render to the output texture
    26. if (stereo) {
    27.     // Left
    28.     camera.RenderToCubemap(Cubemap, 63, Camera.MonoOrStereoscopicEye.Left);
    29.     Cubemap.ConvertToEquirect(OutputTexture, Camera.MonoOrStereoscopicEye.Left);
    30.  
    31.     // Right
    32.     camera.RenderToCubemap(Cubemap, 63, Camera.MonoOrStereoscopicEye.Right);
    33.     Cubemap.ConvertToEquirect(OutputTexture, Camera.MonoOrStereoscopicEye.Right);
    34. }
    35. else {
    36.     camera.RenderToCubemap(Cubemap, 63, Camera.MonoOrStereoscopicEye.Right); // << Mono?  NO!
    37.     Cubemap.ConvertToEquirect(OutputTexture);                                // << Mono?  YES!
    38. }
    39.  
    40. // Write the frame to the video file
    41. MG.LogInfo($"Adding frame {FrameCounter} @ {LocalTime:F3}");
    42. CameraCapture.RecordFrame(OutputTexture);
    43.  
    44. if (manager) {
    45.     GPUInstancerAPI.SetCamera(manager, protoCamera);
    46. }
    47.  
    48.  
    49. // ---------------------
    50. // My PrefabManager setup
    51. prefabManager.isFrustumCulling = true;
    52. prefabManager.isOcclusionCulling = true;
    53. prefabManager.lightProbeDisabled = true;
    54. prefabManager.minCullingDistance = 0;
    55. prefabManager.enableMROnManagerDisable = true;
    56. prefabManager.enableMROnRemoveInstance = true;
    57. prefabManager.autoSelectCamera = false;
    58.  
    59. var camera = SourceCamera;
    60. if (!camera) {
    61.     camera = Camera.main;
    62. }
    63. prefabManager.SetCamera(camera);
    64.  
    65.  
     
    Last edited: May 29, 2022
  39. GurhanH

    GurhanH

    Joined:
    Apr 24, 2017
    Posts:
    539
    Hi there,
    We checked version 2022 and did not see any issues.
    You will not see frame rates similar to the ones you saw in built-in render pipeline in HDRP. HDRP is inherently slow, you won't see high fps even on an empty scene.
    GPUI improves the rendering performance of the objects it is rendering, it can not improve the performance of the render pipeline.
    For example, here is results of my test:
    No trees rendering: 9.5 ms - 105 FPS
    Trees rendered by Unity terrrain: 23.5 ms - 43 FPS
    Trees rendered by GPUI: 15.8 ms - 63 FPS
    You can see that Unity terrain adds an additional 14 ms for the tree rendering while GPUI adds 6.3 ms. While it is a big improvement, it is not as impressive as before mainly because HDRP is not optimized.

    Hi there,

    I did not test the RenderToCubemap specifically, so I am not sure if it supports indirect instancing.
    However one issue here is that GPUI draw calls are made in the LateUpdate method of the manager, so you need to call it manually after you set the camera and before the RenderToCubemap call.
     
  40. DigitalChaotics

    DigitalChaotics

    Joined:
    Dec 18, 2013
    Posts:
    25
    I'll try to gather more info on the RenderTexture/Cube config for you.

    "it"? What needs to be called?
     
  41. jRocket

    jRocket

    Joined:
    Jul 12, 2012
    Posts:
    700
    Will there be any improvements to shadow culling? I have have a lot of shadows popping off with that option on and it is very noticeable. It looks like the shadows are not being culled separately from culling of the tree instance itself. I have to leave that off, but it's a pretty big FPS loss.

    ShadowPopping.gif
     
  42. Spikebor

    Spikebor

    Joined:
    May 30, 2019
    Posts:
    281
    Thank you bro for your explaination.
    However I don't think 9.5ms overhead as default is reasonable, might ask Unity about it.
    If they say it's as it is then it's nut.
     
  43. sharat

    sharat

    Joined:
    Jun 24, 2011
    Posts:
    3
    Hi, I'm using the no object workflow and it seems to be working okay. However, it seems to throw a NullReferenceException whenever I call
    InitializeWithMatrix4x4Array
    with a zero-length matrix array. Is there a more correct way to reduce the number of displayed instances to zero?


    Code (CSharp):
    1.                 if (isResizing)
    2.                 {
    3.                     System.Array.Resize(ref _matrix4x4Array, curList.Count);
    4.                     GPUInstancerAPI.InitializeWithMatrix4x4Array(gpuiPrefabManager, prefabPrototype, _matrix4x4Array);
    5.                 }
    6.                 GPUInstancerAPI.UpdateVisibilityBufferWithMatrix4x4Array(gpuiPrefabManager, prefabPrototype, _matrix4x4Array);
    7.  
    Exception
     
  44. GurhanH

    GurhanH

    Joined:
    Apr 24, 2017
    Posts:
    539
    You need to call the LateUpdate method, that is where the draw calls are made.
    Code (CSharp):
    1.  
    2. if (manager) {
    3.     GPUInstancerAPI.SetCamera(manager, camera);
    4.     manager.LateUpdate();
    5. }
    6.  
    7. // Capture the frame into a cubemap & render to the output texture
    8. ...
    9.  
    GPUI does not have a separate frustum or occlusion culling system for shadows and we do not plan to add one. Considering all possible scene setups, a generic shadow culling system would be very complex and slow which beats the purpose.
    So if you have performance issues because of shadows, I recommend to look at the Quality Settings (shadow cascades, shadow distance etc.). And within GPUI, you can set custom shadow distance and also have different LODs for shadows.

    Hi there,
    The Detail Manager has features that improves visual quality while adversely affecting performance. You can see more information about them from this documentation. Mainly, enabling shadows and cross-quads affects the performance the most.

    Hi there,
    There is the SetInstanceCount API which can be used with a zero instanceCount value.
     
    hippocoder likes this.
  45. perholmes

    perholmes

    Joined:
    Dec 29, 2017
    Posts:
    296
    Prefab Manager vs. Instancer API Question

    I'm trying to judge the impact on scene size and performance by using prefabs vs. constructing the scene via the API. The case I'd like to understand is a forest of 10,000 trees made out of 10 prefabs.

    If I do them as prefabs, there are 10,000 instances physically in a folder in Unity and the Prefab Manager manages them. Their only difference is transform (pos/scale/rotation). If I do them as API calls, I have the transform data for them stored as data (9 floats), and use this to instantiate 10,000 items via the API.

    * Is there a material performance difference between these two ways?

    * How does the editor handle 10,000 game objects in a folder? They wouldn't be there if I used the API.

    * Is there some per-frame evaluation that happens on GameObjects that doesn't happen when populating via the API directly?

    * How much does my DISTRIBUTION scene size increase with Prefabs compared to simply storing 9 floats?

    I want to use prefabs unless there's a large penalty to performance or scene size, because each tree can be positioned by a human. API seems to lend itself better to procedural generation, and is harder to tweak.
     
  46. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    Lovely asset but I really should pay attention to supported devices first! I have reached out in PM!
     
  47. perholmes

    perholmes

    Joined:
    Dec 29, 2017
    Posts:
    296
    Curious, what device are you finding unsupported?
     
  48. GurhanH

    GurhanH

    Joined:
    Apr 24, 2017
    Posts:
    539
    Hi there,

    In this case, rendering performance will be the same if you use no-GameObjects or prefab instances.

    When you have prefab instances in the scene, all the information about the prefab instance and their components will be serialized in the scene. It will use up more memory and adding/removing will be slower because of memory allocations and garbage collection.

    GPUI disables the Mesh Renderer components on the GameObjects, so their per-frame overhead will be avoided. I am not sure how Unity internally handles Transform components, but they are handled quite fast. The rest depends on the other components you have on the GameObject. For example, if you have colliders, you will see Physics updates regularly.

    I can not say exactly how much memory it would take when you use prefab instances. However if you serialize 10000 Matrix4x4s (which GPUI uses for transform information instead of 9 floats) , it would take 0.64MB.

    In conclusion, if you do not have memory limitations on your target devices, you should be fine with using 10k GOs if it is making things easier. But if you have memory limitations - need fast initialization - has to add/remove GOs often, then it would be better to use no-GOs.
     
    hippocoder and perholmes like this.
  49. perholmes

    perholmes

    Joined:
    Dec 29, 2017
    Posts:
    296
    Awesome answer, thank you very much!
     
  50. cloverme

    cloverme

    Joined:
    Apr 6, 2018
    Posts:
    198
    This is such a fantastic tool, thanks for continuing to update it. It's insane how something like this hasn't been adopted by Unity.
     
    GurhanH likes this.