基于GPU的三维气象数据显示

    这篇文章是关于气象局的一个项目,写出来旨在总结一下自己两个月的劳动成果,同时也写写东西,毕竟很久没写东西了,表达能力也有退化之嫌。不多废话,直奔主题。

    基于GPU的三维气象数据显示,这个题目已经定义了这个项目运行的硬件要求以及显示的主要内容。先来说说气象局提供的一些数据格式,其实说来也很简单,就是500*400*20的网格数据,每个网格数据的格式是unsigned byte,用计算机图形学的概念来说,就是一个500*400*20的三维纹理。相信每个接触过图形编程的人都会了解二维纹理,但对三维纹理不一定有足够的了解。就气象局的这个数据来说,就是一个由20张500*400的二维纹理叠加起来的三维纹理。

                                   

   上图是一个由4层二维纹理组成的三维纹理。介绍完三维纹理的概念,接下来介绍一下三维纹理的显示的一些技术,要把一个三维纹理完整的现实出来,主要有两种体渲染(Volume Rendering)技术,一种是基于切片(slice)的显示方式,另一种是基于光线跟踪的显示方式。本文使用后者,基本原理:由视点(观察者位置)向要计算颜色的当前像素发出一条光线(向量),如果该光线与三维纹理有交点,证明光线进入三维纹理,就从该交点开始,等距获取三维纹理与光线相交部分的值,然后按照某种方式把这些值叠加起来,作为当前像素的颜色值。

                                         

   上图简单显示了光线跟踪体渲染的原理,圆心处是视点,图中矩形就是三维纹理,但严格来说三维纹理应该是个立方体,上图并没有体现出来。

   讲完必要的技术原理,下面来说说本项目具体的渲染实现。运用的图形API为OpenGL,在加上Cg(C for Graphic)语言,当然我觉得如果懂GLSL更好,毕竟GLSL与硬件无关,而Cg是Nvidia的,在Nvidia系显卡与非Nvidia显卡运行的效率的差距是摆在那儿的。

   首先是三位纹理的生成,

  glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // 启用三线性过滤,以得到更加清晰的图像
  glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

  glTexImage3DEXT(GL_TEXTURE_3D, 0, GL_RGBA, width, height, depth, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);

注意第三个函数的第三个和第八个参数均为GL_RGBA,这是因为我们的三维纹理的每个网格点都由四个unsigned byte组成,对应OpenGL里面的r/g/b/a,其中a保存了该网格点的气象数据,r/g/b保存了我们计算出来的梯度值,梯度值的作用主要是用来计算光照值,在这里就不详细讨论了。上面三个函数的前两个是控制三维纹理放大缩小时运用的插值和取样算法,算法由显卡驱动所提供。这里运用了三线性插值算法。

   接下来就是确定光线(向量),首先我们来说说代理立方体(proxy volume),以我的理解,我们在世界空间建立一个立方体来代理我们的三维纹理,每次绘制的时候,首先绘制立方体的背面,将其保存在帧缓冲对象(FBO)之中,保存成纹理,如下图右示。

                      

然后在帧缓冲直接绘制立方体的正面,然后把刚保存的帧缓冲纹理传到pixel shader之中, 接下来的工作都是在pixel shader里面完成。注意这里用了一些小技巧,我们确定光线跟立方体的交点是通过绘制立方体正面时赋予的纹理坐标来确定的,纹理坐标的范围是0-1之间,而光线的终点是根据画立方体的背面是的颜色值来确定的,如上图所示,颜色的范围也是0-1。有了起点和终点,光线的向量随之确定。光线每次取样的距离就可以根据用户的需要而定了,当然,取样距离越小,效率就越低。程序实际效果如下图所示,

   

  当然我们可以在pixel shader里面做随心所欲的东西,shader除了不能调试之外,几乎是万能的,哈哈!上图已经加了光照。由于本人表达能力有限,时间更有限,很多细节地方都没有涉及,以后有时间再补充完整。牛人尽管发表意见,谢不吝赐教。

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值