Skip to content

Commit d59a98c

Browse files
committed
linear interpolation perspective correction
1 parent 850c71b commit d59a98c

File tree

2 files changed

+8
-6
lines changed

2 files changed

+8
-6
lines changed

main.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ struct PhongShader : IShader {
3636
vec4 r = normalized(n * (n * l)*2 - l); // reflected light direction
3737
double ambient = .4; // ambient light intensity
3838
double diffuse = 1.*std::max(0., n * l); // diffuse light intensity
39-
double specular = (3.*sample2D(model.specular(), uv)[0]/255.) * std::pow(std::max(r.z, 0.), 35); // specular intensity, note that the camera lies on the z-axis (in eye coordinates), therefore simple r.z, since (0,0,1)*(r.x, r.y, r.z) = r.z
39+
double specular = (.5+2.*sample2D(model.specular(), uv)[0]/255.) * std::pow(std::max(r.z, 0.), 35); // specular intensity, note that the camera lies on the z-axis (in eye coordinates), therefore simple r.z, since (0,0,1)*(r.x, r.y, r.z) = r.z
4040
TGAColor gl_FragColor = sample2D(model.diffuse(), uv);
4141
for (int channel : {0,1,2})
4242
gl_FragColor[channel] = std::min<int>(255, gl_FragColor[channel]*(ambient + diffuse + specular));
@@ -61,7 +61,7 @@ int main(int argc, char** argv) {
6161
init_perspective(norm(eye-center)); // build the Perspective matrix
6262
init_viewport(width/16, height/16, width*7/8, height*7/8); // build the Viewport matrix
6363
init_zbuffer(width, height);
64-
TGAImage framebuffer(width, height, TGAImage::RGB);
64+
TGAImage framebuffer(width, height, TGAImage::RGB, {177, 195, 209, 255});
6565

6666
for (int m=1; m<argc; m++) { // iterate through all input objects
6767
Model model(argv[m]); // load the data

our_gl.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,13 @@ void rasterize(const Triangle &clip, const IShader &shader, TGAImage &framebuffe
3636
#pragma omp parallel for
3737
for (int x=std::max<int>(bbminx, 0); x<=std::min<int>(bbmaxx, framebuffer.width()-1); x++) { // clip the bounding box by the screen
3838
for (int y=std::max<int>(bbminy, 0); y<=std::min<int>(bbmaxy, framebuffer.height()-1); y++) {
39-
vec3 bc = ABC.invert_transpose() * vec3{static_cast<double>(x), static_cast<double>(y), 1.}; // barycentric coordinates of {x,y} w.r.t the triangle
40-
if (bc.x<0 || bc.y<0 || bc.z<0) continue; // negative barycentric coordinate => the pixel is outside the triangle
41-
double z = bc * vec3{ ndc[0].z, ndc[1].z, ndc[2].z }; // linear interpolation of the depth
39+
vec3 bc_screen = ABC.invert_transpose() * vec3{static_cast<double>(x), static_cast<double>(y), 1.}; // barycentric coordinates of {x,y} w.r.t the triangle
40+
vec3 bc_clip = { bc_screen.x/clip[0].w, bc_screen.y/clip[1].w, bc_screen.z/clip[2].w }; // check https://github.com/ssloy/tinyrenderer/wiki/Technical-difficulties-linear-interpolation-with-perspective-deformations
41+
bc_clip = bc_clip / (bc_clip.x + bc_clip.y + bc_clip.z);
42+
if (bc_screen.x<0 || bc_screen.y<0 || bc_screen.z<0) continue; // negative barycentric coordinate => the pixel is outside the triangle
43+
double z = bc_screen * vec3{ ndc[0].z, ndc[1].z, ndc[2].z }; // linear interpolation of the depth
4244
if (z <= zbuffer[x+y*framebuffer.width()]) continue; // discard fragments that are too deep w.r.t the z-buffer
43-
auto [discard, color] = shader.fragment(bc);
45+
auto [discard, color] = shader.fragment(bc_clip);
4446
if (discard) continue; // fragment shader can discard current fragment
4547
zbuffer[x+y*framebuffer.width()] = z; // update the z-buffer
4648
framebuffer.set(x, y, color); // update the framebuffer

0 commit comments

Comments
 (0)