2012-02-28 18 views
17

レイキャスティングアルゴリズムを使用してボリュームレンダリングを学習しています。私は良いデモと修道院を発見したhere。問題は、デモでcgシェーダを使用できないようにするnVidiaの代わりにATIグラフィックカードを使用しているため、CGシェーダをglslシェーダに変更したいということです。私はOpenGLの赤い本(7版)を見てきましたが、glslとcgに精通していません。 誰でも私がデモのCGシェーダをglslに変更するのを助けることができますか?レイキャスティングを使ったボリュームレンダリングの最も簡単なデモの資料があります(もちろんglslで)。 hereは、デモのcgシェーダです。それは私の友人のnVidiaグラフィックカードで動作することができます。レイキャスティングアルゴリズムでボリュームレンダリング(glslを使用)

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

より何、私は2テクスチャユニットとプログラムのバインド2テクスチャオブジェクトを書くことができます:どのようなほとんどは私を混乱することは、私は例えば、GLSLにCGのエントリー一部を翻訳する方法がわからないということですシェーダは、画面を描画する際にデモでは、プログラムは、ために2つのテクスチャ(1つの2Dに結合する

glMultiTexCoord2f(GL_TEXTURE0, 1.0, 0.0);

glMultiTexCoord2f(GL_TEXTURE1, 1.0, 0.0);

Iは、例えば、2 TEXCOORDを割り当てることを提供しました私はGL_TEXTURE1ユニットはボリュームテクスチャ用ですが、どのテクスチャユニットがbackface_buffer用であると思いますか?volume textureの場合は3210 1 3Dですが、glMultiTexCoord3f(GL_TEXTURE1, x, y, z);のようなテクスチャユニットは1つだけです。私の知る限り、シェーダでテクスチャOBJをバインドするために知っているように、私は、例えばバインドするテクスチャユニットを取得する必要があります。

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); 

プログラムは罰金コンパイルし、[OK]をリンクされています。 3つの場所(texloc、volume_texloc、stepsizeloc)のうち-1つしかありません。私はそれが最適化されるかもしれないことを知っている。 誰でも私がcgシェーダをglslシェーダに変換するのを助けることができますか?

編集:あなたはGLSLを備えたモダンなOpenGLのAPIの実装(C++ソースコード)に興味ある場合は、次の解決Volume_Rendering_Using_GLSL

+0

Cgシェーダは、nVidiaと同じようにATi/AMDでも同様に動作します(Cgランタイムは*多くの*クラッシュ・オン・エラーコードパスを持っているため、比較的相対的です)。 – ssube

+0

CgコンパイラはGLSLコードを発行することができます。また、CgはAMD/ATIカードで使用できます。わずかなNVidia特有のものはうまく動作せず、パフォーマンスはわずかに低下します。 – datenwolf

+0

@datenwolf本当ですか?私はそれを試してみましょう。私はどのようにglslコードを発行するのだろうか? – toolchainX

答えて

14

問題。 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; 
} 

フラグメントシェーダ CGとGLSLの間に少しだけ違いがあるあなたは、CGの元shader見た場合

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; 
} 

param = cgGetNamedParameter(program, par); 
cgGLSetTextureParameter(param, tex); 
cgGLEnableTextureParameter(param); 

において非常に重要であるテクスチャユニットと(glActiveTextureを使用して)マルチテクスチャ活性化および非活性化のプロセスをカプセル化:GLSLバージョンにデモを変換する最も難しい部分は、以下のようなOpenGLでのCG関数ということですこのデモでは固定パイプラインとプログラマブルパイプラインを使用していました。ここではメインの機能void raycasting_pass()で変更されたキーセグメントです。それだ

機能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); 
} 

:チュートリアルをレイキャスティングピーターTriers GPUでのデモのCPP。

関連する問題