赞
踩
**
**
lecture11和lecture12,主要了解如何递归的去求解贝塞尔曲线,曲面细分和简化的一些方法。作业也很简单,这里就不再多说了。提一下lecture12末尾的shadowmap。
在光栅化中,做求解阴影是很难直接求解的。shadowMap的原理就是在光源方向再放置一个摄像机,通过一个只处理深度的shader把场景的深度信息存入到一张贴图中。那么处理遮挡信息就变成了,在主相机渲染时,将世界坐标下的点转换到光源相机的view空间中,通过对比深度计算遮挡关系。但是,由于这张shadowMap的分辨率限制,它对应的不是场景中的一个点而是一片区域。可想而知,这片区域的深度在计算时如果都按照一个深度去计算就不太对。因此人们采用了bias的方法,把深度向光源方向“拉一点”。这个bias可以根据需要写作常量,也可以根据相机和着色点的夹角进行求解。当然,这个开销还是比较大的,对于低性能机器,可以直接绘制一个阴影的面片,或者在绘制人物的时候,把人物“压”到一个固定的平面上。这样也不用考虑阴影的投射和接收了。缺点就是在上楼梯这种就会有明显的穿帮。王者荣耀似乎就是用的planar shadow + 根据高度增加透明度的方法。同时,对于计算阴影时如果采用非0即1的方法,容易在边界处出现一些锯齿。因此可以采用PCF等办法,避免这种非0即1的情况。在有些游戏中采用了低分辨率的shadowmap,就会采用一种blur的办法来避免这种情况。
**
**
这是作业4,贝塞尔曲线的代码。
cv::Point2f recursive_bezier(const std::vector<cv::Point2f> &control_points, float t)
{
// TODO: Implement de Casteljau's algorithm
if(control_points.size() == 1) return control_points[0];
std::vector<cv::Point2f> Points;
for(int i = 0 ; i < control_points.size()-1; ++i){
Points.emplace_back(control_points[i] * (1-t) + t * control_points[i+1]);
}
//return cv::Point2f();
return recursive_bezier(Points,t);
}
**
**
这节主要讲Whitted-Style Ray Tracing.
思想很简单,根据光路的可逆性,我们完全可以从屏幕向场景打一条光线出去。根据这条光线打到的物体,对hitPoint进行着色返回到屏幕上。打到物体后,根据法线求解反射光线再继续递归。阴影的实现是根据这个hitPoint向光源连一条线,查看是否还有其它的hitPoint。
光线的定义 : 发射原点o,发射方向dir,参数t。 那么一个光线就可以定义为 p = o + dir * t。
光线和球体的碰撞是容易求解的,联立方程组并取较小的解即可。
光和三角面的碰撞:o + dir * t = (1-u-v)A + uB + vC,求解一个线性方程组。右边是用重心坐标进行表示的。
**
**
光线和三角形碰撞
bool rayTriangleIntersect(const Vector3f& v0, const Vector3f& v1, const Vector3f& v2, const Vector3f& orig, const Vector3f& dir, float& tnear, float& u, float& v) { // TODO: Implement this function that tests whether the triangle // that's specified bt v0, v1 and v2 intersects with the ray (whose // origin is *orig* and direction is *dir*) // Also don't forget to update tnear, u and v. Vector3f E1 = v1 - v0; Vector3f E2 = v2 - v0; Vector3f S = orig - v0; Vector3f S1 = crossProduct(dir,E2); Vector3f S2 = crossProduct(S,E1); float det = 1 / dotProduct(S1,E1); u = det * dotProduct(S1,S); if(u < 0 || u > 1) return false; v = det * dotProduct(S2,dir); if(v < 0 || u + v > 1) return false; tnear = det * dotProduct(S2,E2); if(tnear < 0) return false; return true; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。