Skip to content

Commit 1587841

Browse files
author
Michael Bassili
committed
Look at model and compute projection instead of just rendering model with camera angle transpose
1 parent 2a5d59e commit 1587841

File tree

1 file changed

+41
-82
lines changed

1 file changed

+41
-82
lines changed

main.cpp

Lines changed: 41 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include <vector>
2+
#include <cstdlib>
23
#include <limits>
34
#include <iostream>
45
#include "tgaimage.h"
@@ -7,124 +8,82 @@
78
#include "our_gl.h"
89

910
Model *model = NULL;
10-
float *shadowbuffer = NULL;
1111

1212
const int width = 800;
1313
const int height = 800;
1414

15-
Vec3f light_dir(1,1,0);
16-
Vec3f eye(1,1,4);
15+
Vec3f eye(1.2,-.8,3);
1716
Vec3f center(0,0,0);
1817
Vec3f up(0,1,0);
1918

20-
struct Shader : public IShader {
21-
mat<4,4,float> uniform_M; // Projection*ModelView
22-
mat<4,4,float> uniform_MIT; // (Projection*ModelView).invert_transpose()
23-
mat<4,4,float> uniform_Mshadow; // transform framebuffer screen coordinates to shadowbuffer screen coordinates
24-
mat<2,3,float> varying_uv; // triangle uv coordinates, written by the vertex shader, read by the fragment shader
25-
mat<3,3,float> varying_tri; // triangle coordinates before Viewport transform, written by VS, read by FS
26-
27-
Shader(Matrix M, Matrix MIT, Matrix MS) : uniform_M(M), uniform_MIT(MIT), uniform_Mshadow(MS), varying_uv(), varying_tri() {}
19+
struct ZShader : public IShader {
20+
mat<4,3,float> varying_tri;
2821

2922
virtual Vec4f vertex(int iface, int nthvert) {
30-
varying_uv.set_col(nthvert, model->uv(iface, nthvert));
31-
Vec4f gl_Vertex = Viewport*Projection*ModelView*embed<4>(model->vert(iface, nthvert));
32-
varying_tri.set_col(nthvert, proj<3>(gl_Vertex/gl_Vertex[3]));
23+
Vec4f gl_Vertex = Projection*ModelView*embed<4>(model->vert(iface, nthvert));
24+
varying_tri.set_col(nthvert, gl_Vertex);
3325
return gl_Vertex;
3426
}
3527

36-
virtual bool fragment(Vec3f bar, TGAColor &color) {
37-
Vec4f sb_p = uniform_Mshadow*embed<4>(varying_tri*bar); // corresponding point in the shadow buffer
38-
sb_p = sb_p/sb_p[3];
39-
int idx = int(sb_p[0]) + int(sb_p[1])*width; // index in the shadowbuffer array
40-
float shadow = .3+.7*(shadowbuffer[idx]<sb_p[2]); // magic coeff to avoid z-fighting
41-
Vec2f uv = varying_uv*bar; // interpolate uv for the current pixel
42-
Vec3f n = proj<3>(uniform_MIT*embed<4>(model->normal(uv))).normalize(); // normal
43-
Vec3f l = proj<3>(uniform_M *embed<4>(light_dir )).normalize(); // light vector
44-
Vec3f r = (n*(n*l*2.f) - l).normalize(); // reflected light
45-
float spec = pow(std::max(r.z, 0.0f), model->specular(uv));
46-
float diff = std::max(0.f, n*l);
47-
TGAColor c = model->diffuse(uv);
48-
for (int i=0; i<3; i++) color[i] = std::min<float>(20 + c[i]*shadow*(1.2*diff + .6*spec), 255);
28+
virtual bool fragment(Vec3f gl_FragCoord, Vec3f bar, TGAColor &color) {
29+
color = TGAColor(0, 0, 0);
4930
return false;
5031
}
5132
};
5233

53-
struct DepthShader : public IShader {
54-
mat<3,3,float> varying_tri;
55-
56-
DepthShader() : varying_tri() {}
34+
float max_elevation_angle(float *zbuffer, Vec2f p, Vec2f dir) {
35+
float maxangle = 0;
36+
for (float t=0.; t<1000.; t+=1.) {
37+
Vec2f cur = p + dir*t;
38+
if (cur.x>=width || cur.y>=height || cur.x<0 || cur.y<0) return maxangle;
5739

58-
virtual Vec4f vertex(int iface, int nthvert) {
59-
Vec4f gl_Vertex = embed<4>(model->vert(iface, nthvert)); // read the vertex from .obj file
60-
gl_Vertex = Viewport*Projection*ModelView*gl_Vertex; // transform it to screen coordinates
61-
varying_tri.set_col(nthvert, proj<3>(gl_Vertex/gl_Vertex[3]));
62-
return gl_Vertex;
40+
float distance = (p-cur).norm();
41+
if (distance < 1.f) continue;
42+
float elevation = zbuffer[int(cur.x)+int(cur.y)*width]-zbuffer[int(p.x)+int(p.y)*width];
43+
maxangle = std::max(maxangle, atanf(elevation/distance));
6344
}
64-
65-
virtual bool fragment(Vec3f bar, TGAColor &color) {
66-
Vec3f p = varying_tri*bar;
67-
color = TGAColor(255, 255, 255)*(p.z/depth);
68-
return false;
69-
}
70-
};
45+
return maxangle;
46+
}
7147

7248
int main(int argc, char** argv) {
7349
if (2>argc) {
7450
std::cerr << "Usage: " << argv[0] << "obj/model.obj" << std::endl;
7551
return 1;
7652
}
77-
7853
float *zbuffer = new float[width*height];
79-
shadowbuffer = new float[width*height];
80-
for (int i=width*height; --i; ) {
81-
zbuffer[i] = shadowbuffer[i] = -std::numeric_limits<float>::max();
82-
}
83-
54+
for (int i=width*height; i--; zbuffer[i] = -std::numeric_limits<float>::max());
8455
model = new Model(argv[1]);
85-
light_dir.normalize();
8656

87-
{ // rendering the shadow buffer
88-
TGAImage depth(width, height, TGAImage::RGB);
89-
lookat(light_dir, center, up);
90-
viewport(width/8, height/8, width*3/4, height*3/4);
91-
projection(0);
57+
TGAImage frame(width, height, TGAImage::RGB);
58+
lookat(eye, center, up);
59+
viewport(width/8, height/8, width*3/4, height*3/4);
60+
projection(-1.f/(eye-center).norm());
9261

93-
DepthShader depthshader;
94-
Vec4f screen_coords[3];
95-
for (int i=0; i<model->nfaces(); i++) {
96-
for (int j=0; j<3; j++) {
97-
screen_coords[j] = depthshader.vertex(i, j);
98-
}
99-
triangle(screen_coords, depthshader, depth, shadowbuffer);
62+
ZShader zshader;
63+
for (int i=0; i<model->nfaces(); i++) {
64+
for (int j=0; j<3; j++) {
65+
zshader.vertex(i, j);
10066
}
101-
depth.flip_vertically(); // to place the origin in the bottom left corner of the image
102-
depth.write_tga_file("depth.tga");
67+
triangle(zshader.varying_tri, zshader, frame, zbuffer);
10368
}
10469

105-
Matrix M = Viewport*Projection*ModelView;
106-
107-
{ // rendering the frame buffer
108-
TGAImage frame(width, height, TGAImage::RGB);
109-
lookat(eye, center, up);
110-
viewport(width/8, height/8, width*3/4, height*3/4);
111-
projection(-1.f/(eye-center).norm());
112-
113-
Shader shader(ModelView, (Projection*ModelView).invert_transpose(), M*(Viewport*Projection*ModelView).invert());
114-
Vec4f screen_coords[3];
115-
for (int i=0; i<model->nfaces(); i++) {
116-
for (int j=0; j<3; j++) {
117-
screen_coords[j] = shader.vertex(i, j);
70+
for (int x=0; x<width; x++) {
71+
for (int y=0; y<height; y++) {
72+
if (zbuffer[x+y*width] < -1e5) continue;
73+
float total = 0;
74+
for (float a=0; a<M_PI*2-1e-4; a += M_PI/4) {
75+
total += M_PI/2 - max_elevation_angle(zbuffer, Vec2f(x, y), Vec2f(cos(a), sin(a)));
11876
}
119-
triangle(screen_coords, shader, frame, zbuffer);
77+
total /= (M_PI/2)*8;
78+
total = pow(total, 100.f);
79+
frame.set(x, y, TGAColor(total*255, total*255, total*255));
12080
}
121-
frame.flip_vertically(); // to place the origin in the bottom left corner of the image
122-
frame.write_tga_file("framebuffer.tga");
12381
}
12482

125-
delete model;
83+
frame.flip_vertically();
84+
frame.write_tga_file("framebuffer.tga");
12685
delete [] zbuffer;
127-
delete [] shadowbuffer;
86+
delete model;
12887
return 0;
12988
}
13089

0 commit comments

Comments
 (0)