문제

레이 캐스팅 알고리즘을 이용한 볼륨 렌더링을 배우고 있습니다.나는 좋은 데모와 튜토리얼을 찾았습니다. 여기.하지만 문제는 nVidia 대신 ATI 그래픽 카드가 있어서 데모에서 cg 셰이더를 사용할 수 없다는 것입니다. 그래서 cg 셰이더를 glsl 셰이더로 변경하고 싶습니다.나는 OpenGL의 레드북(7판)을 읽었지만 glsl과 cg에는 익숙하지 않습니다.데모의 cg 셰이더를 glsl로 변경하는 데 도움을 줄 수 있는 사람이 있나요?또는 광선 캐스팅(물론 glsl)을 사용하는 가장 간단한 볼륨 렌더링 데모에 대한 자료가 있습니까? 여기 데모의 CG 셰이더입니다.내 친구의 nVidia 그래픽 카드에서도 작동할 수 있습니다.가장 혼란스러운 점은 cg의 입력 부분을 glsl로 변환하는 방법을 모른다는 것입니다. 예를 들면 다음과 같습니다.

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

게다가 화면을 그릴 때 2개의 texcoord를 할당하면 2개의 텍스처 단위가 있는 2개의 텍스처 개체를 셰이더에 바인딩하는 프로그램을 작성할 수 있습니다.

glMultiTexCoord2f(GL_TEXTURE0, 1.0, 0.0);

glMultiTexCoord2f(GL_TEXTURE1, 1.0, 0.0);

데모에서 프로그램은 두 개의 텍스처(하나는 2D backface_buffer 3D 1개 volume texture), 그러나 다음과 같은 텍스처 단위가 하나만 있습니다. glMultiTexCoord3f(GL_TEXTURE1, x, y, z); 내 생각 엔 GL_TEXTURE1 단위는 볼륨 텍스처를 위한 것이지만 어떤 것(텍스처 단위)이 볼륨 텍스처를 위한 것입니까? 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

도움이 되었습니까?

해결책

문제 해결. GLSL 버전의 데모 :

정점 쉐이더

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

원래 쉐이더 cg와 glsl 사이에는 약간의 차이가 있습니다. ...에 데모를 GLSL 버전으로 번역하는 가장 어려운 부분은 다음과 같은 OpenGL의 CG 기능입니다.

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

텍스처 유닛과 멀티 라인 덱 코드 (glActiveTexture 사용) 및 비활성화의 프로세스를 캡슐화하고 고정 된 파이프 라인뿐만 아니라 프로그래밍 가능한 파이프 라인을 사용 하므로이 데모에서 매우 중요합니다. 피터 트리 어 GPU RayCasting 자습서의 데모의 Main.cpp의 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);
}
.

.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top