huailiang / ray_tracing

gpu-ray-tracing-in-unity implements by three-eyed-games

Home Page:http://blog.three-eyed-games.com/2018/05/12/gpu-path-tracing-in-unity-part-1/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

光线追踪

GPU Ray Tracing in Unity – Part 1

  • 光线追踪
  • 阴影

GPU Ray Tracing in Unity – Part 2

  • 路径追踪 支持蒙特卡洛离散采样。

  • 支持自发光效果。

GPU Ray Tracing in Unity – Part 3

  • 支持对Mesh射线相交算法

Usage

克隆对应的仓库, 然后切换对应的分支

git clone https://github.com/huailiang/ray_tracing.git
cd ray_tracing
# 切換分支(Option)
git checkout pt2

射线相交算法

说明文档

1. 射线与平面相交



所以代码里实现如下:

bool IntersectPlane(Ray ray) {
    t = -ray.origin.y / ray.direction.y;
    return true;
}

2. 射线与球相交



bool IntersectSphere(Ray ray, float3 position,float radius,inout float t) {
    float3 d = ray.origin - position;
    float p1 = -dot(ray.direction, d);
    float p2sqr = p1 * p1 - dot(d, d) +radius*radius;
    if (p2sqr < 0)//不存在解也就是不相交
        return false;
    float p2 = sqrt(p2sqr);
    t = p1 - p2 > 0 ? p1 - p2 : p1 + p2;//优先选近的那个点,除非近的点在后头
    return true;
}

3. 射线与三角形相交

射线:$R(t)=O+tD$

射线,一个点从起点o开始,沿着方向D移动任意长度,得到终点R,根据t值的不同,得到的R值也不同,所有这些不同的R值便构成了整条射线,比如下面的射线,起点是P0,方向是u,p0 + tu也就构成了整条射线。



static const float EPSILON = 1e-8;
bool IntersectTriangle_01(Ray ray, float3 vert0, float3 vert1, float3 vert2,
    inout float t, inout float u, inout float v,inout float toward) {
    //E1 E2
    float3 edge1 = vert1 - vert0;
    float3 edge2 = vert2 - vert0;
    //P=DxE2
    float3 pvec = cross(ray.direction, edge2);
    float det = dot(edge1, pvec);
    //背面det<0 正面>0 在三角形内=0
    if (det < EPSILON&&det >-EPSILON) return false;
    toward=sign(det);
    // 1/(DxE2)·E1    
    float inv_det = 1.0f / det;
    //T
    float3 tvec = ray.origin - vert0;
    //u=invdet *(P·T)
    u = dot(tvec, pvec) * inv_det;
    //如果三角形内的点,重心坐标一定在[0,1]
    if (u < 0.0 || u > 1.0f) return false;
    //Q=TxE1
    float3 qvec = cross(tvec, edge1);
    //v=invdet*(Q·D)
    v = dot(ray.direction, qvec) * inv_det;
    if (v < 0.0 || u + v > 1.0f) return false;
    //t=Q·E2  
    t = dot(edge2, qvec) * inv_det;
    return true;
}

参考资料

About

gpu-ray-tracing-in-unity implements by three-eyed-games

http://blog.three-eyed-games.com/2018/05/12/gpu-path-tracing-in-unity-part-1/


Languages

Language:C# 87.3%Language:ShaderLab 12.7%