2012-02-28 18 views
17

के साथ वॉल्यूम प्रतिपादन (glsl का उपयोग करके) मैं रे कास्टिंग एल्गोरिदम का उपयोग करके वॉल्यूम प्रतिपादन सीख रहा हूं। मुझे here में एक अच्छा डेमो और ट्यूटोरियल मिला है। लेकिन समस्या यह है कि मेरे पास एनवीडिया के बजाय एक अति ग्राफिक कार्ड है जो मुझे डेमो में सीजी शेडर का उपयोग नहीं कर सकता है, इसलिए मैं सीजी शेडर को glsl shader में बदलना चाहता हूं। मैं ओपनजीएल की लाल किताब (7 संस्करण) से गुजर चुका हूं, लेकिन ग्लस्ल और सीजी से परिचित नहीं हूं। क्या कोई मुझे डीएसओ में सीजी शेडर को glsl में बदलने में मदद कर सकता है? या रे कास्टिंग (निश्चित रूप से glsl में) का उपयोग कर वॉल्यूम प्रतिपादन के सबसे सरल डेमो के लिए कोई सामग्री है। here डेमो का सीजी शेडर है। और यह मेरे दोस्त के एनवीडिया ग्राफिक कार्ड पर काम कर सकता है।रे कास्टिंग एल्गोरिदम

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

क्या अधिक है, मैं करने के लिए 2 बनावट यूनिट के साथ एक कार्यक्रम बाँध 2 बनावट वस्तु लिख सकते हैं: क्या सबसे मुझे भ्रमित कर रहा है कि कैसे उदाहरण के लिए, GLSL के लिए तटरक्षक के प्रवेश हिस्सा अनुवाद करने के लिए नहीं पता है कि है शेडर प्रदान की है कि मैं उदाहरण के लिए दो texcoord आवंटित जब स्क्रीन आकर्षित,

glMultiTexCoord2f(GL_TEXTURE0, 1.0, 0.0);

glMultiTexCoord2f(GL_TEXTURE1, 1.0, 0.0);

डेमो में कार्यक्रमके लिए दो बनावट (एक 2 डी करने के लिए बाध्य होगा volume texture के लिएएक 3 डी), लेकिन 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 और stepizeloc) में से -1 मिला। मुझे पता है कि इसे अनुकूलित किया जा सकता है। कोई भी मुझे सीजी शेडर को glsl shader में अनुवाद करने में मदद कर सकता है?

संपादित करें: आप GLSL के साथ आधुनिक ओपन API कार्यान्वयन (सी ++ स्रोत कोड) में रुचि रखते हैं: Volume_Rendering_Using_GLSL

+0

छग shaders (है, जो बल्कि रिश्तेदार है के रूप में छग क्रम * कई * दुर्घटना-ऑन-त्रुटि codepaths है) अति/AMD पर बस के रूप में अच्छी तरह से काम के रूप में वे nVidia पर करते हैं। – ssube

+0

बस एक अनुस्मारक: सीजी कंपाइलर जीएलएसएल कोड उत्सर्जित कर सकता है। सीजी का उपयोग एएमडी/एटीआई कार्ड के साथ भी किया जा सकता है। केवल कुछ एनवीडिया विशिष्ट चीजें काम नहीं करेंगे, और प्रदर्शन थोड़ा खराब होगा। – datenwolf

+0

@ डेटनवॉल्फ वास्तव में? मुझे इसे एक मौका और देना होगा। मुझे आश्चर्य है कि 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; 
} 

टुकड़ा शेडर

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

वहाँ केवल तटरक्षक और GLSL के बीच एक छोटा सा फर्क है अगर आप तटरक्षक के मूल shader देखा । सबसे कठिन हिस्सा अनुवाद करने के लिए GLSL संस्करण के लिए डेमो ओपन जैसे में तटरक्षक समारोह है जो:

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

बनावट इकाई और multitexture सक्रियण (glActiveTexture प्रयोग करके) और छोड़ना की प्रक्रिया है, जिसमें बहुत महत्वपूर्ण है संपुटित इस डेमो के रूप में यह निश्चित पाइपलाइन के साथ ही प्रोग्राम करने योग्य पाइपलाइन का इस्तेमाल किया। मुख्य कुंजी के फ़ंक्शन void raycasting_pass() में मुख्य सेगमेंट बदल गया है।पीटर Triers GPU raycasting ट्यूटोरियल डेमो के सीपीपी:

समारोह 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); 
} 

यह है कि।

संबंधित मुद्दे