|
Post by serial on Nov 5, 2019 4:48:02 GMT
I've gotten groups working and did the hexagon exercise, but when I started playing around with it I noticed it looks funny. Here's the "normal" one from the exercise, it renders ok: Here's the same thing but rotated around the x axis Pi / -3 Any idea why it has those weird pinch-points?
|
|
|
Post by gbordelon on Nov 5, 2019 5:55:00 GMT
My first guess is the normal vector is not being correctly calculated. Can you share your normal_at, world_to_object, and object_to_world functions?
|
|
|
Post by serial on Nov 5, 2019 16:01:41 GMT
|
|
|
Post by serial on Nov 6, 2019 4:43:31 GMT
Maybe it's related, but there's another problem with my code too, I can't seem to be able to recreate the image here forum.raytracerchallenge.com/thread/15/first-light-refraction-codeMine just turns out like this: Even if I take both sphere's out of the scene just to see if I can render a view looking down at the checkered "floor" but it comes out the same. I've been implementing the unit tests and they're passing, but I guess I've missed something somewhere or made a mistake. Any idea's on which part I might have messed up? At least I can go back through my git history to see if I had it working at some point...
|
|
|
Post by serial on Nov 6, 2019 5:14:48 GMT
Turns out I was using the wrong vector in my view transformation for "up", so the glass-inside-a-sphere works.
|
|
|
Post by gbordelon on Nov 6, 2019 10:03:31 GMT
As far as I can tell (never written F# before) the normal functions look good. Did the view vector fix for the glass-inside-a-sphere also fix the group text render?
|
|
|
Post by serial on Nov 6, 2019 15:32:43 GMT
No; for the sphere-within-a-sphere I needed to set X to be "up", but was using "Y". Trying "X" for "up" with the hexagon shape just gives me this
|
|
|
Post by Jamis on Nov 8, 2019 4:39:43 GMT
As with gbordelon, I don't have much experience with F#, but I'm not seeing anything obviously wrong. Given the images that are being rendered, though, it feels like transformations aren't being applied correctly to child shapes within a group. As was also suggested, it could also be something with the normal computation, but it looks to me like more than the normals are wrong--the geometry itself seems off. My next step here would be to pick a pixel in your output image, preferably one where the shading/geometry is obviously wrong, and then run your renderer on just that pixel. Dump out a whole bunch of numbers for the computations being done on that pixel, and then try to see what might be going wrong. You might need to do some of the computations by hand to compare. Another option would be to start with the unrotated image (which you said renders correctly), and apply a minuscule rotation to it (like, 0.01 radians or something). Does it immediately go wrong? Or does rotation work up to some threshold value? Sorry I don't have a quick fix for you. I could probably render that image with some rotation, and give you some numbers from my own renderer for you to compare with, if that would help?
|
|
|
Post by serial on Nov 10, 2019 0:53:55 GMT
|
|
|
Post by Jamis on Nov 10, 2019 4:06:25 GMT
serial -- that video is really insightful! It makes me wonder if gbordelon is right, about the normal vector not being computer correctly (specifically in the case where the normal is being computed on a child of a group). I've not used F# before, but I did write this ray tracer once in OCaml, and IIRC the stuff involving groups was a lot trickier than I expected in that language. (You can see my OCaml implementation here, if you're interested: github.com/jamis/rtc-ocaml). To simplify the problem being investigated, what happens if you have a scene containing a single group, which contains a single sphere? Then, apply a transformation (like a translation or a scaling) to the sphere, and a rotation to the group. Does the sphere still render correctly?
|
|
|
Post by serial on Nov 10, 2019 15:34:26 GMT
Great idea! I created a sphere with a scaling 1.0 0.5 0.5 on the sphere and rendered it. Then I put it into a group with rotation_z (Math.PI/3.0) on the group Then I put that group into another group with rotation_z (Math.PI/4.0)
|
|
|
Post by serial on Nov 10, 2019 15:37:49 GMT
These all look okay to me; then I repeated the exact same thing but with a cylinder, using the same matrices as I applied to the sphere/groups before. Scaled cylinder by itself Cylinder in a group Cylinder in a group in a group This last one looks wrong, and since the sphere worked, it looks like the issue is with my cylinder code.
|
|
|
Post by serial on Nov 10, 2019 15:48:47 GMT
Cool I'll definitely check that out! The group stuff is definitely difficult with immutable objects; I completely cheated and used mutable collections rather than the idiomatic F# ones. I'm not super happy with my F# code right now, I don't think I've used the type system all that effectively so I'm considering rewriting how I handle shapes. It's been fun to make such a complex program in a programming language I'm new to though, and the book has been fantastic.
|
|
|
Post by Jamis on Nov 10, 2019 17:29:53 GMT
serial, I think the last picture of the sphere looks odd, too, actually. The normals seem off--compare the location of the specular highlight to the location of the shadow. It reminds me of the illustration in the "Surface Normals" section of the book (page 83 or so), with the purple sphere that's been squashed. Huge kudos for going this route! I learned a ton writing the ray tracer in OCaml, too--I'd never written anything in it before, and I learned a lot. Definitely a baptism by fire, though.
|
|
|
Post by serial on Nov 11, 2019 16:25:23 GMT
Ohh, ok. So I rendered just the sphere with all of the same transformations, but without any groups. It turned out like this, does this look right? (rotation_z (Math.PI/4.0))*(rotation_z (Math.PI/3.0))*(rotation_z (Math.PI/3.0))*(scaling 1.0 0.5 0.5) If this one is correct then it's processing groups that's messing up the normals in my code.
|
|