ssloy / tinyrenderer

A brief computer graphics / rendering course
https://github.com/ssloy/tinyrenderer/wiki
Other
20.73k stars 1.99k forks source link

Lesson 6 About the calculation of Zbuffer #103

Closed C-SunRay closed 1 year ago

C-SunRay commented 2 years ago
  1. Thank you for starting this project, I really learned a lot from this project.
  2. When i look into the code of lesson6, i found the following code: Vec3f c = barycentric(proj<2>(pts[0]/pts[0][3]), proj<2>(pts[1]/pts[1][3]), proj<2>(pts[2]/pts[2][3]), proj<2>(P)); float z = pts[0][2]*c.x + pts[1][2]*c.y + pts[2][2]*c.z; float w = pts[0][3]*c.x + pts[1][3]*c.y + pts[2][3]*c.z;

And I am wondering if it is incorrect in geometry? My implentation is divide the pt[0][3] early so it would look like this: float z = pts[0][2]*c.x/pt[0][3] + pts[1][2]/pt[1][3]*c.y + pts[2][2]/pt[2][3]*c.z And its result obviously is not the same with the code I read in lesson6.

  1. Also, I am really curious about the operation of making zbuffer as a tpa image, the code as fellow: int frag_depth = std::max(0, std::min(255, int(z/w+.5))); I believe this operation is based on the deduction that the max z value would not surpass 255 ? well, i think that would be the case if i just mutiply the object coords(z is [-1,1]) by viewport matrix, but if I had use modelview natrix to transfer object coords, it is very likely that the z would surpass the value of 255.

I understand that you are very busy, and I appciate that if someone could share the experience with me.

C-SunRay commented 2 years ago

About 3, I have figured out where is my mistake, i thought the code was moving the camera to the origin, but it actually move the object's coords axis, the origin remain the same, so naturally, the z would not surpass 255.

C-SunRay commented 2 years ago

Also, i believe the proj<3> function would cause some issue too, because if if the r in (x,y,z,r) is smaller than 0, direct discard the fourth dimension would cause the vector <x,y,z> to point in the opposite direction? Instead, make proj function look like this : <x/r,y/r,z/r> might be correct.

XiaofanLinUS commented 2 years ago

"My implentation is divide the pt[0][3] early so it would look like this: float z = pts[0][2]c.x/pt[0][3] + pts[1][2]/pt[1][3]c.y + pts[2][2]/pt[2][3]*c.z And its result obviously is not the same with the code I read in lesson6."

Do you mean you defer the division of pt[*][3] later in the interpolation process?

That wouldn't be correct theoretically. The ideal of division early is to convert the homogeneous coordinates of vec4, which is probably calculated by Mat4 multiplication. If you do not perform it early on, when the w-coordinates which is pt[*][3] is larger than 1 or less than 1, the triangle you draw would be larger or smaller than the correct one in practice.

As for proj<3>, only proj<2> is used. When performing the barycentric coordinate calculation, z is always discarded, which I don't know why. I hope this will help you.