9
我想通過計算着色器在OpenGL中進行一些光線追蹤,並且遇到了一個奇怪的問題。此刻,我只想顯示一個沒有任何陰影的球體。我的計算着色器發射的光線爲每個像素,看起來像這樣:通過計算着色器在OpenGL中進行光線追蹤
#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));
}
}
}
當我運行的應用程序,我獲得下面的圖片:
但是當我運行的CPU,我得到相同的算法以下更令人信服的圖像:
首先,我以爲我沒有派遣足夠的工作組,以便不是每個像素都獲得自己的計算着色器調用,但事實並非如此。正如您在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);
}
哪裏錯了嗎?浮點計算的準確性可能存在問題嗎?
奇怪這個應用程序看起來很像我的東西在週六做.. – 2013-03-11 17:53:42
你碰到過這種奇怪的行爲? – Stan 2013-03-11 18:06:12
你的'#version'指令在哪裏? – genpfault 2013-03-11 18:46:05