gpt4 book ai didi

opengl - 使用光线转换算法进行体积渲染(使用 glsl)

转载 作者:行者123 更新时间:2023-12-03 13:34:23 36 4
gpt4 key购买 nike

我正在使用光线转换算法学习体积渲染。我在 here 中找到了一个很好的演示和教程.但问题是我有一个 ATI 显卡而不是 nVidia,这使我无法在演示中使用 cg 着色器,所以我想将 cg 着色器更改为 glsl 着色器。看过OpenGL的红皮书(7版),但是对glsl和cg不熟悉。
有人可以帮我将演示中的 cg 着色器更改为 glsl 吗?或者是否有任何 Material 可以使用光线转换(当然在 glsl 中)进行最简单的体积渲染演示。
here是demo的cg shader。它可以在我 friend 的 nVidia 显卡上运行。最让我困惑的是,我不知道如何将 cg 的入口部分翻译成 glsl,例如:

struct vertex_fragment
{
float4 Position : POSITION; // For the rasterizer
float4 TexCoord : TEXCOORD0;
float4 Color : TEXCOORD1;
float4 Pos : TEXCOORD2;
};

更重要的是,我可以编写一个程序将具有 2 个纹理单元的 2 个纹理对象绑定(bind)到着色器,前提是我在绘制屏幕时分配了两个 texcoord,例如
glMultiTexCoord2f(GL_TEXTURE0, 1.0, 0.0); glMultiTexCoord2f(GL_TEXTURE1, 1.0, 0.0);
在演示中,程序将绑定(bind)到两个纹理(一个 2D 用于 backface_buffer 一个 3D 用于 volume texture ),但只有一个纹理单元,如 glMultiTexCoord3f(GL_TEXTURE1, x, y, z);我认为 GL_TEXTURE1 unit 用于体积纹理,但哪个(纹理单元)用于 backface_buffer ?据我所知,为了在着色器中绑定(bind)纹理 obj,我必须获得一个纹理单元来绑定(bind),例如:
glLinkProgram(p);   
texloc = glGetUniformLocation(p, "tex");
volume_texloc = glGetUniformLocation(p, "volume_tex");
stepsizeloc = glGetUniformLocation(p, "stepsize");
glUseProgram(p);
glUniform1i(texloc, 0);
glUniform1i(volume_texloc, 1);
glUniform1f(stepsizeloc, stepsize);
//When rendering an object with this program.
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, backface_buffer);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_3D, volume_texture);

该程序编译良好并且链接正常。但我只得到了所有三个位置(texloc、volume_texloc 和stepsizeloc)中的-1。我知道它可能会被优化。
任何人都可以帮我将 cg 着色器转换为 glsl 着色器吗?

编辑:如果您对使用 glsl 的现代 OpenGL API 实现(C++ 源代码)感兴趣: Volume_Rendering_Using_GLSL

最佳答案

问题解决了。 glsl versiondemo :

顶点着色器

void main()
{
gl_Position = gl_ModelViewProjectionMatrix*gl_Vertex;
//gl_FrontColor = gl_Color;
gl_TexCoord[2] = gl_Position;
gl_TexCoord[0] = gl_MultiTexCoord1;
gl_TexCoord[1] = gl_Color;
}

片段着色器
uniform sampler2D tex;
uniform sampler3D volume_tex;
uniform float stepsize;

void main()
{
vec2 texc = ((gl_TexCoord[2].xy/gl_TexCoord[2].w) + 1) / 2;
vec4 start = gl_TexCoord[0];
vec4 back_position = texture2D(tex, texc);
vec3 dir = vec3(0.0);
dir.x = back_position.x - start.x;
dir.y = back_position.y - start.y;
dir.z = back_position.z - start.z;
float len = length(dir.xyz); // the length from front to back is calculated and used to terminate the ray
vec3 norm_dir = normalize(dir);
float delta = stepsize;
vec3 delta_dir = norm_dir * delta;
float delta_dir_len = length(delta_dir);
vec3 vect = start.xyz;
vec4 col_acc = vec4(0,0,0,0); // The dest color
float alpha_acc = 0.0; // The dest alpha for blending
float length_acc = 0.0;
vec4 color_sample; // The src color
float alpha_sample; // The src alpha

for(int i = 0; i < 450; i++)
{
color_sample = texture3D(volume_tex,vect);
// why multiply the stepsize?
alpha_sample = color_sample.a*stepsize;
// why multply 3?
col_acc += (1.0 - alpha_acc) * color_sample * alpha_sample*3 ;
alpha_acc += alpha_sample;
vect += delta_dir;
length_acc += delta_dir_len;
if(length_acc >= len || alpha_acc > 1.0)
break; // terminate if opacity > 1 or the ray is outside the volume
}

gl_FragColor = col_acc;
}

如果你看过原版 shader cg 的 cg 和 glsl 之间只有一点区别。将demo翻译成glsl版本最困难的部分是opengl中的cg函数,例如:
param = cgGetNamedParameter(program, par); 
cgGLSetTextureParameter(param, tex);
cgGLEnableTextureParameter(param);

封装了纹理单元和多纹理激活(使用 glActiveTexture )和停用的过程,这在这个演示中非常重要,因为它使用了固定管道以及可编程管道。这是函数 void raycasting_pass() 中更改的关键段Peter Triers GPU 光线转换教程中演示的 main.cpp:

函数 raycasting_pass
void raycasting_pass()
{
// specify which texture to bind
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
GL_TEXTURE_2D, final_image, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glUseProgram(p);
glUniform1f(stepsizeIndex, stepsize);
glActiveTexture(GL_TEXTURE1);
glEnable(GL_TEXTURE_3D);
glBindTexture(GL_TEXTURE_3D, volume_texture);
glUniform1i(volume_tex, 1);
glActiveTexture(GL_TEXTURE0);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, backface_buffer);
glUniform1i(tex, 0);

glUseProgram(p);
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
drawQuads(1.0,1.0, 1.0); // Draw a cube
glDisable(GL_CULL_FACE);
glUseProgram(0);
// recover to use only one texture unit as for the fixed pipeline
glActiveTexture(GL_TEXTURE1);
glDisable(GL_TEXTURE_3D);
glActiveTexture(GL_TEXTURE0);
}

就是这样。

关于opengl - 使用光线转换算法进行体积渲染(使用 glsl),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9482572/

36 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com