I have tried to write a simple ray tracer in the fragment shader. I have this function that is supposed to create a diffuse sphere as follows :
Here is the function :
vec3 GetRayColor(Ray ray)
{
Ray new_ray = ray;
vec3 FinalColor = vec3(1.0f);
bool IntersectionFound = false;
int hit_times = 0;
for (int i = 0; i < RAY_BOUNCE_LIMIT; i++)
{
RayHitRecord ClosestSphere = IntersectSceneSpheres(new_ray, 0.001f, MAX_RAY_HIT_DISTANCE);
if (ClosestSphere.Hit == true)
{
// Get the final ray direction
vec3 R;
R.x = nextFloat(RNG_SEED, -1.0f, 1.0f);
R.y = nextFloat(RNG_SEED, -1.0f, 1.0f);
R.z = nextFloat(RNG_SEED, -1.0f, 1.0f);
vec3 S = normalize(ClosestSphere.Normal) + normalize(R);
S = normalize(S);
new_ray.Origin = ClosestSphere.Point;
new_ray.Direction = S;
hit_times += 1;
IntersectionFound = true;
}
else
{
FinalColor = GetGradientColorAtRay(new_ray);
break;
}
}
if (IntersectionFound)
{
FinalColor /= 2.0f; // Lambertian diffuse only absorbs half the light
FinalColor = FinalColor / float(hit_times);
}
return FinalColor;
}
For some reason, it seems like hit_times is constant.
This exact same code works on the CPU and produced the attached screenshot.
I'm not sure if this something to do with the GPU. But I've tested all the other functions and they work as expected.
- The normals are fine and identical
- The random number generator works fine and has been visualized
Here is the Normal + RandomVec or S visualized :
And it is the exact same when done on the CPU.
Here is the hit_times visualised on the CPU
But on the GPU, all three spheres are white. Here is the full fragment shader : https://pastebin.com/3xeA6LtT Here is the code that works on the CPU : https://pastebin.com/eyLnHYzr


