I've been going though Peter Shirley's beginner raytracing books. Upon building the Cornell box and rendering an image, I get a much darker / dimmer image than expected.
The color values are normalized (in the range [0.0f, 1.0f]). The author of the books has stated that for a brighter result, I need to gamma correct the values (calculating the nth root of the color values)The above image has a gamma correction of 2 (square root). This is the same value that the author uses, but his result is much brighter
I tried making the gamma correction larger (increasing n) and after setting n=4 (each color gets set to the (1/4)th exponent), I get this image.
There are obvious artifacts, like a lack of highlights near the light, and the over-saturated small number of pixels where a wall is close to the sphere.
The way a pixel's color is calculated is like this:
for(int j = height - 1; j >= 0; j--)
{
for(int i = 0; i < width; i++)
{
vec3 color(0.0f, 0.0f, 0.0f);
for(int s = 0; s < samplesPerPixel; s++)
{
float u = ((float)i + RandomNumber(0.0f, 1.0f)) / width;
float v = ((float)j + RandomNumber(0.0f, 1.0f)) / height;
ray r = cam.CastRay(u, v);
color += Color(r, list, depth);
}
color /= (float)samplesPerPixel;
color = vec3(pow(color.x, gammaCorrection), pow(color.y, gammaCorrection), pow(color.z, gammaCorrection));
int ir = Map(0.0f, 1.0f, 0.0f, 255.0f, color.x);
int ig = Map(0.0f, 1.0f, 0.0f, 255.0f, color.y);
int ib = Map(0.0f, 1.0f, 0.0f, 255.0f, color.z);
output << ir << " " << ig << " " << ib << "\n";
}
}
And the resulting color values for each channel (red, green and blue) is in the range of [0, 255].
Is there a problem with how I calculate a pixel's color based on all samples? My color
function is pretty much the same as it is in the book
vec3 Color(const ray& r, HitableList& hitables, int depth)
{
float tmin = 0.001f;
float tmax = 10000.0f;
HitData data;
// If the ray hit something
if(hitables.Hit(r, tmin, tmax, data))
{
ray scattered;
vec3 attenuation;
// If the material is a light, store its emitted color
vec3 emitted = data.mat->Emitted(data.u, data.v, data.point);
// If the number of bounces is below 50 and the ray gets scattered into a random direction
if(depth < 50 && data.mat->Scatter(r, data, attenuation, scattered))
return emitted + attenuation * Color(scattered, hitables, depth + 1);
else
return emitted;
} else
return vec3(0.0, 0.0f, 0.0f);
}
Has anyone come across a similar issue before?