Hexahedron volume plot

How to volume plot a Hexahedron :ice: for colors given at each vertices?

using Meshes, CoordRefSystems ,GLMakie, LinearAlgebra, Unitful

r =  Float32[1.6, 1.754088, 1.9230156, 2.1082115, 2.311243, 2.5338273, 2.7778475, 3.0453684, 3.3386526, 3.6601818, 4.012676, 4.3991165, 4.8227735, 5.287231, 5.7964177, 6.354642, 6.9666257, 7.637547, 8.373081]
θ =  Float32[0.0, 0.09817477, 0.19634955, 0.2945243, 0.3926991]
Ď• =  Float32[0.0, 0.3926991, 0.7853982, 1.1780972, 1.5707964, 1.9634954, 2.3561945, 2.7488935, 3.1415927, 3.5342917, 3.9269907, 4.3196898, 4.712389, 5.105088, 5.497787, 5.8904862, 6.2831855]

g = RectilinearGrid{𝔼,typeof(Spherical(0,0,0))}(r, θ, ϕ)
hxdrn = element(g,1)
spherpts = coords.(vertices(hxdrn))
cartpts =  convert.(Cartesian, spherpts)
viz(hxdrn, alpha=0.3)

@ffreyer What stops us to volume plot a Hexahedron :ice: for colors given at each vertices? Is there some limitation in OpenGL or in Makie.jl itself? Can it be solved with Vulkan?

Ignoring GPU rendering, I think the main thing you need is a function that tells you the color which should go at a given position. For a uniform 3D cartesian grid like a 3D array provides that’s relatively easy. You just find the 8 grid points around the sample position and nest linear interpolations. A tetrahedron is probably also some combination of linear interpolations. Beyond that, no clue. If you want to try working it out, here’s roughly what :absorptionrgba would look like for a single Rect3:

using Colors
using GeometryBasics

function get_interpolated_color(sample_pos, rect_positions, rect_colors)
    # This relies on the order of vertices
    mini = first(rect_positions)
    maxi = last(rect_positions)

    if sample_pos in Rect3f(mini, maxi .- mini)
        color = mapreduce(+, rect_positions, rect_colors) do vertex_pos, color
            interp = abs.(sample_pos - vertex_pos) ./ (maxi - mini)
            return color * prod(interp)
        end

        return color
    else
        return Vec4f(0,0,0,0)
    end
end

rect_positions = coordinates(Rect3f(-0.5, -0.5, -0.5, 1, 1, 1))
rect_colors = [Vec4f(0.5 + 0.5x, 0.5 + 0.5y, 0.5 + 0.5z, 0.1) for (x, y, z) in rect_positions]

width = 400
height = 300
img = [RGBA(0,0,0,0) for x in 1:width, y in 1:height]

R = Mat3f(0.7886752, -0.21132484, -0.57735026, -0.21132484, 0.7886752, -0.57735026, 0.57735026, 0.57735026, 0.5773503)
steps = 100
step_weight = 1.0
for (i, x) in enumerate(range(-1, 1, width))
    @info i
    for (j, y) in enumerate(range(-1, 1, height))
        accumulated_color = Vec3f(0)
        remaining_intensity = 1.0
        for z in range(-1, 1, steps)
            pos = R * Point3f(x, y, z)
            sample_rgba = get_interpolated_color(pos, rect_positions, rect_colors)

            sample_weight = step_weight * sample_rgba[4]
            remaining_intensity *= (1 - sample_weight)
            sample_color = sample_weight * remaining_intensity * Vec3f(sample_rgba)
            accumulated_color += sample_color

            remaining_intensity < 0.01 && break
        end
        img[i, j] = RGBA(clamp.(accumulated_color, 0, 1)..., 1 - remaining_intensity)
    end
end

using GLMakie
image(img)

You’d have to swap out rect_positions and rect_colors for the vertex coordinates and colors of you mesh and write a get_interpolated_color() function that returns the appropriate colors for your mesh. If you have that though, you could also just resample your data into 3D array and run the ray tracing part on the GPU with Makie volume plots.

When it comes to doing this on the GPU, you also have the problem that this doesn’t fit in the normal rendering pipeline. Regardless of which Graphics API you use, the normal rendering pipeline will have a vertex shader which acts on one vertex each, then the API will combine that data into faces and figure out which pixels are covered by them and then run a fragment shader to draw those pixels.
Makie essentially draws the bounding box of the volume plot and does ray tracing inside it for the fragment shader. To do the ray tracing you’ll need all volume data. If it’s on a regular cartesian grid you can simply put it in a 3D texture. That’ll also handle the interpolation for you. For anything else you’ll need to do the interpolation yourself and pack and unpack it yourself. (This could be a bit simpler with compute shaders but Makie doesn’t support them and you’d still need to handle data passthrough and interpolation.)

What stops us from doing this is mainly that it’s a lot of effort for something very specific.

1 Like

I have density values which i will use for coloring. The density array have size of (r, θ, ϕ).

rho = Float32[-129.99329 -160.20337 -325.54758 -4397.118; -116.43426 -153.51779 -344.19086 -4532.1997; -107.907104 -152.00218 -369.87686 -7925.962; -130.99937 -196.26501 -565.8035 4876.3447; -165.3039 -272.68054 -1371.5248 1317.8116; -207.02216 -394.10532 13337.116 794.45966; -296.5668 -715.42914 1128.3673 565.2868; -650.61505 9918.685 539.77625 434.2165; 991.7024 450.0072 313.10022 327.24747; 230.60722 206.73088 208.91093 251.65675; 129.25938 137.04987 157.44899 208.05527; 87.78064 100.1997 125.68948 176.73077; 64.455795 78.02462 104.65618 153.88618; 50.99267 63.01702 88.183174 134.05287; 42.36314 52.81029 75.79579 118.07631; 36.579487 45.86699 66.760185 106.47329; 30.627419 40.20409 60.989166 98.72323; 31.210024 38.868122 57.872925 92.76187;;; -97.99951 -119.31532 -220.96242 -687.9891; -97.82085 -130.18547 -276.36395 -965.10516; -98.47665 -141.93025 -339.3774 -1796.2848; -134.01302 -215.71342 -647.72705 -4676.9937; -193.37137 -351.64053 -4416.303 1341.8435; -282.49567 -602.9082 1830.2158 625.2697; -695.2689 65254.477 594.1931 439.94525; 892.6505 458.99533 326.57098 334.98346; 236.23892 210.58841 211.42093 252.38893; 124.02805 131.86818 153.1588 200.11765; 83.86573 96.22058 120.437325 167.90582; 61.64901 74.19523 98.79456 142.5238; 49.126213 60.578144 84.34129 124.54496; 41.30804 51.567978 73.375046 110.50345; 35.80516 45.16255 65.01548 99.61272; 32.058582 40.469498 58.85535 90.72365; 27.29905 36.278343 54.80211 84.361984; 27.995182 35.647793 52.47851 79.759926;;; -88.32891 -106.34936 -183.96466 -411.2385; -95.15461 -126.207756 -247.87685 -576.69073; -104.95081 -152.06787 -329.79944 -858.3828; -159.14694 -258.02948 -645.56384 -1342.325; -276.98218 -529.34357 -4998.0034 3926.2307; -573.5366 -1806.269 1258.2404 764.5956; 1461.9509 675.75964 447.66074 441.1562; 271.2118 252.6234 254.31181 306.23358; 142.62761 150.82426 174.41473 229.28433; 93.49399 107.17448 132.91736 181.42578; 69.50536 82.192116 107.063194 149.93611; 54.30714 65.54972 88.69273 125.49056; 45.596737 55.417667 76.50803 108.971924; 40.025867 48.95047 67.98315 97.70543; 36.02604 44.480335 62.255184 90.19685; 33.24014 41.20718 58.20765 83.94832; 28.843754 37.7476 55.148563 79.008736; 29.754904 37.858013 53.759083 75.96447;;; -94.45789 -113.24129 -184.16296 -339.96155; -109.87668 -144.46954 -259.5737 -459.55447; -133.20793 -194.84044 -369.18134 -596.21735; -240.39082 -372.4391 -693.8989 -969.6099; -691.7937 -1567.7675 -7015.6597 -3859.6328; 1781.2776 1136.2345 879.4682 1221.6077; 333.36316 336.5944 369.71677 515.06256; 168.04167 186.1875 225.51904 317.45044; 113.134384 130.53821 165.18251 233.4395; 86.08579 101.2036 131.57219 184.71846; 68.993355 81.71096 108.75786 151.73012; 57.172836 67.88412 91.73201 127.68159; 50.29212 59.52913 80.281876 110.93882; 46.07204 54.571075 73.37526 100.54719; 43.26255 51.720673 70.2189 95.12051; 41.351265 49.874416 68.38473 91.6354; 37.16251 47.444855 66.986725 88.4952; 38.089397 48.888622 68.05684 87.94073;;; -125.83967 -147.3447 -216.57237 -323.02863; -163.52567 -210.22945 -335.42917 -442.67255; -229.55782 -342.8905 -538.0842 -577.07526; -683.1058 -1067.3855 -1299.7345 -950.821; 934.16895 1148.707 3010.1152 -2975.5005; 325.5495 403.44464 645.80365 1887.2352; 189.17796 235.93488 344.91916 629.7768; 135.0862 165.69792 233.03409 376.60648; 109.44648 132.76773 183.99786 279.29993; 94.29409 112.65356 154.34782 227.59517; 82.27603 97.989555 134.51387 192.06935; 73.01001 86.64378 119.43513 167.01556; 68.69997 80.33463 109.39166 149.31291; 66.99533 78.45125 105.97067 139.08208; 68.12718 80.49166 109.238846 137.73756; 69.22728 84.21783 116.094826 142.29695; 67.08692 87.32886 125.2723 147.84001; 67.32758 96.90675 142.2469 161.222;;; -259.2951 -279.6777 -326.63202 -360.9537; -471.472 -535.0621 -604.8034 -535.24677; -1653.9143 -2335.6414 -1397.019 -767.2549; 730.1557 995.84326 6908.7344 -1366.9033; 288.07632 405.99942 979.54596 -6791.475; 190.12192 262.9899 540.4154 2144.2368; 147.9887 205.2723 382.97623 934.0796; 133.55754 180.02438 311.01172 603.9347; 128.6712 169.0057 275.27994 477.76413; 128.93536 164.23177 257.62903 417.03674; 127.65534 164.7346 258.74973 397.3713; 131.24484 170.08981 272.24756 403.97034; 145.64412 188.12221 305.49527 436.5411; 178.0077 236.27779 395.02087 523.0769; 248.99443 380.80554 747.71094 819.3751; 428.35995 1146.4564 -10970.198 4090.9644; 1289.2599 -1109.5739 -620.2922 -1315.339; 1023.0993 -415.1028 -325.4063 -543.4129;;; 1451.6713 7761.8945 -1010.0048 -528.0486; 456.12823 802.1614 -7695.201 -888.1748; 310.5969 504.56396 2564.411 -1516.618; 246.69829 372.65323 1076.4971 -4314.037; 193.63074 281.23557 711.95984 6711.7637; 155.98785 221.89238 577.9321 3621.0513; 147.99144 217.30855 600.8715 3804.0623; 162.41321 260.17273 802.4034 6885.609; 201.23505 351.93594 1366.2034 -12855.497; 278.57755 556.7959 12719.309 -2031.2275; 473.6127 1927.449 -1150.6368 -813.891; 3574.0735 -802.1031 -454.87665 -448.0447; -490.26758 -305.6605 -260.40784 -290.86432; -207.92586 -176.6817 -176.27307 -210.7385; -130.76031 -120.43817 -129.98514 -163.0878; -95.17089 -90.92171 -102.36327 -132.05733; -71.24953 -71.53033 -83.89716 -111.91685; -73.09393 -64.81389 -73.82136 -99.1647;;; 203.44833 270.3365 787.91003 -2128.9038; 164.42554 238.26425 694.92236 -8728.905; 151.31969 240.58623 716.97906 55129.434; 162.9077 269.89706 789.6802 2594.3682; 171.5058 268.50955 869.35095 17490.219; 164.2632 254.52591 961.7902 -2462.5808; 186.30263 321.42038 5645.4487 -933.5447; 272.95502 843.2097 -867.9477 -548.5069; 751.4374 -983.6872 -379.94263 -358.92255; -749.9418 -319.6452 -243.4795 -253.22282; -244.87665 -182.94914 -170.17563 -186.5418; -136.81137 -118.94636 -123.08742 -141.64392; -90.78489 -85.58249 -93.00557 -112.21189; -66.90105 -66.13575 -74.372116 -93.395226; -52.699745 -53.789127 -62.75438 -81.44664; -44.226604 -45.467175 -54.835052 -73.491905; -35.573166 -38.640316 -49.09724 -68.143265; -36.295826 -37.119404 -45.82458 -64.69837;;; 121.81117 154.39653 311.4127 841.8636; 113.252426 156.74219 355.89435 1024.7904; 111.67357 174.96933 462.6135 1835.2362; 139.59892 252.15562 906.84674 3015.538; 183.91988 369.36322 4699.487 -1717.9937; 224.92825 502.8211 -2251.623 -648.65704; 347.20905 1975.4913 -571.58844 -397.13177; 2055.7566 -518.4338 -279.9165 -269.8877; -394.51328 -209.47719 -175.1244 -189.67395; -159.77281 -129.69795 -127.44041 -144.2394; -101.33393 -92.30451 -97.15705 -116.48949; -70.70371 -69.19644 -76.91261 -96.05332; -53.5283 -54.211205 -62.750793 -81.48904; -43.054028 -44.531567 -53.31606 -71.61801; -35.947 -38.19586 -47.221706 -65.49208; -31.249857 -33.71015 -43.13388 -61.783783; -25.792809 -29.593332 -40.364685 -59.483925; -26.26155 -28.990746 -39.123283 -58.023132;;; 100.21515 129.7303 245.78491 474.1179; 100.17082 141.16927 306.08173 671.063; 104.0815 166.56392 446.21805 1402.2839; 143.54887 289.7144 1754.2451 -3363.4014; 244.77469 981.90173 -1007.8702 -704.3306; 501.5498 -1580.0994 -421.90408 -371.7888; -3893.8757 -389.4933 -256.78506 -262.72586; -355.2453 -203.40007 -175.15683 -197.05885; -160.7228 -127.09232 -126.16885 -150.24142; -97.64683 -90.29196 -96.35354 -119.3745; -69.64331 -68.543755 -77.01765 -100.19924; -53.094833 -54.737038 -64.29903 -86.96981; -42.765656 -45.260742 -55.417713 -77.713234; -36.038048 -38.89829 -49.276512 -71.12113; -31.151815 -34.451313 -45.26204 -66.57887; -27.73513 -31.290773 -42.69463 -63.86906; -23.529821 -28.127655 -41.085304 -62.267292; -23.727173 -28.026144 -41.20132 -61.531307;;; 100.13194 141.2632 293.0349 668.4161; 106.896194 165.07494 413.89212 1163.1978; 118.25096 206.1979 680.9174 4707.73; 180.25053 452.89047 -4863.497 -1149.2871; 465.77463 -1655.1316 -492.14932 -469.2561; -1307.4255 -326.8231 -257.01724 -281.6656; -295.8157 -190.54509 -178.96382 -206.02968; -170.7 -138.11082 -139.8405 -168.19339; -110.834785 -102.098305 -111.039345 -142.28697; -79.27218 -78.988785 -89.954124 -121.08541; -60.815464 -63.029377 -75.56325 -105.07586; -49.19417 -52.82657 -65.90484 -94.450775; -41.66397 -45.957886 -59.745625 -88.236786; -36.476154 -41.131004 -55.546906 -83.97089; -32.722137 -37.492245 -52.77135 -80.60458; -29.957245 -34.869663 -51.108006 -78.658; -26.156288 -32.272015 -50.69973 -78.18704; -25.873945 -32.752464 -52.130787 -79.60909;;; 118.68344 191.67033 534.957 15165.693; 139.52989 254.70718 1132.9664 -1987.7849; 168.39479 359.77866 6898.5786 -1103.5162; 314.40732 2057.0405 -861.3477 -610.57184; -144142.66 -492.23346 -355.9058 -380.34677; -301.8817 -212.33981 -212.78148 -257.0839; -169.1746 -147.62198 -158.79659 -198.97926; -124.57534 -118.66469 -133.0882 -169.38872; -96.80212 -97.97346 -114.140045 -154.20995; -77.234055 -81.2607 -99.78524 -142.29515; -63.47076 -69.027435 -88.76905 -131.55646; -54.063747 -60.594364 -81.598625 -123.92856; -48.32109 -55.61483 -78.140976 -121.97265; -44.29666 -52.003788 -76.43512 -122.98456; -41.750145 -49.34923 -75.39379 -124.81549; -39.361473 -47.46824 -75.52359 -127.22622; -35.489883 -45.67407 -78.21234 -133.25513; -34.453476 -47.12659 -83.407104 -143.6432;;; 174.50882 335.51764 2213.9375 -1145.8553; 248.70007 644.2452 -2114.2068 -683.55524; 377.7698 2212.9873 -912.5201 -568.6363; 2472.732 -752.9985 -471.52 -446.9474; -459.15067 -317.58743 -308.98996 -353.08; -193.75638 -179.71814 -209.59587 -291.05576; -137.52292 -141.43332 -172.30135 -243.73813; -113.76243 -121.783134 -153.44884 -217.4387; -99.69234 -108.89928 -140.74928 -207.4757; -88.57174 -98.52844 -132.69336 -205.36346; -78.693954 -89.96354 -127.7628 -209.9988; -71.39902 -83.99175 -126.79114 -221.42899; -68.36383 -82.476944 -131.83932 -243.13426; -67.676674 -83.5252 -140.3731 -279.4791; -68.51296 -85.355354 -151.68907 -335.13986; -68.47549 -88.15617 -167.10161 -416.67722; -65.13018 -90.65989 -195.09846 -575.1497; -62.127308 -99.01888 -237.93889 -907.71716;;; 409.57187 1357.2465 -2323.1743 -1214.7596; 1971.2769 -1460.7427 -794.52185 -738.1947; -1148.3624 -559.28326 -529.16626 -621.41626; -423.74606 -350.66138 -400.72623 -462.46542; -242.49657 -249.10559 -319.96255 -459.5698; -163.6995 -183.39761 -247.52751 -417.78705; -135.84515 -158.80933 -231.5472 -418.10577; -123.19108 -147.31786 -225.1688 -406.08102; -119.94776 -144.12984 -223.7914 -413.83682; -122.90221 -147.95235 -235.9025 -458.68683; -123.525024 -152.37193 -265.34256 -606.0148; -125.65754 -160.82152 -315.7783 -1091.6467; -139.26076 -186.84013 -429.99902 -6697.707; -172.45845 -244.2495 -790.20123 1493.2803; -229.97635 -373.15182 -11912.829 651.5018; -339.8115 -733.36053 964.03766 426.37073; -548.09894 29375.387 451.7095 323.3437; -422.90762 850.8468 312.72934 271.73688;;; -991.2652 -680.85767 -1002.41046 -9328.137; -337.75784 -352.5573 -564.9889 -2196.2288; -237.0602 -269.23737 -444.2236 -1206.3169; -205.71881 -241.81311 -407.45245 -1005.6824; -180.60704 -227.54768 -394.40067 -876.1509; -159.6716 -217.04478 -402.1552 -930.3045; -153.40642 -212.00978 -438.0427 -1410.2545; -156.00146 -216.58575 -494.39252 -2700.1567; -177.71559 -253.07385 -637.43414 -11715.566; -241.0322 -361.28857 -1262.1504 2540.8699; -360.97943 -638.38434 5540.6826 882.0322; -718.8617 -3249.7847 798.0216 509.32156; 1406.8733 705.15546 407.3008 353.2205; 299.52322 279.7111 255.73038 264.08362; 167.46863 169.28673 180.37164 209.84286; 117.24569 123.792366 142.00967 178.10602; 86.385605 96.27054 119.2282 158.67336; 90.2851 87.04229 106.02306 146.8688;;; -223.80905 -262.48563 -556.521 2953.7007; -164.72069 -206.39977 -439.7438 7138.8315; -140.6441 -187.51646 -409.60886 -5202.51; -148.23744 -200.47252 -459.89783 10562.191; -161.40656 -235.3465 -602.9139 -32300.166; -173.12814 -285.14212 -1100.4869 3774.2769; -196.3709 -340.41962 -2463.6416 1403.0193; -242.44023 -450.73154 6109.5366 818.69196; -421.16495 -1294.1218 929.77875 581.95917; 7250.5557 787.93665 432.66394 408.94278; 378.55804 311.61566 276.55283 307.25894; 193.01012 190.72412 200.08838 246.7556; 117.243576 131.3412 154.9275 206.44124; 82.17086 95.956604 122.882675 172.34648; 63.65258 74.955795 100.40662 147.12918; 52.071377 62.12621 85.81 130.27202; 42.194286 52.70697 76.43728 120.04157; 43.075584 50.098907 71.03788 112.44003]

since these are cell-body center color values, i convert them to vertex centered values using

vertex function
function to_vertex_centered(rho::Array{Float32,3})
	Nx, Ny, Nz = size(Bt_block)
	Bt_vertex = zeros(Float32, Nx+1, Ny+1, Nz+1)
	for i in 1:Nx, j in 1:Ny, k in 1:Nz
	    Bt_vertex[i, j, k] += rho[i, j, k]
	    Bt_vertex[i+1, j, k] += rho[i, j, k]
	    Bt_vertex[i, j+1, k] += rho[i, j, k]
	    Bt_vertex[i, j, k+1] += rho[i, j, k]
	    Bt_vertex[i+1, j+1, k] += rho[i, j, k]
	    Bt_vertex[i+1, j, k+1] += rho[i, j, k]
	    Bt_vertex[i, j+1, k+1] += rho[i, j, k]
	    Bt_vertex[i+1, j+1, k+1] += rho[i, j, k]
	end
	Bt_vertex ./= 8
end
using Meshes, CoordRefSystems ,GLMakie, LinearAlgebra, Unitful, GeometryBasics, Colors

r =  Float32[1.6, 1.754088, 1.9230156, 2.1082115, 2.311243, 2.5338273, 2.7778475, 3.0453684, 3.3386526, 3.6601818, 4.012676, 4.3991165, 4.8227735, 5.287231, 5.7964177, 6.354642, 6.9666257, 7.637547, 8.373081]
θ =  Float32[0.0, 0.09817477, 0.19634955, 0.2945243, 0.3926991]
Ď• =  Float32[0.0, 0.3926991, 0.7853982, 1.1780972, 1.5707964, 1.9634954, 2.3561945, 2.7488935, 3.1415927, 3.5342917, 3.9269907, 4.3196898, 4.712389, 5.105088, 5.497787, 5.8904862, 6.2831855]

g = RectilinearGrid{𝔼,typeof(Spherical(0,0,0))}(r, θ, ϕ)
vc = coords.(vertices(g))
cvc = convert.(Cartesian, vc)
rect_positions = [Point3f(Float32.(ustrip.((c.x, c.y, c.z)))...) for c in cvc]