Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Native access for VBO or ComputeBuffer

Discussion in 'Scripting' started by qdrhbdfq, Jan 9, 2015.

  1. qdrhbdfq

    qdrhbdfq

    Joined:
    Aug 19, 2013
    Posts:
    3
    I am performing physics simulations on deformable object on GPU (with OpenCL) via a native plugin and I need to display the deformed meshes in Unity.

    Currently I copy the deformed meshed from the GPU to the CPU in the native plugin. Then I copy the data from the native plugin into the C# code. And finally I set the vertices of the Mesh instances (which copy the data from the CPU to the VBO in the GPU). This method is obviously inefficient and I would like to avoid passing all the data through the CPU.

    Is it possible to get a direct access to the VBO in a native plugin? If so I could directly copy my meshes from the OpenCL buffer directly into the VBO.

    If it is not possible, is it possible to at least get the native identifier of a ComputeBuffer (like Texture.GetNativeTexturePtr())? With it I could fill one with my meshes and bypass the VBO with a vertex shader.
     
    bilke and CKahler like this.
  2. qdrhbdfq

    qdrhbdfq

    Joined:
    Aug 19, 2013
    Posts:
    3
  3. NavyFish

    NavyFish

    Joined:
    Aug 16, 2013
    Posts:
    28
    Did you find a solution to this? I'm also looking for a way to get a native identifier to a ComputeBuffer object.

    I don't know if you can access the 'Unity-managed' VBO (or whatever the DirectX equivalent of a VBO is..) from within a native plugin, but I DO know you can use ComputeShaders in Unity 5.0, which is something I'm doing for a procedural terrain program.

    The ComputeShader performs whatever arbitrary calculations I want on the GPU (in this case single-pass heightmap generation, although using a ping-pong set of buffers to perform simulations is perfectly doable), and writes the data to an HLSL "RWStructuredBuffer", which maps to a Unity ComputeBuffer. Then, the vertices are rendered using a custom shader on a Mesh. The mesh is simply a flat plane (grid of NxN vertices), and the custom shader modifies the position of its vertices by reading the corresponding values from the StructuredBuffer. This occurs in a 'pre-pass' (I'm not sure if that's the correct terminology) vertex shader, and thus integrates seamlessly into the physically-based rendering pipeline.

    There are a few disadvantages: Meshes are limited to 65k vertices, so each terrain patch must be < 256 x 256 vertices. Also, until Unity implements a MaterialPropertyBlocks.SetBuffer() function for Materials, each terrain patch must use its own Material (where the only difference between each material is the pointer to a different ComputeBuffer) - and this forces a separate batch per-patch.

    Anyhow, I want to access the ComputeBuffers from a native plugin so I can write a simple asynch readback function that will give my CPU access to the generated terrain data (2 frames after it was generated) without causing a pipeline stall. If you've found a way to do anything like this, I'd love to hear about it!
     
    sebj and bilke like this.
  4. sebj

    sebj

    Joined:
    Dec 4, 2013
    Posts:
    70
    Hi NavyFish, would you mind elaborating on your deformation pre-pass? When you say it integrates into the physically-based pipeline, do you mean you have a surface shaders that use the vertex modifier parameter?

    I am also very interested in using ComputeShaders to generate geometry that can be rendered by Unity's traditional pipeline, both for rendering very large meshes and for doing real-time deformation, but so far it looks like every solution involves re-implementing a considerable part of the pipeline.
     
  5. NavyFish

    NavyFish

    Joined:
    Aug 16, 2013
    Posts:
    28
    Yes, that's exactly what I mean, thanks. It's been a few months since working with Unity so I forgot the term they used.

    Here's a thread in which I'm posting on the same subject. I'll post an example with code hopefully tomorrow or this weekend, just haven't had time to dig back through the terrain project. But there is some more information in there, including a link to some Unity examples which demonstrate modifying vertex properties (ie position) from within a surface Shader.

    My code does this, and accesses the ComputeBuffer containing the results of the Compute Shader's calculation as a StrucutredBuffer (HLSL), looking up the data in that buffer using a vertexID (part of HLSL's 'kernel', requires no configuration to access), to modify the vertex by that data.