标记
放假上网一直不方便,回来一看,发现被图形学团队吸收了,兴奋中。
看来要积极更新了!
posted @ 2009-02-28 00:59 Alex226 阅读(28) 评论(0) 编辑
Just for fun
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)相等,则在光栅化阶段通过图形流水线的三线性插值,包围盒表面上每一点的颜色和它的空间坐标都相等,那么后表面纹理中保存的绘制结果是包围盒后表面的坐标信息,也就是投射光线的终点。
posted @ 2008-12-03 22:21 Alex226 阅读(252) 评论(0) 编辑
最近打算写一个volume rendering中的focus & context算法,准备用GPU的raycasting来实现,对以前写的程序一直不太满意,View.Cpp奇大无比,里面的类全部糅到了一起,所以打算重新写一个。为了简洁起见,窗口用glut来生成。关于raycasting的具体算法在后面的文章中再具体细说,本文只说文件路径问题。
通过vs2005新建一个win23 console型,名为GPU_RayCasting的工程时,GPU_RayCasting.cpp文件和众多工程文件都在根目录下。为了方便管理,在工程中分别建立了build、src、data等三个文件夹,而src文件夹又由core、app、shader、math等四个文件夹组成,来存放不同的文件。把众多工程文件放入build文件夹中,GPU_RayCasting.cpp放入'\src\app'文件夹中,并在'\src\math'文件夹中放入Vector3.h文件。
在GPU_RayCasting.cpp中加载头文件。如何选择头文件的路径呢?绝对路径比较简单,但当工程文件改变位置后,绝对路径就不能用了,为增加程序的可移植性,选用相对路径较好。
用#include 加载头文件时,"./"表示当前目录,"../"表示当前目录的上一级目录。注意!这个当前目录不是工程所在的目录,而是该文件所在的目录。在include中,'/'与'\'的功能貌似一样,#include "../math/Vector3.h"与#include "..\math\Vector3.h"也貌似等价。
当使用cgCreateProgramFromFile(CGcontext ctx, CGenum program_type, const char *program_file, CGprofile profile, const char *entry, const char **args)函数创建Cg程序时,const char *program_file中存放是Cg程序的路径,此时同样应选用相对路径来加载Cg程序。同样,"./"表示当前目录,"../"表示当前目录的上一级目录。注意,这个当前目录不是该文件所在的目录,而是解决方案文件sln所在的目录。
在字符串中,'\'是转义字符,要表示'\',在字符串中应写为'\\',因此"../src/shader/raycasting_shader.cg"与 "..\\src\\shader\\raycasting_shader.cg"等价。
posted @ 2008-12-03 19:46 Alex226 阅读(1251) 评论(0) 编辑