Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Book 1.10.6: Dark edge around hittables with Metal material #1285

Open
0xCache opened this issue Oct 1, 2023 · 4 comments
Open

Book 1.10.6: Dark edge around hittables with Metal material #1285

0xCache opened this issue Oct 1, 2023 · 4 comments
Milestone

Comments

@0xCache
Copy link

0xCache commented Oct 1, 2023

Hi, I'm following the first book's guide and noticed some parts around the fuzzy metal hittable sphere are darker than the center. I suspected it's because when the reflected vector is closer to the surface, where dot(hit.normal, reflected) is closer to 0, a random unit vector multiplied by a big fuzz will make the final scattered ray point inside the sphere. I added a dot check, multiplied the fuzz vector by the dot product, and solved the problem.
Before:
image
After:
image

@hollasch hollasch self-assigned this Oct 19, 2023
@hollasch hollasch added this to the Backlog milestone Oct 19, 2023
@hollasch
Copy link
Collaborator

hollasch commented Apr 4, 2024

Tempted to close this as "by design". From the book, with my emphasis added:

The bigger the fuzz sphere, the fuzzier the reflections will be. This suggests adding a fuzziness parameter that is just the radius of the sphere (so zero is no perturbation). The catch is that for big spheres or grazing rays, we may scatter below the surface. We can just have the surface absorb those.

I agree that this is not an ideal solution, but I inclined to think that formally covering a possible fix for this isn't worth it.

@hollasch hollasch modified the milestones: Backlog, v4.0.0 Apr 4, 2024
@hollasch
Copy link
Collaborator

hollasch commented Apr 4, 2024

Hmmm, perhaps we should just put more guardrails around the fuzz factor. Current code:

metal(const color& albedo, double fuzz) : albedo(albedo), fuzz(fuzz < 1 ? fuzz : 1) {}

Suggested update:

metal(const color& albedo, double fuzz) : albedo(albedo), fuzz(fmin(fabs(fuzz), 0.99)) {}

@hollasch
Copy link
Collaborator

hollasch commented Apr 4, 2024

Nope, the above won't work, since the "fuzz sphere" will more easily intersect with the surface for grazing rays. This is the purpose of the return (dot(scattered.direction(), rec.normal) > 0) statement at the end of metal::scatter().

@0xCache
Copy link
Author

0xCache commented Apr 8, 2024

The problem is that although only returning when not pointing into the sphere works, some energy carried by the rays is lost when rays are absorbed, resulting in a darker colour. So I choose to make the absorbed rays point out. The code first uses a dot product, and returns the scattered ray if the product is greater than 0. If not, return the tangent.

double scale = dot(hit.normal, reflected);
Vec direction = dot(reflected + fuzz, hit.normal) > 0 ? reflected + fuzz : reflected + (scale- 1e-5) * fuzz;

A draft:
image

@hollasch hollasch changed the title [Book1] Dark edge around hittables with Metal material Book1.10.6: Dark edge around hittables with Metal material Apr 19, 2024
@hollasch hollasch changed the title Book1.10.6: Dark edge around hittables with Metal material Book 1.10.6: Dark edge around hittables with Metal material Apr 19, 2024
@hollasch hollasch modified the milestones: v4.0.0, Backlog, v4.0.1 Jul 22, 2024
@hollasch hollasch removed their assignment Jul 29, 2024
@hollasch hollasch modified the milestones: v4.0.1, Backlog, v4.0.2 Aug 21, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants