@@ -18,22 +18,43 @@ Vec3f up(0,1,0);
18
18
19
19
struct Shader : public IShader {
20
20
mat<2 ,3 ,float > varying_uv; // triangle uv coordinates, written by the vertex shader, read by the fragment shader
21
+ mat<4 ,3 ,float > varying_tri; // triangle coordinates (clip coordinates), written by VS, read by FS
21
22
mat<3 ,3 ,float > varying_nrm; // normal per vertex to be interpolated by FS
23
+ mat<3 ,3 ,float > ndc_tri; // triangle in normalized device coordinates
22
24
23
25
virtual Vec4f vertex (int iface, int nthvert) {
24
26
varying_uv.set_col (nthvert, model->uv (iface, nthvert));
25
27
varying_nrm.set_col (nthvert, proj<3 >((Projection*ModelView).invert_transpose ()*embed<4 >(model->normal (iface, nthvert), 0 .f )));
26
28
Vec4f gl_Vertex = Projection*ModelView*embed<4 >(model->vert (iface, nthvert));
27
29
varying_tri.set_col (nthvert, gl_Vertex);
30
+ ndc_tri.set_col (nthvert, proj<3 >(gl_Vertex/gl_Vertex[3 ]));
28
31
return gl_Vertex;
29
32
}
30
33
31
34
virtual bool fragment (Vec3f bar, TGAColor &color) {
32
35
Vec3f bn = (varying_nrm*bar).normalize ();
33
36
Vec2f uv = varying_uv*bar;
34
37
35
- float diff = std::max (0 .f , bn*light_dir);
38
+ mat<3 ,3 ,float > A;
39
+ A[0 ] = ndc_tri.col (1 ) - ndc_tri.col (0 );
40
+ A[1 ] = ndc_tri.col (2 ) - ndc_tri.col (0 );
41
+ A[2 ] = bn;
42
+
43
+ mat<3 ,3 ,float > AI = A.invert ();
44
+
45
+ Vec3f i = AI * Vec3f (varying_uv[0 ][1 ] - varying_uv[0 ][0 ], varying_uv[0 ][2 ] - varying_uv[0 ][0 ], 0 );
46
+ Vec3f j = AI * Vec3f (varying_uv[1 ][1 ] - varying_uv[1 ][0 ], varying_uv[1 ][2 ] - varying_uv[1 ][0 ], 0 );
47
+
48
+ mat<3 ,3 ,float > B;
49
+ B.set_col (0 , i.normalize ());
50
+ B.set_col (1 , j.normalize ());
51
+ B.set_col (2 , bn);
52
+
53
+ Vec3f n = (B*model->normal (uv)).normalize ();
54
+
55
+ float diff = std::max (0 .f , n*light_dir);
36
56
color = model->diffuse (uv)*diff;
57
+
37
58
return false ;
38
59
}
39
60
};
0 commit comments