230 likes | 329 Vues
Learn about volume visualization using various models and rendering techniques, such as ray casting and cube representation. Discover how to apply transfer functions, shading, and illumination in rendering simulations. Explore the intersection between CPU and GPU programming for realistic 3D visuals.
E N D
Térfogatvizualizáció Szirmay-Kalos László
Térfogati modellek hőmérséklet sűrűség légnyomás potenciál anyagfeszültség ... v(x,y,z) v(x,y,z) tárolás: 3D tömb
Térfogati modell megjelenítése • Kocka megjelenítése ??? • Megjelenítés átlátszó anyagként (belsejébe belelátunk) • Adott szintfelület kiemelése (külsôt lehámozzuk)
Átlátszó anyagok L(s + ds) L(s) dL(s)/ds = - kt · L(s) + ka · Le + f(‘,) Li(‘) d ‘ L(s + s) L(s) L(s + s) = L(s) - kt s · L(s) + Li(s) s (s) C(s)
Számítás fénysugárkövetéssel L(s + s) = (1- (s)) · L(s) + C(s) L(s) L = 0 for(s = 0; s < T; s += s) { L = (1- (s)) · L + C(s) }
Számítás láthatóság sugárkövetéssel L*(s) (s) L*(s-s)=L*(s)+(1- (s)) · C(s) (s-s)=((s)) · ((s)) L* = 0 for( s = T; s >0 ; s -= s ) { L += (1- ) · C(s) (1- ) · ((s)) if (break }
Térfogat vetítés L(s) L(s + s) = (1- (s)) · L(s) + C(s)
Voxel szín és opacitás: Transfer functions • Röntgen: • opacitás = v(x,y,z) • C(0) = 1, egyébként 0 • Klasszikus árnyalási modellek • opacitás: v osztályozása • C = árnyalási modell (diffúz + Phong) • normál = grad v • opacitás *= | grad v |
Marching cubes v(x,y,z) > szint v(x,y,z) < szint
Masírozó kockák Szintérték = 110 Szintérték = 60
Isosurface ray casting normal = grad v v(x,y,z) > isovalue
GPU ray-casting right up lookat eye p q entry p = lookat + right + up , are in [-1,1] exit Unit cube with 3D texture
Isosurface ray-casting Full screen quad For each pixel Find pixel center p raydir = normalize(p – eye); Find exit and entry for(t = entry; t < exit; t+=dt) { q = eye + raydir * t; if (volume[q] > isovalue) break; } normal vector estimation; illumination } Interpolation from the corners Render a cube and store the image in a texture central differences
GPU Isosurface ray-casting volume, entry, exit texture ids eye, isolevel, material/light properties Ray casting Pixel shader CPU program Vertex shader Rasterization Interpolation Vertices of the window quad hpos=fullscreen textcoords Interpolated textcoords volume entrytex exittex
CPU program - OpenGL display void Display( ) { cgGLSetParameter3f(eye, 10, 20,30); cgGLSetParameter3f(lookat, 3, 5, 6); cgGLSetParameter3f(right, Right.x, Right.y, Right.z); cgGLSetParameter3f(up, Up.x, Up.y, Up.z); // PASS: non uniform parameters glBegin( GL_QUADS ); Vector p = lookat - Right + Up; glTexCoord2f(0, 0); glVertex3f(p.x, p.y, p.z) p = lookat - Right - Up; glTexCoord2f(0, 1); glVertex3f(p.x, p.y, p.z) p = lookat + Right - Up; glTexCoord2f(1, 1); glVertex3f(p.x, p.y, p.z) p = lookat + Right + Up; glTexCoord2f(1, 0); glVertex3f(p.x, p.y, p.z) glEnd(); }
Ray casting: vertexshader voidVertexShader( in float3position : POSITION, in float2uv : TEXCOORD0, out float4 hPosition : POSITION, out float2 ouv : TEXCOORD0, out float3p : TEXCOORD1 ) { hPosition = float4(uv.x * 2 – 1,1 – uv.y * 2, 0, 1); ouv = uv; p = position; }
Ray casting: fragment shader voidFragmentShader( in float3 uv : TEXCOORD0, in float3p : TEXCOORD1, uniform float3 eye, uniform sampler2D entrytex, exittex, uniform sampler3D volume, uniform float isolevel, uniform float3 lightdir, lightint, kd ) : COLOR { float entry = tex2d(entrytex, uv); float exit = tex2d(exittex, uv); float raydir = normalize(p – eye); float dt = (exit – entry) / STEPS; bool found = false; float3 q; for(t= entry; t < exit; t += dt) { if ( !found ) { q = eye + raydir * t; if (tex3D(volume, q).r > isolevel) found = true; } }
Ray castingfragment shader cont’d float3 color = float3(0, 0, 0); // background color if ( found ) { float3 normal; normal.x = tex3d(volume, q + float3(1/RES,0,0)) – tex3d(volume, q - float3(1/RES,0,0)); normal.y = tex3d(volume, q + float3(0,1/RES,0)) – tex3d(volume, q - float3(0,1/RES,0)); normal.z = tex3d(volume, q + float3(0,0,1/RES)) – tex3d(volume, q - float3(0,0,1/RES)); normal = normalize( normal ); color = lightint * saturate(dot(lightdir, normal)); } return float4(color, 1); }