2012-02-28 26 views
17

Işınım oluşturma algoritması kullanarak hacim oluşturma öğreniyorum. here'da iyi bir demo ve tuturial buldum. Ama problem şu ki, nVidia yerine ATI grafik kartım var, bu da cg shader'ı demoda kullanamayacağından, cg shader'ı glsl shader'a değiştirmek istiyorum. OpenGL'nin kırmızı kitabını (7 baskı) geçtim ama glsl ve cg ile aşina değilim. Herkes demoda cg shader'ı glsl'ye değiştirmeme yardım edebilir mi? veya ışın dökümü kullanarak hacim oluşturmanın en basit demosuna (tabii ki glsl'de) yönelik herhangi bir materyal var mıdır? here, demonun cg gölgesidir. ve arkadaşımın nVidia grafik kartında çalışabilir.birim oluşturma (glsl kullanarak)

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

dahası, ben 2 doku ünitesi ile bir program bağlama 2 doku nesnesini yazabilirsiniz: beni en çok kafa karıştırıcı Ben örneğin, GLSL için cg giriş bölümünü çevirmek için nasıl bilmiyorum olmasıdır gölgelendirici ekranı çizerken demo programıiçin iki doku (bir 2D bağlanacaktır

glMultiTexCoord2f(GL_TEXTURE0, 1.0, 0.0);

glMultiTexCoord2f(GL_TEXTURE1, 1.0, 0.0);

Ben mesela, iki texcoord atamak şartıyla volume texture içinbir 3D) ama) tek glMultiTexCoord3f(GL_TEXTURE1, x, y, z); gibi doku ünitesi ben GL_TEXTURE1 birim hacim dokusu için olduğunu düşünüyorum, ama bir (texure birimi ile backface_buffer içindir? bildiğim kadarıyla bir gölgelendiricide doku obj bağlamak için bildiği gibi, ben mesela bağlamak için bir doku ünitesi almak gerekir:

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

programı ince derlenmiş ve Tamam bağlantılıdır. ama sadece her üç konumdan -1 tane aldım (texloc, volume_texloc ve stepsizeloc). Optimize edilmiş olabileceğini biliyorum. Herkes cg shader'ı glsl shader'a çevirmeme yardım edebilir mi?

Düzenleme: Eğer GLSL modern OpenGL API uygulama (C++ kaynak kodu) ilgi varsa: Volume_Rendering_Using_GLSL

+0

Cg gölgelendiriciler, ATV/AMD'de olduğu gibi nVidia'da da çalışırlar (Cg çalışma zamanı * hatayla dolu bir hata kodu gibi oldukça görecelidir). – ssube

+0

Sadece bir hatırlatma: Cg derleyici GLSL kodunu yayabilir. Ayrıca Cg, AMD/ATI kartları ile kullanılabilir. Sadece birkaç NVidia'ya özgü şey çalışmayacak ve performans biraz zayıflayacak. – datenwolf

+0

@datenwolf gerçekten? Bir deneyeceğim. Glsl kodunu nasıl gönderebilirim acaba? – toolchainX

cevap

14

Sorun çözüldü. arasında glsl versiondemo:

tepe tarayıcı

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

parça gölgelendirici cg ve GLSL arasında sadece küçük bir fark vardır sen cg orijinal shader görülen eğer

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

çok önemlidir doku birimi ve (glActiveTexture kullanarak) multitexture aktivasyonu ve deaktivasyonu sürecini kapsülleyen: en zor kısmı glsl sürümüne demo OpenGL gibi CG fonksiyonu olmasıdır çevirmek Bu demo, sabit boru hattının yanı sıra programlanabilir boru hattını kullandı. Burada ana void raycasting_pass() işlevinde değiştirilen anahtar bölümdür.Peter denekçileri GPU ışın atma eğitimde demo cpp:

fonksiyon raycasting_pass bu kadar

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

.