疯狂的光线追踪器

时间:2014-09-29 16:30:14

标签: opengl glsl fragment-shader raytracing

我最近开始研究光线跟踪器,即使我工作得很好,但我很快就遇到了麻烦。我试图模拟一个公园,我基本上只有一个DistanceFromPoint(vec3 p)函数来计算一个点与最近对象的距离,在该函数内部,我调用其他函数如DistanceToBench()来给出我与单个物体的距离,我用它来找到最小距离。像DistanceToBench这样的所有函数都首先进行AABB测试,如果它通过了,它们会继续进行更全面的检查。我遇到麻烦的部分是,如果我有一个对象,那么渲染一帧需要近70毫秒或者其他东西。如果我有2,类似于200.如果我有3,它会达到500或者其他东西,4个或更多的对象会简单地崩溃整个场景(每帧15-20秒)。同样的事情,如果我尝试使用阴影 - 如果我有一个对象,阴影将渲染时间从70毫秒增加到180毫秒,但是当我添加2或3个对象时,我无法再渲染具有阴影的场景而不会崩溃整件事情。这是我实际代码的一部分。

float u = (pos.x - 0.5) * 2 * 1.77;
float v = (pos.y - 0.5) * 2;

vec3 ro = eye;
vec3 rd = normalize(forward * f + right * u + up * v);

int materialID;
float dist;

vec3 color = skyColor;

if (CastRay(ro, rd, dist, materialID))
{
    vec3 N = NormalAtPoint(ro + rd*dist);
    vec3 L = -lightDir;
    vec3 V = -rd;
    vec3 H = normalize(V + L);

    float diffuseTerm = saturate(dot (N, L));
    float aoTerm = AOAtPoint(ro + rd*dist, N);
    #ifndef SHADOWS
    float shadowTerm = 1;
    #else
    float shadowTerm = mix(0.5, 1, ShadowAtPoint(ro + rd*dist, L, materialID));
    #endif
    color = mix(materialDarkColor[materialID], materialLightColor[materialID], diffuseTerm) * aoTerm * shadowTerm;
}

color = ApplyFog(rd, dist, color, -lightDir);

这里使用的主要功能是CastRay,它只是从r沿着rd移动直到它到达远处的平面,或者与一个对象碰撞(我使用前面提到的DistanceFromPoint()进行测试)。

所以我的问题是,当对象数量略有增加时,有没有办法阻止程序崩溃?我已经读过将世界划分为网格并将对象放入网格中,但由于我的对象并不完全符合网格 - 因为我的世界将包含7-8个对象,所有这些都是将进行AABB测试 - 我决定不再使用它。除此之外,我不知道如何加快这件事。任何处理这种情况的提示都将受到赞赏。

另外,我已经读过,着色器不能很好地处理分支,因为所有线程必须在给定的时间点执行相同的指令。如果是这样的话,我会更好地使用CPU来渲染而不是GPU,因为我的代码中有很多分支吗?

0 个答案:

没有答案