2012-02-28 4 views
17

레이 캐스팅 알고리즘을 사용하여 볼륨 렌더링을 배우고 있습니다. 나는 좋은 데모와 tuturial을 발견했다 here. 하지만 문제는 내가 데모에서 cg 쉐이더를 사용할 수 없도록 만드는 nVidia 대신 ATI 그래픽 카드가있어서 CGS 쉐이더를 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 텍스처 유닛과 프로그램의 결합이 텍스처 오브젝트를 작성할 수 있습니다 무엇을 가장 저를 혼동하는 것은 내가 예를 들어, GLSL에 CG의 입구 부분을 번역하는 방법을 모르는 것입니다 쉐이더는 화면을 그릴 때 데모에서는 프로그램이두 개의 텍스처 (한 2D에 바인딩

glMultiTexCoord2f(GL_TEXTURE0, 1.0, 0.0);

glMultiTexCoord2f(GL_TEXTURE1, 1.0, 0.0);

내가 예를 들어, 두 개의 TEXCOORD를 할당하는 것이 제공 3232 하나의 3D에 대한 volume texture), 단 하나의 텍스처 유닛이 glMultiTexCoord3f(GL_TEXTURE1, x, y, z); 인 것 같습니다. GL_TEXTURE1 유닛은 볼륨 텍스처를위한 것이지만, 어느 하나 (texure 유닛)는 backface_buffer입니까? 지금까지의 내가 쉐이더에 텍스처 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); 

프로그램은 잘 컴파일하고 확인을 연결되어 있습니다. 하지만 나는 세 위치 (texloc, volume_texloc 및 stepsizeloc) 중 -1 개 밖에 없습니다. 나는 그것이 밖으로 낙관 될지도 모른다라는 것을 안다. 누구나 내가 cg 쉐이더를 glsl 쉐이더로 변환하는 것을 도울 수 있습니까?

편집 : 당신은 GLSL 현대는 OpenGL API 구현 (C++ 소스 코드)에 관심이 있다면 : Volume_Rendering_Using_GLSL

+0

Cg 쉐이더는 nVidia에서와 마찬가지로 ATi/AMD에서도 잘 작동합니다 (Cg 런타임은 * 많은 * crash-on-error 코드 경로가 있기 때문에 상대적입니다). – 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() main에서 변경된 핵심 세그먼트입니다.피터 Triers GPU의 raycasting 튜토리얼에서 데모의 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); 
} 

.

관련 문제