0

I've started working on a ray tracer recently, and even though I got it working pretty well, I soon ran into some trouble. I'm trying to simulate a park, and I basically have one single DistanceFromPoint(vec3 p) function that calculates the distance of a point from the nearest object, and inside that function, I call other functions like DistanceToBench() to give me distance to individual objects, whose min I use to find the minimum distance. All my individual functions like DistanceToBench first do a AABB test, and if it passes that, they proceed to do a more complete check. The part where I'm running into trouble is that if I have 1 object, it takes me nearly 70 ms or something to render one frame. If I have 2, something like 200. If I have 3, it goes up to 500 or something, and 4 objects or more simply crashes the entire scene (something like 15-20s per frame). Same thing if I try to use shadows - if I have one object, shadows increase the render time from 70 ms to something like 180 ms, but the moment I add 2 or 3 objects, I cannot render the scene with shadows anymore without crashing the whole thing. Here is part of my actual code.

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

The main function used here is CastRay, that simply moves from ro along rd until it reaches far plane, or collides with an object (which I test using the before-mentioned DistanceFromPoint()).

So my question is, is there any way to stop the program from crashing when number of objects slightly increase? I've read about partitioning the world into grids and placing objects in grids, but since my objects aren't exactly going to be in grid - and because my world will contain something like 7-8 objects, all of which will have AABB test - I decided to skip using that. Other than that, I don't know how else to speed up this thing. Any tips for handling the situation would be appreciated.

Also, I've read that shaders don't handle branching very well, since all threads must execute the same instructions at a given point of time. If that's the case, would I be better off using CPU to do the rendering instead of GPU, since there are so many branches in my code?

  • 1
    If it takes you 70 ms to render *one single object* then there's something awfully wrong with your tracer architecture. Did you profile your code to see where those 70 ms are coming from? Is it really the GLSL? – user703016 Sep 29 '14 at 16:43
  • When I say 'object', I mean a complex object (like a complex shape made up of several primitives). A single primitive (like a single sphere) takes up virtually no time at all (I have currently capped FPS at 60, so not sure if it can take less than 16 ms to render, but it's at least as fast as that). If it's still slow, then I have no idea why. And no, I haven't tried profiling my code - I'm pretty new to glsl, so I don't know how to do that. Any suggestions on how to do it? And yeah, it's definitely GLSL. If you want, I can show you the entire code. – user3541787 Sep 29 '14 at 17:05
  • @user3541787 How many is "several" primitives? If it's a lot you may want to consider some spacial subdivision scheme within the object. – Tavian Barnes Sep 29 '14 at 21:35
  • Actually, "several" is not too much. Something like 7-8 primitives. The thing I've observed is that the speed decreases exponentially with the number of objects - one single primitive takes virtually no time at all, 8-10 take 70 ms, and anything exceeding 50 (rough guess, but should be fairly accurate) will cause it to take 10s or something to render. – user3541787 Sep 30 '14 at 07:52
  • It seems like the error is not in that snippet. Maybe you can show some more snippets, and we can say whether the error is not in those. Or you can just put your code up on Github or something. – FeepingCreature Sep 30 '14 at 10:44
  • Fair warning : It's nearly 550 lines of code. And well, the main problems (IMO, I'm not sure) are when I either increase the primitives, or add shadows/ambient occlusion to moderate number of primitives. http://pastebin.com/qANNcnXd – user3541787 Sep 30 '14 at 12:30

0 Answers0