2013-03-11 23 views
9

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

#version 430 
struct Sphere{ 
    vec4 position; 
    float radius; 
}; 

struct Ray{ 
    vec3 origin; 
    vec3 dir; 
}; 

uniform image2D outputTexture; 
uniform uint  width; 
uniform uint  height; 

float hitSphere(Ray r, Sphere s){ 

    float s_vv = dot(r.dir, r.dir); 
    float s_ov = dot(r.origin, r.dir); 
    float s_mv = dot(s.position.xyz, r.dir); 
    float s_mm = dot(s.position.xyz, s.position.xyz); 
    float s_mo = dot(s.position.xyz, r.origin); 
    float s_oo = dot(r.origin, r.origin); 

    float d = s_ov*s_ov-2*s_ov*s_mv+s_mv*s_mv-s_vv*(s_mm-2*s_mo*s_oo-s.radius*s.radius); 

    if(d < 0){ 
     return -1.0f; 
    } else if(d == 0){ 
     return (s_mv-s_ov)/s_vv; 
    } else { 
     float t1 = 0, t2 = 0; 
     t1 = s_mv-s_ov; 

     t2 = (t1-sqrt(d))/s_vv; 
     t1 = (t1+sqrt(d))/s_vv; 

     return t1>t2? t2 : t1 ; 
    } 
} 

layout (local_size_x = 16, local_size_y = 16, local_size_z = 1) in; 
void main(){ 
    uint x = gl_GlobalInvocationID.x; 
    uint y = gl_GlobalInvocationID.y; 

    if(x < 1024 && y < 768){ 
     float t = 0.0f; 
     Ray r = {vec3(0,0,0), vec3(width/2-x, height/2-y, 1000)}; 
     Sphere sp ={vec4(0, 0, 35, 1), 5.0f}; 

     t = hitSphere(r, sp); 

     if(t <= -0.001f){ 
      imageStore(outputTexture, ivec2(x, y), vec4(0.0, 0.0, 0.0, 1.0)); 
     } else { 
      imageStore(outputTexture, ivec2(x, y), vec4(0.0, 1.0, 0.0, 1.0)); 
     } 

     if(x == 550 && y == 390){ 
      imageStore(outputTexture, ivec2(x, y), vec4(1.0, 0.0, 0.0, 1.0)); 
     } 
    } 
} 

जब मैं आवेदन मैं निम्नलिखित छवि प्राप्त चलाएँ: enter image description here

लेकिन जब मैं सीपीयू मैं पर एक ही एल्गोरिथ्म चलाने निम्नलिखित और अधिक दृढ़ छवि: enter image description here

सबसे पहले मैंने सोचा कि मैंने पर्याप्त कार्य-समूहों को प्रेषित नहीं किया है ताकि प्रत्येक पिक्सेल को अपना स्वयं का गणना शेडर आमंत्रण न हो, लेकिन ऐसा नहीं है। जैसा कि आप GPU प्रस्तुत छवि में देख सकते हैं, मध्य में एक लाल पिक्सेल है जो गणना शेडर में अंतिम पंक्तियों के कारण होता है। इसे हर दूसरे पिक्सेल के लिए पुन: उत्पन्न किया जा सकता है।

मैं इस समय 1024x768 के रिज़ॉल्यूशन का उपयोग करें और यह कैसे मैं अपने गणना शेडर प्रेषण है:

#define WORK_GROUP_SIZE 16 
void OpenGLRaytracer::renderScene(int width, int height){ 
    glUseProgram(_progID); 

    glDispatchCompute(width/WORK_GROUP_SIZE, height/WORK_GROUP_SIZE,1); 

    glMemoryBarrier(GL_TEXTURE_FETCH_BARRIER_BIT); 
} 

गलती कहां है? क्या फ्लोटिंग पॉइंट गणना की सटीकता के साथ कोई समस्या हो सकती है?

+0

अजीब इस एप्लिकेशन को वास्तव में कुछ मैं शनिवार को हुए की तरह लग रहा .. –

+0

आप इस तरह के एक अजीब व्यवहार भर में आया था:

इस समस्या का हल? – Stan

+0

आपका '# संस्करण' निर्देश कहां है? – genpfault

उत्तर

3

गलती इस पंक्ति में है:

Ray r = {vec3(0,0,0), vec3(width/2-x, height/2-y, 1000)}; 

के बाद से चौड़ाई, ऊंचाई, x और y uint चर मैं समस्याओं मिल जाएगा जब अवधि चौड़ाई/2-एक्स negativ हो जाता है।

Ray r = {vec3(0,0,0), vec3(float(width)/2.0f-float(x), float(height)/2.0f-float(y), 1000)}; 
संबंधित मुद्दे