Search Unity

  1. Unity 2019.4 has been released.
    Dismiss Notice
  2. Good news ✨ We have more Unite Now videos available for you to watch on-demand! Come check them out and ask our experts any questions!
    Dismiss Notice
  3. Ever participated in one our Game Jams? Want pointers on your project? Our Evangelists will be available on Friday to give feedback. Come share your games with us!
    Dismiss Notice

[RELEASED] GPU Instancer

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

  1. Agatho_Kakological

    Agatho_Kakological

    Joined:
    Dec 27, 2019
    Posts:
    2
    @LouskRad Hii I generated a scene using gaia and then applied GPUI to the house prefabs on the scene, previously i was getting 27-35FPS but now after adding GPUI I'm getting 10 fps hardly, any solutions
     
  2. holdingjason

    holdingjason

    Joined:
    Nov 14, 2012
    Posts:
    99
    Yes really hope they are on holiday or something as well. Just moved completely off of Veg Studio Pro which was no where near as fast as what I am getting using GPUI. This blows it away, granted you have to know and think a bit more on what to do but NOT that much more. Crushing my FPS rate and stops the annoying hickups I was getting before in VSP.
     
  3. castor76

    castor76

    Joined:
    Dec 5, 2011
    Posts:
    1,725
    Hi. Thanks for the help, but I did try the second method but it does not add instances. It does register prototype, but it does not add inatances using this way. I know my method of adding instances using matrix is working because if I register prototype in editor time it does work.

    So the problem is if I register prototype in run time as your second method, adding instances using matrix does not work.
     
  4. castor76

    castor76

    Joined:
    Dec 5, 2011
    Posts:
    1,725
    Code (CSharp):
    1. GPUInstancerPrefabPrototype prefabPrototype = GPUInstancerAPI.DefineGameObjectAsPrefabPrototypeAtRuntime(gpuInstancerPrefabManager, protoType.gameObject);
    2. GPUInstancerAPI.InitializeGPUInstancer(gpuInstancerPrefabManager, prefabPrototype);
    3. GPUInstancerAPI.InitializeWithMatrix4x4Array(gpuInstancerPrefabManager, prefabPrototype, ma);
    ma is correctly generated, and prototype is registered but no instances are added.. :(

    Even the document says the method to add instances with prototype registered with DefineGameObjectAsPrefabPrototypeAtRuntime is something else. So using matrix method is not working with that. But there are no method to make this possible.
     
    Last edited: Jun 26, 2020
  5. sebas77

    sebas77

    Joined:
    Nov 4, 2011
    Posts:
    1,205
    The code works because I use it in that way. You need to do some debugging to understand the real reason why it doesn't work. I don't remember to have had particular problems in the past. Are you using the right shaders? The shader must be converted by GPUI to work.
     
  6. castor76

    castor76

    Joined:
    Dec 5, 2011
    Posts:
    1,725
    Yeah, the shader is the right one. it is the converted shader. After attempting to add instances to the manager, and check the manager in inspector, I get 0 count.

    when I use edit mode to add prototype and use the exactly the same matrix array, it does add instances. So both shader set up and matrix set up is correct. humm..
     
  7. LouskRad

    LouskRad

    Joined:
    Feb 18, 2014
    Posts:
    807
    Hi everyone,

    The GPUI team was on a short break and now we are back. I will read and answer questions in order below:

    Please take a look at this wiki article and see if it solves the problem.

    The LOD cross-fade issue is caused by Unity changing their implementation of the cross-fading system. As of now, there are technical limitations that prevent us to customize this and implement a generic cross-fading solution. I can only say that we can do this implementation if and when Unity changes the way they have implemented and limited our access to customizing the cross-fading system.

    What matters for GPUI is the GPU where the rendering is done (i.e. the client computer). You can manage your data in the server and render it using GPUI in client computers within the designed usage of GPUI.

    Your registration of the prototypes seems correct like this. It might be that the matrices used for the registered prototype are the culprit. If you are still having problems with this, you can email us a sample project and we can investigate the problem.

    GPUI uses two different compute shaders; where the camera calculation compute shader decides which instances are culled, and the visibility compute shader decides which instances to append based on the former. You could investigate the code to modify these compute shaders, but implementing a generalized solution for instance group culling would not be feasible.

    What I would suggest instead is implementing your own custom logic to enable and disable the instances based on such groups, and you can use this along with the existing frustum/occlusion culling of GPUI for the enabled instances.

    This is usually related to having many lights in your scene, where in forward rendering each light would run an add pass - resulting in the scene being GPU bound already. In deferred rendering you do not have this problem as there is a dedicated buffer (GBuffer) for this.

    Having said this, some post processing effects might also be slowing the scene down in forward rendering. You could also try using the included Depth/Normals shader instead of the built in one to see if it helps.

    Please take a look at the best practices wiki to see what would make good candidates for adding to GPUI as prototypes. Also, please make sure that you do not see any errors or warnings in the console related to GPUI - which might also be slowing the scene down.

    The reason why GPUI uses a shader variant collection is to get its generated shaders to your build automatically. Since it is in the Resources folder, this is handled without any additional input, but if you need to move this file out of the Resources folder, your solution would also result in the same.

    The number of compute shader calls depend mainly on LODs and shadow settings. Apart from this, your target platform, instantiation logic, etc could also increase or decrease this amount.

    There are three compute shader dispatches that are usually at work when rendering a prototype. Steps are:

    1) culling and LOD calculations
    2) appending of the instance
    3) appending of the instance shadows

    Mostly they use the same systems, with the only difference being that the Detail Manager uses 2D spatial partitioning - which is optimized for terrain details. With this additional step, there might or might not be a performance gain depending on your terrain size, amount of terrains, prototype count, etc.
     
  8. castor76

    castor76

    Joined:
    Dec 5, 2011
    Posts:
    1,725
    Code (CSharp):
    1. Matrix4x4[] ma = new Matrix4x4[o.pos.Count];
    2.  
    3.                 for (int i = 0; i < o.pos.Count; i++)
    4.                 {
    5.                     ma[i] = Matrix4x4.TRS(o.pos[i], Quaternion.identity, Vector3.one * 0.25f);
    6.                 }
    7.  
    8.                 var prefabPrototype = GPUInstancerAPI.DefineGameObjectAsPrefabPrototypeAtRuntime(gpuInstancerPrefabManager, protoType.gameObject);
    9.                 GPUInstancerAPI.InitializeGPUInstancer(gpuInstancerPrefabManager, prefabPrototype);
    10.                 GPUInstancerAPI.InitializeWithMatrix4x4Array(gpuInstancerPrefabManager, prefabPrototype, ma);
    This is snipset of the code I am using to register my prototype and instances. I have confirmed that o.pos array is coming in correctly. It's either I am dumb and made stupid mistake, or this way is not supposed to work?

    The prototype does register this way. It just doesn't add any instances.
     
  9. sebas77

    sebas77

    Joined:
    Nov 4, 2011
    Posts:
    1,205
    @castor76 that code looks correct to me, the problem must be somewhere else. Unluckily it can be so many things that it is hard to guess.
     
  10. holdingjason

    holdingjason

    Joined:
    Nov 14, 2012
    Posts:
    99
    *UPDATE* Ok so started digging more deeply into you api documentation and think I see that you already have examples for this at least I think so.

    "Updates and synchronizes the GPU Instancer detail prototypes with the modifications made in the manager at runtime. Use this if you want to make changes to the detail prototypes at runtime. Prototypes in the manager must be modified before using this. For example usages, see: DetailDemoSceneController and TerrainGenerator"

    So glad your back. Do you have a timeline on Map Magic 2 yet, you had mentioned that it would be updated in your next release.

    On that subject the reason we are looking into that is we have a decent sized open world and looking for ways to optimize the terrain and objects. MM 2 does that of course though not sure if a custom system might not still be more efficient tailored for our needs. SO if we rolled our own using GPUI do you have some recommendations basically we would be pooling a set of terrains, moving the terrain, updating its terrain data, wanting at that point to "refresh" the gpu detail manager that is hooked to that pooled terrain (I am guessing refreshing the detail manager on the fly at runtime is possible and hopefully fast). Game objects not on involved directly with the terrain is no biggy since that would just be using your non game object solution and loading and unloading the data as needed as you moved around.

    So really the question is about the best way to deal with terrain chunks and the details with those terrains in regards to GPUI? This relates back to my previous question on if there was much difference between using prefab manager and non game object loading vs detail manager which is why I was asking that question. One obvious solution is to not use the detail manager for terrains and everything is a prefab but not sure how that would work with grass etc?

    So really looking for some guidance on what would be the best solution. Must have some way to handle the details on generated/pooled terrains since you are planning on integrating with map magic 2.

    Thanks, terrific product and really appreciate the work you have done on this.
     
    Last edited: Jun 26, 2020
  11. sebas77

    sebas77

    Joined:
    Nov 4, 2011
    Posts:
    1,205
    @LouskRad

    The reason why GPUI uses a shader variant collection is to get its generated shaders to your build automatically. Since it is in the Resources folder, this is handled without any additional input, but if you need to move this file out of the Resources folder, your solution would also result in the same.

    The number of compute shader calls depend mainly on LODs and shadow settings. Apart from this, your target platform, instantiation logic, etc could also increase or decrease this amount.

    There are three compute shader dispatches that are usually at work when rendering a prototype. Steps are:

    1) culling and LOD calculations
    2) appending of the instance
    3) appending of the instance shadows


    It's not the first time you tell me about the shaders collection being in the resource folder, but in reality, it doesn't answer my question. I couldn't find the code that explicitly loads that collection and I do not add it in the preload shaders collection list, so I am wondering if I have to care about it somehow to be sure that those shaders are preloaded not just used.

    Regarding the computer shaders, we do not use LODS, but I still see 3 LOD calls per prototype, so I think I need to investigate that further, is that right?

     
  12. castor76

    castor76

    Joined:
    Dec 5, 2011
    Posts:
    1,725
    I "think" I have finally figured out why instances were not showing up. I think it is because after registering the instances, I turn the gameobject of the manager off to toggle it back on for the later usage. But when I do that , I think the instances are lost. The same goes if I disable manager, all added instances are gone..

    Is this by design? It would be cool to have them kept but disabling or deactivating the manager gameobject to simply stop rendering the instances and rerender upon reactivating.

    If there is a good reason why the instances are destroyed on deactivation of manager gameobject instead of just not rendering them, I understand. But having to keep re-add all the instances again is a bit of pain when registered prototypes does stay kept with manager....
     
  13. joshcamas

    joshcamas

    Joined:
    Jun 16, 2017
    Posts:
    1,029
    Oh, okay! That seems very doable :) But don't I need to update the InstanceBuffers (InitializeGPUBuffer), slowing down everything? Or would this be negligible? I know I wouldn't need to create a new instanceDataArray, just update the array values / instancecount / buffercount, would that be enough, or do I need to upload the new data to the GPU, every frame?
     
    Last edited: Jun 26, 2020
  14. sebas77

    sebas77

    Joined:
    Nov 4, 2011
    Posts:
    1,205
    ah! I think we register prototypes from just loaded prefabs, not instanced gameobjects. I am not sure how it works with instances gameobjects, I wouldn't expect GPUI to add any extra monobehaviour on them to keep track of the changes.
     
  15. LouskRad

    LouskRad

    Joined:
    Feb 18, 2014
    Posts:
    807
    Yes it is by design. Since for general use we cannot assume why the manager is being disabled, this is intended to prevent unnecessary memory usage and/or leaks. If you wish to keep instance data but disable rendering, you can use the SetInstanceCount API method to set the instance counts to 0 - effectively disabling their rendering.

    The MM2 integration will indeed be in our next update. We have delayed submitting this update (a week or so) to add a few more features, including a multi-terrain support for the TreeManager. This will help with the performance on multiple terrains with your trees, but this does not apply to the DetailManager. You can add your prefab type details to the TreeManager though.

    The Resources folder is a special folder type in Unity, whatever is in this folder (and whatever is referenced by those that are in this folder) always gets in your builds - including the shaders referenced by a ShaderVariantCollection.

    As for the compute shader dispatch calls, please notice that these are not draw calls, and these 3 steps are dispatch calls for all instances regardless of their LOD counts.

    The InstanceCount for GPUI is responsible for the entire array, so it would not work for segments of this array (e.g. culling instances in the middle of the array). Thus you would need to modify the the new data to the GPU also; one example would be to setting your instances to the GPUI buffer in your own custom compute shader before GPUI's LateUpdate usage.
     
  16. sebas77

    sebas77

    Joined:
    Nov 4, 2011
    Posts:
    1,205
    @LouskRad thanks. Even if it's the resource folder, you still need to use

    Code (CSharp):
    1.  ShaderVariantCollection shaderVariantCollection = Resources.Load<ShaderVariantCollection>(GPUInstancerConstants.SETTINGS_PATH + GPUInstancerConstants.SHADER_VARIANT_COLLECTION_DEFAULT_NAME);
    to load it.

    In your code Resources.Load<ShaderVariantCollection> is used only in the place above, which is used in "
    SetDefaultShaderVariants"

    However, as far as I can see, "SetDefaultShaderVariants" does nothing in a built client. So yeah I am still confused. I am confident I am missing some piece of code, but I want you to confirm it and you must forgive me, but your explanation is still not clear.

    As far as I know the code should do something like :

    Code (CSharp):
    1. var collection = Resources.Load<ShaderVariantCollection>(GPUInstancerConstants.SETTINGS_PATH + GPUInstancerConstants.SHADER_VARIANT_COLLECTION_DEFAULT_NAME);
    2.  
    3. collection.WarmUp()
    but even with code, shaders could be loaded too late (it would be optimal to load shaders in the GPU memory as soon as possible, but this could be an obsolete concept nowadays, it's just what I remember from my old good days as gfx coder)

    Edit: I think I understood why I am confused. You are talking about loading shaders, I am talking about "preloading" them, the equivalent of putting the shader collection in here:

    upload_2020-6-26_20-1-21.png

    I still don't know if to have the best performance I should put your collection in there. That array doesn't just load shaders, it preloads them, which my guess means that it also put load them to the GPU memory as early as possible.

    Regarding the dispatches, I will be back to it once I have more info on my side (I want to study the code more before to ask more questions)
     
    Last edited: Jun 26, 2020
  17. castor76

    castor76

    Joined:
    Dec 5, 2011
    Posts:
    1,725
    I have one more question if I may.

    If I set my array of matrix and supply it to GPUInstancer, will it draw in that particular order? Or is it upto GPU to just draw them in any order it wants per frame?
     
  18. sebas77

    sebas77

    Joined:
    Nov 4, 2011
    Posts:
    1,205
    GPUI doesn't sort the calls at all, but since the batches are quite big anyway it doesn't matter much. The order is probably not the order of submission, but it depends on how the drawcalls are going to be batched. I guess it may draw them in the order of the prototypes registered.
     
  19. castor76

    castor76

    Joined:
    Dec 5, 2011
    Posts:
    1,725
    I was talking about within the batch of per prototype. Where I build array of matrices. Was wonderijng if the gpu will render in the order that I built that array.
     
  20. sebas77

    sebas77

    Joined:
    Nov 4, 2011
    Posts:
    1,205
    It's an interesting question. I didn't check the compute shaders yet, so it's for @LouskRad. GPUInstancer compute shaders are not hard to read, but my current understanding of a compute shader pipeline is too limited. My guess is that GPUI is exploiting GPU instancing and indeed I wouldn't be surprised if the order of the instances is the order of the matrices in the array.
     
  21. ftejada

    ftejada

    Joined:
    Jul 1, 2015
    Posts:
    606
    @LouskRad
    But if I don't use GPU Instancer, LOD cross fade works well natively in Unity HDRP ...
    Can't somehow use the "native" way Unity is doing it?

    By the way, I have sent two emails to the support email regarding the Culling problem and two new problems that are happening to me.

    I have a presentation in 3 weeks and right now it is impossible for me to use GPUI for that presentation demo
    ... So I have a pretty serious problem.
    Would it be possible to give me a Fix/Solution for this time ??? I would greatly appreciate it ... Answer me in the emails if you want.

    Regards
     
  22. juliobds

    juliobds

    Joined:
    Dec 27, 2011
    Posts:
    24
    @LouskRad Just to let you know GPUI isn't working on iOS at all. I tried building the Asteroid example scene and running it on my iPad and I got the following error:

    Execution of the command buffer was aborted due to an error during execution. Caused GPU Hang Error (IOAF code 3)

    I tried rebuilding and using the simulator and the same thing happened. At this moment GPUI is completely unusable on iOS. Unless I missed a critical step, but I couldn't find any specific steps for mobile on the documentation.

    I'm using the latest version of GPUI on the asset store, using URP, and tried with both Unity 2019.4.1f1 and 2020.1.0b13. I'm on macOS Catalina 10.15.3 and Xcode 11.5 .

    I'm running this on a bit of an older machine but it worked in the editor:
    MacBook Pro (Retina, 15-inch, Late 2013), 16GB Ram, NVIDIA GeForce GT 750M 2 GB

    If you cannot reproduce the issue let me know and we can initiate a support email thread.
     
  23. MrDigitalBoss

    MrDigitalBoss

    Joined:
    Feb 28, 2020
    Posts:
    1
    @LouskRad Have a big issue with Gpu Instancer.When instancing grass with it,dynamic blending system according to player position which works at grass's shader,just don't works.How to fix that issue?
     
  24. jaeeunpark

    jaeeunpark

    Joined:
    Feb 3, 2020
    Posts:
    2
    How can I use diffuse profile for HDRP foliage shader?
    I put some definitions on top of shader and diffusionprofilehash as below, but foliage shows only shaded black.
    Am I missing something?

    Definitions
    #define _MATERIAL_FEATURE_SUBSURFACE_SCATTERING 1
    #define _MATERIAL_FEATURE_TRANSMISSION 1

    hard coded setting diffusion profile
    surfaceDescription.DiffusionProfile = asfloat(uint(1081006321));
     
  25. alex_1302

    alex_1302

    Joined:
    Aug 20, 2019
    Posts:
    23
    Hi LousKRad.
    I am using gpu instancer tree Manager. it works fine, but i have a situation and maybe you can help me:
    - i am working in a multiplayer fps. and when the player shoots to a tree i make the tree falls down. to make that effect when the level is loaded i put a capsule collider on every tree on the terrain (is s slow process because my terrain is big), and with every collider i set the tree index of the associated tree, so when the players shoots a tree i get from the collider the tree instance index of the tree, and then i use RemoveInstancesInsideCollider of gpui to delete the tree and then i instance a new tree, but like a regular gameobject (with the same tree prototype, in the same position, with the same rotation and the same scale) of the hitted tree), i get the tree data using my capsule collider. But i was thinking that if there was a method like QueryInstancesInsideCollider (it doesn't exists) returning the tree instances. it would be great, because it
    should eliminate the need for locate a collider in every tree position. My questions: could you help me to get a way to get the tree instances inside a collider ?. I think that it could be very useful to many users like me.

    Thanks ind advance. and i hope you have a nice day.
     
    Last edited: Jul 2, 2020 at 8:09 PM
  26. kanestudio

    kanestudio

    Joined:
    Jan 29, 2018
    Posts:
    3
    Hi LousKRad.
    I have some problems with Grass shadows. The grass is in the shadow side but in the distance the grass completely lit, but when i move the camera near the grass the shadows show up. Did I make any wrong with settings? My setting: camera rendering path: Deferred, Shadow distance 300, Grass using Meadow Environment assets.
     

    Attached Files:

  27. etehau

    etehau

    Joined:
    Aug 8, 2015
    Posts:
    8
    Require OpenGL ES 3.1 (Android 8). So this can't work on Oculus Quest (Android 7.1.1) VR?
     
  28. LouskRad

    LouskRad

    Joined:
    Feb 18, 2014
    Posts:
    807
    Yes, GPUI does neither use the ShaderVariantCollection for loading shaders, nor warming them up. It is only used for shaders to be included in the builds.

    we saw that they were ordered by prototype and instance data, but I cannot say for sure since this would depend on Unity's draw API implementation (and the GPU).

    Thank you for the feedback. We will check if anything has changed on the new Unity versions for the iOS side that will require a change in the GPUI code.

    Most likely the blending system you are using is not compatible with procedural instancing.

    We haven't tested this, so I can't offer any advice on it right now.

    Since the instance data is handled in the GPU, accessing instances with a readback would not be ideal. One way to go about this would be to use the trees with the Prefab Manager (instead of terrain trees with the Tree Manager) and customize the behavior according to your needs.

    This should be related to pipeline render settings and the shader/material or light settings. GPUI shadow settings would not have such an effect as in your video.

    GPUI does not officially support Occulus Quest, because the platform offers limited compute shader support.

    We have had reports from our users that they successfully use GPUI in Occulus Quest, and mainly by limiting their projects to the requirements of this device. However, we have not tested GPUI in this platform and cannot give you the specifics of a correct setup.
     
unityunity