raycasting算法在众多体绘制算法中以采样精度高,绘制图像细腻著称,但计算量的缺点阻碍了它的广泛应用。
GPU的raycasting算法被提出后,达到了实时交互的绘制速度。近年来,该技术逐渐成熟,可分为两类:单通路和多通路。多通路最早被提出,由于GPU的可编程性能较差,需绘制体数据包围盒多次来计算光线参数,而随着GPU的可编程性能提高,单通路算法被提出,只需绘制一次体数据包围盒就可获得投射光线参数,但顶点着色程序较为复杂。最近利用离屏渲染获取投射光线参数的方法被提出,该方法绘制包围盒两次来获取投射光线参数,避免的复杂的顶点着色程序。下面对该算法进行详细的叙述。
主要由以下几个部分组成:
(1). 3D纹理的生成。保存原始3D体数据场为3D纹理。
(2). 投射光线起始点、终点的确定。利用Framebuffer object执行离线渲染来确定投射光线参数。Framebuffer object于2005年提出,主要用于离屏渲染,它在显存中定义一块存储区域作为帧缓存使用,和真正的帧缓存一样,同样包括颜色缓存、深度缓存和模板缓存等,不同的是将绘制的结果保存在与Framebuffer object绑定的纹理对象中,而不是直接显示在屏幕上。确定投射光线起点、终点等参数的步骤如下:
step 1. 定义一个Framebuffer object和两个2D纹理对象,2D纹理对象分别被命名为前表面纹理和后表面纹理,将分别保存光线的起始点和终点坐标。
glGenFramebuffersEXT(1, &framebuffer); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT,framebuffer); glGenTextures(1, &backface_buffer); glBindTexture(GL_TEXTURE_2D, backface_buffer); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); glTexImage2D(GL_TEXTURE_2D, 0,GL_RGBA16F_ARB, WINDOW_SIZE, WINDOW_SIZE, 0, GL_RGBA, GL_FLOAT, NULL); glGenTextures(1, &final_image); glBindTexture(GL_TEXTURE_2D, final_image); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); glTexImage2D(GL_TEXTURE_2D, 0,GL_RGBA16F_ARB, WINDOW_SIZE, WINDOW_SIZE, 0, GL_RGBA, GL_FLOAT, NULL);
step 2. 绑定Framebuffer object和后表面纹理,并启用Framebuffer object。根据体数据的大小生成一个包围盒,在Framebuffer object中绘制包围盒的表面,并剔除包围盒的前表面,此时,在Framebuffer object中的绘制结果为体数据包围盒的后表面,保存在后表面纹理中。绘制时,令每个面四个顶点的颜色值(r, g, b)与顶点的坐标值(x, y, z)相等,则在光栅化阶段通过图形流水线的三线性插值,包围盒表面上每一点的颜色和它的空间坐标都相等,那么后表面纹理中保存的绘制结果是包围盒后表面的坐标信息,也就是投射光线的终点。
step 3. 绑定Framebuffer对象和前表面纹理,在Framebuffer对象中绘制包围盒的表面,把每个面的顶点坐标(x, y, z) 作为顶点的颜色(r, g, b),并剔除包围盒的后表面,通过绘制,前表面纹理中保存的绘制结果是包围盒前表面的坐标信息,也就是投射光线的起始点。光线方向在光线积分时可通过光线起始点和终点来计算。如下图。

本文转自:博客园 - Alex的虚拟世界,转载此文目的在于传递更多信息,版权归原作者所有。