Image Based Flow Visualization(IBFV)

Image Based Flow Visualization

 

IBFV(Image Based Flow Visualization)是利用噪点图(noise image)来模拟向量场运动的一种可视化方法。为了了解IBFV,先来看看它的原理。如下图

Image Based Flow Visualization(IBFV)_第1张图片

 

 

 

从上图中可以看到,在一个2D向量场(vector field)中有很多样点(sampling),这些样点都在网格(grid)上。每个样点受到向量场的影响,在Δt时刻后,产生速度和位移。由于向量场的影响,网格就要发生变形,如上图中的(warped grid)。然后,我们再用噪点图作为网格的texture,和flow texture进行混合(blending)。上图中map textureinject nosieflow texture是个循环的过程,这样就能产生像流动一样的效果。要注意的是,这里不能只使用一张噪点图,因为我们想到得到动画的效果。所以我们可以预先用代码随机的生成很多张。

void init(float alpha) { glEnable(GL_TEXTURE_2D); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glGenTextures(NOISE+1, tex); int phase[NSIZE][NSIZE]; float noise[NSIZE][NSIZE][2]; for(int i=0; i<NSIZE;i++) for(int j=0; j<NSIZE;j++) phase[i][j] = rand() % 256; for(int k=0;k<NOISE;k++) { int t = k*256/NOISE; for(int i=0;i<NSIZE;i++) for(int j=0;j<NSIZE;j++) { noise[i][j][0] = f((t+phase[i][j]) % 256); noise[i][j][1] = alpha; } glBindTexture(GL_TEXTURE_2D, tex[k]); glTexImage2D(GL_TEXTURE_2D, 0 , GL_LUMINANCE_ALPHA, NSIZE, NSIZE, 0, GL_LUMINANCE_ALPHA, GL_FLOAT, noise); } }

 

上面的代码随机生成噪点图。有了噪点图我们就可以在进行对网格贴图的时候,顺序的取出噪点图。下面来看看如何计算向量场对网格的影响。假设向量场中一点p的位置为p(x,y),那么在 Δt时刻后,p’的位置为:

 

 

这里假设在很短的Δt时刻内,p做匀速直线运动。这样就可以得到2D向量场中每个样点受向量场影响在Δt时刻后的位置了。利用这个位置坐标作为噪点图的贴图坐标,然后和inject noise进行混合。然后重复这个步骤,就可以得到连续的动画效果,如下图。

 

 

Image Based Flow Visualization(IBFV)_第2张图片

 

 

如果我们在inject noise阶段,把inject noise用color map进行贴图,那么我们可以得到彩色的流动画。比如,我们用红色代表速度快的部分,蓝色代表速度慢的部分,如下图。

 

Image Based Flow Visualization(IBFV)_第3张图片

 

 

下面列出主要的pseudo代码

const int ISIZE = 512; //image size const int NSIZE = 64; //noise texture size const int NOISE = 32; //how many noise frames const float NSPOT = 4; //size of nosise spots const float T = ISIZE / (NSPOT*NSIZE); GLuint tex[NOISE+1]; int frame = 0; //frame counter float f(int t) { return (t>127 ? 1: 0); } void advect() { for(int i = 0; i<N; i++) { glBegin(GL_POLYGON); for(int j = 0; j<n(i); j++) { glTexCoord2f(xij, yij); glVertex2f(xij+v(xij)*t , yij+v(yij)*t); } glEnd(); } } void inject() { glEnable(GL_BLEND); glBindTexture(tex[frame % NOISE]); glBegin(GL_QUADS); glTexCoord2f(0,0); glVertex2f(0,0); glTexCoord2f(T,0); glVertex2f(1,0); glTexCoord2f(T,T); glVertex2f(1,1); glTexCoord2f(0,T); glVertex2f(0,1); glEnd(); glDisable(GL_BLEND); } void init(float alpha) { glViewport(0,0,ISIZE,ISIZE); glMatrixMode(GL_PROJECTION); glTranslatef(-1,-1,0); glScalef(2,2,1); glEnable(GL_TEXTURE_2D); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glGenTextures(NOISE+1, tex); int phase[NSIZE][NSIZE]; float noise[NSIZE][NSIZE][2]; for(int i=0; i<NSIZE;i++) for(int j=0; j<NSIZE;j++) phase[i][j] = rand() % 256; for(int k=0;k<NOISE;k++) { int t = k*256/NOISE; for(int i=0;i<NSIZE;i++) for(int j=0;j<NSIZE;j++) { noise[i][j][0] = f((t+phase[i][j]) % 256); noise[i][j][1] = alpha; } glBindTexture(GL_TEXTURE_2D, tex[k]); glTexImage2D(GL_TEXTURE_2D, 0 , GL_LUMINANCE_ALPHA, NSIZE, NSIZE, 0, GL_LUMINANCE_ALPHA, GL_FLOAT, noise); } } void run() { init(0.10); for(;;frame++) { advect(); inject(); glBindTexture(GL_TEXTURE_2D, tex[NOISE]); glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, SIZE, SIZE, 0) } }

 

*原创文章,转载请注明出处*

你可能感兴趣的:(Image Based Flow Visualization(IBFV))