计算机图形学学习日志3
计算机图形学学习日志3
- 1.Z-Buffer算法
- 2.漫反射的能量计算
- 作业2
1.Z-Buffer算法
由画家算法推广而来。
画家算法:优先选择深度更深的东西渲染,循序渐进。
不足:无法处理3个或者更多个两两互相覆盖的图形。
Z-Buffer在以画家算法思想(没有排序)渲染的时候,记录当前像素点的深度,如果后续该点的深度大于新渲染的点的深度,那么更新这个像素点的深度为较浅的这个。
2.漫反射的能量计算
kd表示漫反射系数,i表示单位长度能获取的能量,r表示距离光源距离,max(0, n*l)表示入射和发现夹角余弦值,与v无关。
由于能量守恒,单位面积光强相等,小的圆球表面积总和光强应该等于大圆球表面积总和光强。所以图示点位光强是I/r^2。
作业2
来源:九九345
auto v = t.toVector4();
// TODO : Find out the bounding box of current triangle.
int minX = std::min(std::min(v[0].x(), v[1].x()), v[2].x());
int minY = std::min(std::min(v[0].y(), v[1].y()), v[2].y());
int maxX = std::max(std::max(v[0].x(), v[1].x()), v[2].x());
int maxY = std::max(std::max(v[0].y(), v[1].y()), v[2].y());
//得到三角形的边框盒
// iterate through the pixel and find if the current pixel is inside the triangle
for (int i = minX; i <= maxX; i++)
{
for (int j = maxY; j <= maxY; j++)
{
if (insideTriangle(i + 0.5, j +0.5, t.v))
{
auto[alpha, beta, gamma] = computeBarycentric2D(i, j, t.v);
float w_reciprocal = 1.0/(alpha / v[0].w() + beta / v[1].w() + gamma / v[2].w());
float z_interpolated = alpha * v[0].z() / v[0].w() + beta * v[1].z() / v[1].w() + gamma * v[2].z() / v[2].w();
z_interpolated *= w_reciprocal;
//得到目前的深度z
int cur_index = get_index(i, j);//获取当前坐标的索引
if (z_interpolated < depth_buf[cur_index])//通过索引找到该坐标目前的深度
{
depth_buf[cur_index] = z_interpolated;//如果比目前的深则更新
Vector3f vertex;
vertex << i, j, z_interpolated;
set_pixel(vertex, t.getColor());//重新渲染该点
}
}
}
static bool insideTriangle(int x, int y, const Vector3f* _v)
{ //向量叉乘
// TODO : Implement this function to check if the point (x, y) is inside the triangle represented by _v[0], _v[1], _v[2]
Eigen::Vector2f AB, BC, CA, AP, BP, CP, p;
float a, b, c;
p << x, y;
AB = _v[1].head(2) - _v[0].head(2);
AP = p - _v[0].head(2);
BC = _v[2].head(2) - _v[1].head(2);
BP = p - _v[1].head(2);
CA = _v[0].head(2) - _v[2].head(2);
CP = p - _v[2].head(2);
a = AB[0] * AP[1] - AB[1] * AP[0];
b = BC[0] * BP[1] - BC[1] * BP[0];
c = CA[0] * CP[1] - CA[1] * CP[0];
if (a > 0 && b > 0 && c > 0) return true;
else if (a < 0 && b < 0 && c < 0) return true;
return false;
}