doon
New Member
Posts: 4
|
Post by doon on Dec 9, 2018 9:02:29 GMT
Just finishing up the shadows chapter and ran into issue, and just wanted to make sure my thinking was correct.
Shading an intersection from the inside, no longer passes once adding the shadow support. The Second sphere in the world shows as in shadow, so we use the ambient. Based on the default world this seems correct and I think changing the test to match the expected in shadow color is the right thing to do.
also is is also expected that you would need to change the tests for precomputing_comps and testing hit when intersection is inside? my comps.point.z is -1.00001 (when using EPSILON 0.00001) but (at least in my version of python) it will fail the equality test (Adjusting epsilon to 0.0001, makes it pass though)
|
|
|
Post by Jamis on Dec 9, 2018 14:55:53 GMT
Hello doon! For the "Shading an intersection from the inside test", note that the light source is moved so that it is inside the inner sphere, and so should not be casting a shadow on the point of intersection (which should also be inside the sphere). If you're getting a shadow there, and the light and intersection are both inside the sphere, let me know and I can help you troubleshoot. I'm not entirely sure I follow your second question, but there are two things you might try to make it work. First, in your precomputing_comps function, make sure you're using EPSILON as the amount to offset the point, and not a hard-coded 0.0001. (An earlier version of the book hard-coded 0.0001, which was problematic for just the reason you're mentioning.) Second, in the final (unreleased) version of the book, I've changed precomputing_comps so that it does not adjust "comps.point" at all, and instead introduces a new attribute, "comps.over_point". Thus, comps.point remains the raw, unadjusted point, and comps.over_point is the point adjusted by "EPSILON * normalv". The shadow test and lighting code then use "comps.over_point" instead of "comps.point". Does that make sense? One last point: are you saying that when the intersection is inside, your z is -1.00001? Perhaps I'm misunderstanding which test you're talking about, but a z of that value would actually be *outside* the sphere. Let me know specifically which test you're referring to here and I'll see if I can share some specific values from my own tests that might help you troubleshoot.
|
|
doon
New Member
Posts: 4
|
Post by doon on Dec 9, 2018 19:36:08 GMT
Sorry for being unclear, that is what I get for posting late at night.. The test I was referring to was precomputing the state of intersection which for me looks like this
def test_precomputing_state_of_intersection(self): r = rays.Ray(rt.Point(0, 0, -5), rt.Vector(0, 0, 1)) shape = Sphere() i = rays.Intersection(4, shape) comps = i.prepare_computations(r) self.assertEqual(comps.t, i.t) self.assertEqual(comps.object, i.object) self.assertEqual(comps.point, rt.Point(0, 0, -1)) self.assertEqual(comps.eyev, rt.Vector(0, 0, -1)) self.assertEqual(comps.normalv, rt.Vector(0, 0, -1))
When the Test Fails after adjusting comps.point the values are as follows.
Comps.Point: Point: < 0.0, 0.0, -1.00001> Comps.eyev: Vector: < 0.0, 0.0, -1.0> Comps.normalv: Vector:< 0.0, 0.0, -1.0>
Comps.point.z - -1.0 = -1.0000000000065512e-05 abs(Comps.point.z - -1.0) < EPSILON = False
everything is using the EPSILON value, nothing hardcoded.
changing EPSILON to 0.0001 the values become
Comps.Point: Point: < 0.0, 0.0, -1.0001> Comps.eyev: Vector: < 0, 0, -1> Comps.normalv: Vector:< 0.0, 0.0, -1.0>
Comps.point.z - -1.0 = -9.999999999998899e-05 abs(Comps.point.z - -1.0) < EPSILON = True
But if the new version uses a over_point I'll move to using that as well. As this just looks to be floating point oddness when multiplying by 1.
I'll dig into why my shading intersection from inside thinks it is in shadow. Just wanted to make sure that it wasn't expected that it needed to change... Normally I've found when I've screwed up a value in the test.
def test_shading_intersection_from_inside(self): w = World.default() w.light = PointLight(rt.Point(0, 0.25, 0), rt.Color(1, 1, 1)) r = rays.Ray(rt.Point(0, 0, 0), rt.Vector(0, 0, 1)) shape = w.objects[1] i = rays.Intersection(0.5, shape) comps = i.prepare_computations(r) c = w.shade_hit(comps) self.assertEqual(c, rt.Color(0.90498, 0.90498, 0.90498))
Currently adding better debugging .
|
|
doon
New Member
Posts: 4
|
Post by doon on Dec 10, 2018 3:11:09 GMT
Found a bug in my shadow code, forgot to subtract the Point from the Light Position. Interesting all the tests still passed with that bug. So fixed that one and was all excited, but the inside ones still failed thinking they where in shadow.
Then I found the other bug. When computing the over_point with the normalv * EPSILON, I had accidentally did that computation before figuring out if we where inside and I needed to invert the normal, which is why once I moved the point the wrong way I would intersect the sphere, thus thinking it was in shadow. The test that it is in the right direction passes, since that one wasn't inside, which is why it took me a bit longer to figure this out..
On a side note I have a bunch better debugging info / descriptions for my objects now.
|
|
|
Post by Jamis on Dec 10, 2018 3:41:02 GMT
Interesting that the tests were still passing even though you forgot to subtract the point from the light position. How did you get the light vector without that subtraction? The second bug is one that is specifically addressed in the final version of the book, as this seems to have tripped many people up. The final version will make it clear that you need to adjust the point AFTER you adjust the normal. Sorry that tripped you up, too! Just know you're in good company. Regardless, I'm glad you got it all figured out. Hopefully the road ahead is smoother!
|
|
doon
New Member
Posts: 4
|
Post by doon on Dec 10, 2018 4:55:33 GMT
Interesting that the tests were still passing even though you forgot to subtract the point from the light position. How did you get the light vector without that subtraction?
In my implementation magnitude is implemented on the Tuple class, so i just took the magnitude of a point since Point and Vector all derive from Tuple, and most of my operations just return the base class. Reason for bug: Clowny System Design
|
|