Post by pwnedgej on Feb 2, 2023 6:25:13 GMT
Hi all, I've been working through the ray tracer challenge and I'm up to chapter 11, where I have finished implementing reflective behavior. However, when I render my scene, I notice the walls have a sort of acne effect on them.
The floor seems to be okay, when I render the scene without any walls, it looks great. I have scoured my code and I have no clue what could be causing this issue. I have also looked around on this help forum and have implemented any fixes that helped others on acne-related issues. I have tried translating my walls in the y-direction, I have double checked that I am passing comps.over_point to the lighting() function, instead of the regular comps.point, and I have adjusted my EPSILON value, none of which have worked. I would greatly appreciate if someone could give me some direction as to what might be wrong with my code.
Here are a few notes that I think might help with that process:
- my project is in C++
- all floating point numbers are represented using doubles
- the acne effect appears regardless of the reflectivity and pattern of the walls
- the walls in the image are rendered using planes (as well as the floor), but when I render the walls using flattened spheres as in chapter 7, they work fine, so possibly an issue with the way my planes are implemented?
Here is my implementation of the plane class:
Also, here is my code in main() that actually produces the image:
Lastly, here is my github repository, in case anyone wants to do some investigating for themselves. If you do, please excuse my poor software design, it's my first time using C++ for such a large project
github.com/Jackobins/RayTracer
The floor seems to be okay, when I render the scene without any walls, it looks great. I have scoured my code and I have no clue what could be causing this issue. I have also looked around on this help forum and have implemented any fixes that helped others on acne-related issues. I have tried translating my walls in the y-direction, I have double checked that I am passing comps.over_point to the lighting() function, instead of the regular comps.point, and I have adjusted my EPSILON value, none of which have worked. I would greatly appreciate if someone could give me some direction as to what might be wrong with my code.
Here are a few notes that I think might help with that process:
- my project is in C++
- all floating point numbers are represented using doubles
- the acne effect appears regardless of the reflectivity and pattern of the walls
- the walls in the image are rendered using planes (as well as the floor), but when I render the walls using flattened spheres as in chapter 7, they work fine, so possibly an issue with the way my planes are implemented?
Here is my implementation of the plane class:
plane::plane() = default;
plane::plane(matrix transform, material material) {
inverseTransform = transform.inverse();
surfaceMaterial = material;
}
vec plane::normalAt(point point) {
return vec(0,1,0);
}
vector<double> plane::intersect(ray r) {
if ((double)abs((double)r.direction.y) < EPSILON) {
return {};
}
return {(double)-r.origin.y / (double)r.direction.y};
}
Also, here is my code in main() that actually produces the image:
shape* floor = new plane();
floor->surfaceMaterial.pattern = new checkers(color(1,1,1), color(0,0,0));
floor->surfaceMaterial.reflective = 0.3;
shape* leftWall = new plane();
matrix transform = matrixOps::multiply(matrixOps::rotationMatrix(1, -M_PI_4),
matrixOps::rotationMatrix(0, M_PI_2));
transform = matrixOps::multiply(matrixOps::translationMatrix(0,0,5), transform);
leftWall->setTransform(transform);
shape* rightWall = new plane();
matrix transform2 = matrixOps::multiply(matrixOps::rotationMatrix(1, M_PI_4),
matrixOps::rotationMatrix(0, M_PI_2));
transform2 = matrixOps::multiply(matrixOps::translationMatrix(0,0,5), transform2);
rightWall->setTransform(transform2);
shape* middle = new sphere();
middle->setTransform(matrixOps::translationMatrix(-0.5,1,0.5));
middle->surfaceMaterial = material();
middle->surfaceMaterial.surfaceColor = color(0.1,1,0.5);
middle->surfaceMaterial.diffuse = 0.7;
middle->surfaceMaterial.specular = 0.3;
middle->surfaceMaterial.pattern = new stripes(color(0,1,0), color(1,0,0));
middle->surfaceMaterial.pattern->setTransform(matrixOps::scalingMatrix(0.5,0.5,0.5));
middle->surfaceMaterial.reflective = 0.8;
shape* right = new sphere();
right->setTransform(matrixOps::multiply(matrixOps::translationMatrix(1.5,0.5,-0.5),
matrixOps::scalingMatrix(0.5,0.5,0.5)));
right->surfaceMaterial = material();
right->surfaceMaterial.surfaceColor = color(1, 0.5, 0.1);
right->surfaceMaterial.diffuse = 0.7;
right->surfaceMaterial.specular = 0.3;
right->surfaceMaterial.reflective = 0.2;
shape* left = new sphere();
left->setTransform(matrixOps::multiply(matrixOps::translationMatrix(-1.5,0.33,-0.75),
matrixOps::scalingMatrix(0.33,0.33,0.33)));
left->surfaceMaterial = material();
left->surfaceMaterial.surfaceColor = color(1, 0.8, 0.1);
left->surfaceMaterial.diffuse = 0.7;
left->surfaceMaterial.specular = 0.3;
left->surfaceMaterial.reflective = 0.2;
pointLight lightSource = pointLight(point(-10,10,-10),
color(1,1,1));
world* w = new world(lightSource, {floor, leftWall, rightWall, middle, left, right});
camera* cam = new camera(480, 360, M_PI/3);
cam->setTransform(worldOps::viewTransform(point(0, 1.5, -5),
point(0,1,0),
vec(0,1,0)));
canvas c = worldOps::render(cam, w);
Lastly, here is my github repository, in case anyone wants to do some investigating for themselves. If you do, please excuse my poor software design, it's my first time using C++ for such a large project
github.com/Jackobins/RayTracer