Raymarching(光线步进)基础

RayMarching 光线步进:

光线步进,又称为球体追踪(sphere tracing):

Raymarching(光线步进)基础_第1张图片

组件:

Camera:

输入:
  • uv坐标:告诉我们哪一个像素是我们的目标的渲染像素
  • Pos:坐标
  • lookat:方向
  • Zoom:相机到屏幕的垂直距离
输出:
  • ViewRay:视角光线

Ray Intersection(光线相交):

光线与场景中的物体相交

输入:
  • Ray:视角光线
输出:
  • Distance:距离,相机到与光线相交的物体表面的交点的距离

Material & lighting:

输入:
  • Material:材质属性
  • Distance:距离
  • light:光线
输出:
  • pixel color:像素的颜色

算法:

函数构成:

GetDist:

输入某一点的坐标,输出该点与场景中最近物体的距离。

Raymarching(光线步进)基础_第2张图片

float GetDist(vec3 p)
{
    vec4 s = vec4(0,1,6,1);
    float sphereDist = length(p-s.xyz)-s.w;//坐标点p与圆心的向量的长度减去圆的半径 -->得到坐标点p到圆的最短距离
    float planeDist  = p.y;//坐标点p离平面的最短距离 -->坐标点的y值
    
    float d = min(sphereDist,planeDist);//取二者的最小值
    return d;
}
GetNormal:

输入某点坐标,输出该点的法线方向向量

vec3 GetNormal(vec3 p)
{
    vec2 e = vec2(0.01f, 0.0f);   
    float d = GetDist(p);
    vec3 n = vec3(
    	d - GetDist(p - e.xyy),
    	d - GetDist(p - e.yxy),
    	d - GetDist(p - e.yyx));
    return normalize(n);
}
GetLight:

输入视角向量与空间中物体的交点的坐标,计算该点的漫反射颜色,将颜色值作为该uv像素的颜色

float GetLight(vec3 p)
{
    vec3 lightPos = vec3(0, 5, 6);
    vec3 l = normalize(lightPos - p);//光线方向向量
    vec3 n = GetNormal(p);
    float diff = clamp(dot(n ,l), 0., 1.);
    //阴影,将p点作为原始点,沿着光线的方向向量,得到与空间中物体的距离
    float d = RayMarching(p + n * SURFACE_DIST*2, l);
    if(d < length(lightPos - p))//如果距离小于光源到点p的距离说明二者之间有物体也就是p处于阴影中
        diff *= .1;
    return diff;
}

Raymarching(光线步进)基础_第3张图片

RayMarch:

输入一个点的坐标,以及一个方向向量,输出从该点出发沿着方向向量,与物体的交点的距离

Raymarching(光线步进)基础_第4张图片

#define SURFACE_DIST .01 //接近相交点的判断值。如果小于该值表示已经近似得到交点到摄像机的距离
#define MAX_DIST 100.//最大的距离
#define MAX_STEPS 100//最大的步长

float RayMarch(vec3 ro, vec3 rd) {
	float depth = 0.0f;//距离
    for(int i = 0 ;i < MAX_STEPS; i ++) {
		vec3 pos = ro + depth * rd;//更新位置,点在视角光线上进行移动
        float dist = GetDist(pos);//获取点到物体的最近距离
        depth += dist;//点的移动距离
        if(dist < SURFACE_DIST || depth > MAX_DIST)//如果交点与摄像机点的距离超过最远距离,或者 dist小于判断值表示已经近似得到了摄像机与交点的距离
            break;
    }
    return depth;
}
主函数:
//部分
float d= RayMarch(ro,rd);
vec3 p=ro+rd*d;
float diff=GetLight(p);
vec3 col=vec3(diff);
fragcolor=vec4(col,1.0)

参考资料:https://www.bilibili.com/video/BV1QJ411v7J5?from=search&seid=1569927975704725649

你可能感兴趣的:(图形学,技术美术,unity,c++)