GAMES101学习笔记 lecture11-lecture13 作业4-作业5

**

lecture11 and lecture12

**
lecture11和lecture12,主要了解如何递归的去求解贝塞尔曲线,曲面细分和简化的一些方法。作业也很简单,这里就不再多说了。提一下lecture12末尾的shadowmap。

在光栅化中,做求解阴影是很难直接求解的。shadowMap的原理就是在光源方向再放置一个摄像机,通过一个只处理深度的shader把场景的深度信息存入到一张贴图中。那么处理遮挡信息就变成了,在主相机渲染时,将世界坐标下的点转换到光源相机的view空间中,通过对比深度计算遮挡关系。但是,由于这张shadowMap的分辨率限制,它对应的不是场景中的一个点而是一片区域。可想而知,这片区域的深度在计算时如果都按照一个深度去计算就不太对。因此人们采用了bias的方法,把深度向光源方向“拉一点”。这个bias可以根据需要写作常量,也可以根据相机和着色点的夹角进行求解。当然,这个开销还是比较大的,对于低性能机器,可以直接绘制一个阴影的面片,或者在绘制人物的时候,把人物“压”到一个固定的平面上。这样也不用考虑阴影的投射和接收了。缺点就是在上楼梯这种就会有明显的穿帮。王者荣耀似乎就是用的planar shadow + 根据高度增加透明度的方法。同时,对于计算阴影时如果采用非0即1的方法,容易在边界处出现一些锯齿。因此可以采用PCF等办法,避免这种非0即1的情况。在有些游戏中采用了低分辨率的shadowmap,就会采用一种blur的办法来避免这种情况。

**

作业4

**
这是作业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);
}

**

lecture13

**

这节主要讲Whitted-Style Ray Tracing.

思想很简单,根据光路的可逆性,我们完全可以从屏幕向场景打一条光线出去。根据这条光线打到的物体,对hitPoint进行着色返回到屏幕上。打到物体后,根据法线求解反射光线再继续递归。阴影的实现是根据这个hitPoint向光源连一条线,查看是否还有其它的hitPoint。

光线的定义 : 发射原点o,发射方向dir,参数t。 那么一个光线就可以定义为 p = o + dir * t。

光线和球体的碰撞是容易求解的,联立方程组并取较小的解即可。

光和三角面的碰撞:o + dir * t = (1-u-v)A + uB + vC,求解一个线性方程组。右边是用重心坐标进行表示的。

**

作业5

**

光线和三角形碰撞

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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值