I am trying to do ray tracing on a couple of spheres. However, when I put a light source directly in front of a circle, I get a X mark (X mark with 3 lines instead of 4) instead of a circle lighting up on the surface of my spheres. I am not using shadow rays and the lighting is only coming from my 2 light sources. I have also implemented the ray tracer in c++ with very similar code as this but without the problems I described so I suspect that it might be some rounding issues. What do you guys think might be causing the problem with the X mark on the sphere?
The 3 pictures below are:
one of them have a "working?" ray tracer but the lights mark an X on the sphere
one of them is the normal map of the scene
one of them is when I use reflect for the ray direction instead of scattering it in random directions
Here is my shader code
#version 410 core
in vec2 v_texCoord;
in vec2 v_rayCoord;
uniform sampler2D u_randTexture;
uniform vec2 u_randSampler;
out vec4 FragColor;
void main()
{
float window_width = 800.f;
float window_height = 600.f;
float focal_distance = -400.f;
const int sphere_count = 4;
const int ray_bounce = 3;
// might be a better way to randomize
vec2 tex_coord = v_texCoord + u_randSampler;
vec4 rand_vec = texture(u_randTexture, tex_coord);
rand_vec = (rand_vec - vec4(0.5f)) * vec4(2.f);
float radius[sphere_count] = float[](0.5f, 100.f, 80.f, 0.1f);
vec3 positions[sphere_count] = vec3[](vec3(0.f, -2.7f, -5.f), vec3(0.f, -103.f, -5.f), vec3(100.f, 80.f, -100.f), vec3(-0.8f, -1.7f, -4.f));
vec3 color[sphere_count] = vec3[](vec3(1.f, 0.5f, 0.5f), vec3(0.5f, 0.5f, 1.f), vec3(0.9f, 0.9f, 0.3f), vec3(0.48f, 0.38f, 0.57f));
float brightness[sphere_count] = float[](0.f, 0.f, 7.f, 500.f);
vec3 ray_origin = vec3(0.f, 0.f, 0.f);
vec3 ray_direction = vec3(v_rayCoord.x, v_rayCoord.y, focal_distance);
vec3 absorb_col = vec3(1.f);
vec3 light_col = vec3(0.f);
for(int i=0;i<ray_bounce;++i)
{
float closest_hit = 10000.f; // arbitrary large number
int idx = -1;
// loop through all the different objects
for(int j=0;j<sphere_count;++j)
{
vec3 origin_to_center = ray_origin - positions[j];
float a = dot(ray_direction, ray_direction);
float b = 2.f * dot(origin_to_center, ray_direction);
float c = dot(origin_to_center, origin_to_center) - radius[j] * radius[j];
float discriminant = b * b - 4.f * a * c;
if(discriminant < 0.f)
continue;
float t = (-b - sqrt(discriminant)) / (2.f * a);
if(t > 0.f && t < closest_hit)
{
closest_hit = t;
idx = j;
}
}
if(idx < 0)
{
//light_col += vec3(0.627f, 1.f, 1.f) * vec3(0.3) * absorb_col;
light_col += vec3(0.f);
break;
}
vec3 surface = ray_origin + ray_direction * closest_hit;
vec3 normal = normalize(surface - positions[idx]);
vec3 incident_vector = normalize(-ray_direction);
ray_origin = surface + normal * 0.00000000001f;
ray_direction = normal + rand_vec.xyz * 0.99f;
if(brightness[idx] > 0.f)
{
light_col += color[idx] * absorb_col * brightness[idx];
break;
} else
{
absorb_col *= color[idx];
}
}
FragColor = vec4(light_col, 1.0);
}
For the random, I sample them from a texture generated by this function in the cpu
// dis(gen) should generate a float from 0.f to 1.f
void randVec3(Renderer::Vec3<float>& _vec3)
{
_vec3.x = dis(gen) * 2.f - 1.f;
_vec3.y = dis(gen) * 2.f - 1.f;
_vec3.z = dis(gen) * 2.f - 1.f;
_vec3.normalize();
}
int main()
{
...
unsigned char* rand_vec_data = new unsigned char[WINDOW_WIDTH * WINDOW_HEIGHT * 3];
for(unsigned int i=0;i<WINDOW_WIDTH * WINDOW_HEIGHT;++i)
{
Renderer::Vec3<float> rand_vector;
randVec3(rand_vector);
rand_vector = (rand_vector + Renderer::Vec3<float>(1.f)) * Renderer::Vec3<float>(0.5f);
rand_vec_data[i * 3] = static_cast<unsigned char>(rand_vector.x * 255);
rand_vec_data[i * 3 + 1] = static_cast<unsigned char>(rand_vector.y * 255);
rand_vec_data[i * 3 + 2] = static_cast<unsigned char>(rand_vector.z * 255);
}
...
}
By the way, when I replaced my code for scattering rays with reflect, my whole scene becomes dark.
ray_direction = reflect(incident_vector, normal);
I tried to change my ray direction to reflect across the normal instead of scattering it. I was hopeing to isolate the problem to see if it was due to the scattering of the rays or a flaw in my calculations. However, when I do that, my whole scene went dark.


