oyedoyin.dada Posted February 19, 2025 Posted February 19, 2025 Hello everyone, I'm currently working on a fluid visualization project and I need to move our working GLSL implementation to Unigine. To get my bearings, I'm trying to setup a very simple test case where; 1: The shader takes in the vector minimum and maximum positions of the fluid volume 2: I check for collisions for rays starting at each pixel, looking in the camera direction with the volume. If there is a collision, I check the distance against the depth buffer at this point (to make sure the fluid isn't appearing over other scene objects) 3: The pixel colour is then specified based on a value read from the fluid result sent as a 3d texture to the shader. I've gotten this test working with an HLSL shader in Unity as I hope to use that as a conversion guide(I have attached the script, shader and project files), but my current Cpp implementation is Unigine (script is also attached) isn't working. I can send the camera matrices and bind the shader to render but i'm unable to get the texture communication working. I would really appreciate any help with this problem. VolumeEffect.cs Volume.shader AppWorldLogic.cpp Shader_Playground.zip
vovan675 Posted February 21, 2025 Posted February 21, 2025 Hello! It’s not entirely accurate to write shaders directly in plain HLSL. We recommend using our shader API, and ideally, you should work with basemat and its passes. To bind a texture in your shader, use RenderState::setTexture (and be sure to use an INIT_TEXTURE declaration in the shader as well). For defining uniforms, you’ll need to use the CBUFFER declaration. Additionally, there are already pre-bound uniforms available, such as camera position and other useful data. You can refer to shaders\api\uniforms\common.h to see what’s already accessible. Here’s an example of how to bind and use a color texture and depth buffer with shaders using our shader API AppWorldLogic.cpp CustomVolume.basemat 1
oyedoyin.dada Posted February 21, 2025 Author Posted February 21, 2025 Thank you very much! I'll check it out
oyedoyin.dada Posted February 22, 2025 Author Posted February 22, 2025 Finally got it all to work! I had to convert the vertex position to clip space so the volume renders properly in the scene now. The depth buffer logic also works properly which fixes our initial problem :) I've attached the files with the sample 3d fluid data in case someone else finds it useful AppWorldLogic.cpp CustomVolume.basemat
oyedoyin.dada Posted February 22, 2025 Author Posted February 22, 2025 Here's the raw render with the actual fluid data from the CUDA-based solver: @vovan675 Do you have a recommendation for an efficient transfer of the data since both the compute and rendering are happening on the GPU? My current implementation requires extracting the CUDA buffer to a float array and then generating a 3D image from that. 1
vovan675 Posted February 24, 2025 Posted February 24, 2025 Hello. You should attempt to retrieve the external memory resource of a 3D texture using texture->getResourceExternalMemory() with the FORMAT_USAGE_SHARED flag. Then, use this resource to create a cudaExternalMemoryHandleDesc object. Next, generate a surface from it by calling cudaCreateSurfaceObject. After that, invoke a CUDA kernel function, passing the texture surface as a cudaSurfaceObject_t parameter. Finally, process the surface within the kernel using surf3Dwrite, and this approach should work effectively without any GPU->CPU transfers, writing directly to texture that used for rendering. 1
Recommended Posts