ProjectPhysX / FluidX3D

The fastest and most memory efficient lattice Boltzmann CFD software, running on all GPUs via OpenCL. Free for non-commercial use.
https://youtube.com/@ProjectPhysX
Other
3.81k stars 301 forks source link

Opaque solid object voxels? #45

Closed SLGY closed 1 year ago

SLGY commented 1 year ago

I've been searching around for a few hours in the kernel and making lots of attempts to change parts of the code, but I haven't been able to find a way (if possible) to make the solid object voxels an opaque color (they're currently a grey set of axis lines with the remainder of the cube transparent). In some situations it would be good to prevent the coloured vorticity surfaces from appearing through the object from the other side for the sake of clarity.

I'm guessing there's something in +R(kernel void graphics_q, but is anyone aware of how to achieve this?

ProjectPhysX commented 1 year ago

Replace the graphics_flags kernel in src/kernel.cpp with the code below. You can also change the color to different RGB values than 127<<16|127<<8|127 or write it in hex as 0xRRGGBB.

)+"#ifndef FORCE_FIELD"+R(
)+R(kernel void graphics_flags(const global uchar* flags, const global float* camera, global uint* bitmap, global int* zbuffer) {
)+"#else"+R( // FORCE_FIELD
)+R(kernel void graphics_flags(const global uchar* flags, const global float* camera, global uint* bitmap, global int* zbuffer, const global float* F) {
)+"#endif"+R( // FORCE_FIELD
    const uint n = get_global_id(0);
    const uint3 xyz = coordinates(n);
    if(xyz.x==def_Nx-1u || xyz.y==def_Ny-1u || xyz.z==def_Nz-1u) return;
    uint j[8];
    const uint x0 =  xyz.x; // cube stencil
    const uint xp =  xyz.x+1u;
    const uint y0 =  xyz.y    *def_Nx;
    const uint yp = (xyz.y+1u)*def_Nx;
    const uint z0 =  xyz.z    *def_Ny*def_Nx;
    const uint zp = (xyz.z+1u)*def_Ny*def_Nx;
    j[0] = n       ; // 000
    j[1] = xp+y0+z0; // +00
    j[2] = xp+y0+zp; // +0+
    j[3] = x0+y0+zp; // 00+
    j[4] = x0+yp+z0; // 0+0
    j[5] = xp+yp+z0; // ++0
    j[6] = xp+yp+zp; // +++
    j[7] = x0+yp+zp; // 0++
    float v[8];
    for(uint i=0u; i<8u; i++) v[i] = (float)((flags[j[i]]&TYPE_BO)==TYPE_S);
    float3 triangles[15]; // maximum of 5 triangles with 3 vertices each
    const uint tn = marching_cubes(v, 0.5f, triangles); // run marching cubes algorithm
    if(tn==0u) return;
    float camera_cache[15]; // cache camera parameters in case the kernel draws more than one shape
    for(uint i=0u; i<15u; i++) camera_cache[i] = camera[i];
    const float3 offset = (float3)((float)xyz.x+0.5f-0.5f*(float)def_Nx, (float)xyz.y+0.5f-0.5f*(float)def_Ny, (float)xyz.z+0.5f-0.5f*(float)def_Nz);
    for(uint i=0u; i<tn; i++) {
        const float3 p0 = triangles[3u*i   ]+offset;
        const float3 p1 = triangles[3u*i+1u]+offset;
        const float3 p2 = triangles[3u*i+2u]+offset;
        const float3 p=(p0+p1+p2)/3.0f, normal=cross(p1-p0, p2-p0);
        const uint c = lighting(127<<16|127<<8|127, p, normal, camera_cache);
        draw_triangle(p0, p1, p2, c, camera_cache, bitmap, zbuffer);
        //draw_line(p0, p1, c, camera_cache, bitmap, zbuffer); // wireframe rendering
        //draw_line(p0, p2, c, camera_cache, bitmap, zbuffer);
        //draw_line(p1, p2, c, camera_cache, bitmap, zbuffer);
    }
)+"#ifdef FORCE_FIELD"+R(
    const uchar flagsn_bo = flags[n]&TYPE_BO;
    const float3 p = position(xyz);
    if(flagsn_bo==TYPE_S) {
        const float3 Fn = def_scale_F*(float3)(F[n], F[def_N+(ulong)n], F[2ul*def_N+(ulong)n]);
        const float Fnl = length(Fn);
        if(Fnl>0.0f) {
            const uint c = iron_color(255.0f*Fnl); // color boundaries depending on the force on them
            draw_line(p, p+5.0f*Fn, c, camera_cache, bitmap, zbuffer); // draw colored force vectors
        }
    }
)+"#endif"+R( // FORCE_FIELD
}
SLGY commented 1 year ago

Edit: don't think I can reopen this issue, so I'll try to @you for some help?

That's excellent, thankyou for that. @ProjectPhysX I seem to have lost the green boundary around the whole cube though. I've tried uncommenting the "draw_line" lines that mention wireframe rendering, and also tried adding in some of the old code that was related to drawing the boundary but I can't seem to get it. How do I get the green boundary cube back again?