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.
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!
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.
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.