April 2013
Real time visualization of 3D vector field with CUDA
3 Visualization using glyphs
3.1 Line glyphs for VF visualization
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | __global__ void glyphLinesKernel(float x, uint2 glyphsCount, float2 worldSize, float3* outVertices, float3* outColors) { uint id = __umul24(blockIdx.x, blockDim.x) + threadIdx.x; uint totalCount = __umul24(glyphsCount.x, glyphsCount.y); if (id >= totalCount) { return; } float y = (id % glyphsCount.x) * (worldSize.x / glyphsCount.x); float z = (id / glyphsCount.x) * (worldSize.y / glyphsCount.y); float4 vector = tex3D(vectorFieldTex, x, y, z); id *= 2; outVertices[id] = make_float3(x, y, z); outVertices[id + 1] = make_float3(x, y, z) + normalize(make_float3(vector.x, vector.y, vector.z)) * vector.w; float4 color = tex1D(vectorMangitudeCtfTex, vector.w); outColors[id] = make_float3(color.x, color.y, color.z); outColors[id + 1] = make_float3(color.x, color.y, color.z); } |
Figure 1: Vector field visualization using line glyphs
It is possible to set number of glyph lines in plane to very high numbers and create solid wall as shown in Figure 2. This serves as relatively nice visualization of vector magnitudes.
Figure 2: Magnitude visualization using high density of line glyphs.
3.2 Arrow glyphs for VF visualization
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | __global__ void glyphArrowsKernel(float x, uint2 glyphsCount, float2 worldSize, float3* outVertices, uint3* outFaces, float3* outVertexNormals, float3* outVertexColors) { uint id = __umul24(blockIdx.x, blockDim.x) + threadIdx.x; // ... same part as in lines kernel ... float4 vector = tex3D(vectorFieldTex, x, y, z); float3 forward = normalize(make_float3(vector.x, vector.y, vector.z)); float3 xAxis = normalize(findPerpendicular(forward)); float3 yAxis = normalize(cross(forward, xAxis)); uint faceId = id * 6; uint vertId = id * 9; outFaces[faceId] = make_uint3(vertId, vertId + 1, vertId + 2); outFaces[faceId + 1] = make_uint3(vertId, vertId + 2, vertId + 3); outFaces[faceId + 2] = make_uint3(vertId, vertId + 3, vertId + 4); outFaces[faceId + 3] = make_uint3(vertId, vertId + 4, vertId + 1); outFaces[faceId + 4] = make_uint3(vertId + 5, vertId + 6, vertId + 7); outFaces[faceId + 5] = make_uint3(vertId + 5, vertId + 7, vertId + 8); id *= 9; outVertexNormals[id] = forward; outVertexNormals[id + 1] = xAxis; outVertexNormals[id + 2] = yAxis; outVertexNormals[id + 3] = -xAxis; outVertexNormals[id + 4] = -yAxis; forward *= -1; outVertexNormals[id + 5] = forward; outVertexNormals[id + 6] = forward; outVertexNormals[id + 7] = forward; outVertexNormals[id + 8] = forward; forward *= vector.w; xAxis *= 0.1; yAxis *= 0.1; outVertices[id] = position - forward; // Forward was multiplied by -1. outVertices[id + 1] = position + xAxis; outVertices[id + 2] = position + yAxis; outVertices[id + 3] = position - xAxis; outVertices[id + 4] = position - yAxis; outVertices[id + 5] = position + xAxis; outVertices[id + 6] = position + yAxis; outVertices[id + 7] = position - xAxis; outVertices[id + 8] = position - yAxis; float4 color = tex1D(vectorMangitudeCtfTex, vector.w); float3 color3 = make_float3(color.x, color.y, color.z); for (int i = 0; i < 9; ++i) { outVertexColors[id + i] = color3; } } |