Games101-作业5-光线与三角形相交

本文介绍了游戏开发中的光线投射和三角形相交技术,重点讲解了castRay函数如何计算从摄像机出发的光线与场景中的物体交点,以及如何运用菲涅尔函数处理反射和折射,同时讨论了如何使用Phong模型和硬阴影效果。
摘要由CSDN通过智能技术生成

Games101-作业5-光线与三角形相交

分析

这次作业还是比较简单的,主要是光线投射,需要填的部分就是把相机发出的光线坐标变换到物体所在的世界坐标和利用上课讲过的公式计算射线与三角形的交点。
想搞清楚这个过程可以参考Ray-Tracing: Generating Camera Rays

CastRay

来源:https://zhuanlan.zhihu.com/p/438520487
castRay是真正利用光线弹射着色的函数。其作用就是计算从摄像机出发,穿过每个像素击中的物体表面那个点的颜色。如果没有击中物体,就按背景颜色处理。

整个场景设置了光线最多弹射5次,所以在函数一开始,会看一下是不是超过第五次弹射了。如果是直接返回。

场景中的物体被设置了三种不同的材质属性,第一种透明的(REFLECTION_AND_REFRACTION),第二种镜面的(REFLECTION),第三种粗糙的(DIFFUSE_AND_GLOSSY)。当光线打在透明物体和镜面物体上时,由于这两种物体没有颜色,我们看到的颜色都是光线穿过它或者被反射到其他物体上的颜色,所以需要再次调用castRay函数,看一下下一次的反射或者折射的光线能不能打到有颜色的物体上。当光线打在粗糙的物体上,我们需要在光线和物体的交点上(hitpoint),看一下能不能看到光源(从hitpoint发射一条连接光源的线,看一下和场景里面的物体有没有交点,如果没有或者有交点但是交点在光线身后,则可以看到光源,即被光线照射)。如果能看到光源,则用Phong模型计算光照颜色,反之则在阴影内,变成黑色。另外,**光线打在粗糙的物体上后,不再做弹射。**这就是为啥我们最终渲染出来的阴影是硬阴影。

castRay函数中的菲涅尔函数是为了计算光线照射到一个物体后的反射与折射的比例。

Render

让写的就是把raster space中的像素坐标转换到world space中的坐标。

image-20240402170231533

            // generate primary ray direction
            float x = (2 * ((i + 0.5) / scene.width) - 1) * scale * imageAspectRatio;
            float y = (1 - 2 * ((j + 0.5) / scene.height)) * scale;

rayTriangleIntersect

射线与三角形相交,利用课上讲的MT算法公式。

image-20240402170304622

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, E2 = v2 - v0, S = orig - v0;
    Vector3f S1 = crossProduct(dir, E2), S2 = crossProduct(S, E1);
    float S1E1 = dotProduct(S1, E1);
    tnear = 1.0 / S1E1 * dotProduct(S2, E2);
    u = 1.0 / S1E1 * dotProduct(S1, S);
    v = 1.0 / S1E1 * dotProduct(S2, dir);
    return tnear > 0 && u >= 0 && u <= 1 && v >= 0 && v <= 1 && 1 - u - v >= 0 && 1 - u - v <= 1;
}

结果

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值