Chapter 2 : what is a Ray?
上一章,我们理解了什么是光线投影(ray casting)和光线追踪(ray tracing)。这章节我们细致来看什么是光线。
ABSTRACT
We define a ray, show how to use ray intervals, and demonstrate how to specify a ray using DirectX Raytracing (DXR).
在本节中,我们会定义一条光线,展示了如何使用光线间隔(ray intervals),并演示了如何使用DirectX光线跟踪(DXR)来指定一个光线。
2.1 MATHEMATICAL DESCRIPTION OF A RAY
For ray tracing, an important computational construct is a three-dimensional ray. In both mathematics and ray tracing, a ray usually refers to a three-dimensional half-line. A ray is usually specified as an interval on a line. There is no implicit equation for a line in three dimensions analogous to the two-dimensional line y = mx + b, so usually the parametric form is used. In this chapter, all lines, points, and vectors are assumed to be three-dimensional.
对于光线追踪,一个重要的计算结构就是三维光线(3D ray)。 不管是在数学还是在光线追踪中,光线通常是指三维半线(half-line)(射线?)。一条光线通常会被指定为在一条直线(line)上的一部分(interval)。对于一条直线,在三维空间中很难找到一个类似二维空间中
这样的直线方程来隐式表示。因此,通常使用参数化形式来表示。在本章中,所有的直线、点和矢量均假定为三维空间中。
A parametric line can be represented as a weighted average of points A and B:
一条参数化表示的线可以记为点A和B的加权平均值:
In programming, we might think of this representation as a function P(t) that takes a real number t as input and returns a point P. For the full line, the parameter can take any real value, i.e., t ∈ [−∞, +∞], and the point P moves continuously along the line as t changes, as shown in Figure 2-1. To implement this function, we need a way to represent points A and B. These can use any coordinate system, but Cartesian coordinates are almost always used. In APIs and programming languages, this representation is often called a vec3 or float3 and contains three real numbers x, y, and z. The same line can be represented with any two distinct points along the line. However, choosing different points changes the location defined by a given t-value.
在实际编程中,我们会将这种表示形式视为函数
,该函数以实数
作为输入并返回点
。对于一个完整的直线,参数可以取任何实数,即
。点P随着
的变化而沿直线连续移动,如图2-1所示
。 要实现这个思路,我们需要一种方式来表示点A和B。这里可以使用任何坐标系,但我们常用笛卡尔坐标系(Cartesian coordinates)。 在API和编程语言中,这种表示形式通常被称为vec3
或float3
,其中包含三个实数
,
和
。同一条线可以用沿线的任意两个不同的点表示。但是,选择不同的点会更改由给定
值定义的位置。
It is common to use a point and a direction vector rather than two points. As visualized in Figure 2-2, we can choose our ray direction d as B − A and our ray origin O as point A, giving
但更常见的做法是使用一个点和一个方向向量而非两个点。 如图2-2所示,我们可以将射线方向d选择为B − A,将射线原点O选择为A点,得出
For various reasons, e.g., computing cosines between vectors via dot products, some programs find it useful to restrict d to be a unit vector dˆ, i.e., normalized. One useful consequence of normalizing direction vectors is that t directly represents the signed distance from the origin. More generally, the difference in any two t-values is then the actual distance between the points,
由于各种原因,例如,我们可以通过点积计算向量之间的余弦,一些程序发现很有必要去对向量d做单位化处理变为
,如标准
。标准化后一个有用的结果就是
可以直接表示原点开始的有符号距离。一般来说,任何两个t值之差就是两点之间的距离。
对于一般矢量d,此公式表示可以按d的长度缩放。
Ray intervals
With the ray formulation from Equation 2, our mental picture is of a ray as a semi- infinite line. However, in ray tracing a ray frequently comes with an additional interval: the range of t-values for which an intersection is useful. Generally, we specify this interval as two values, tmin and tmax, which bound the t-value to t ∈ [tmin,tmax]. In other words, if an intersection is found at t, that intersection will not be reported if t < tmin or t > tmax. See Figure 2-3.
使用第二种建模方式,我们设想的图像是一条射线,即半无限线。在光线追踪中,光线经常带有一个额外的间隔。相交在特定的 值范围内才是有效的。 通常做法是我们将此间隔指定为两个值 和 ,并规定 。 换句话说,如果在 处找到一个交集(intersection),如果 或 则不会报告(report)该交集。 参见图2-3。
对于这个图中为什么要寻找相交点(intersection),其意义是什么?
A maximum value is given when hits beyond a certain distance do not matter, such as for shadow rays. Assume that we are shading point P and want to query visibility of a light at L. We create a shadow ray with origin at O = P, unnormalized direction vector d = L − P, tmin = 0, and tmax = 1. If an intersection occurs with t in [0,1], the ray intersects geometry occluding the light. In practice, we often set tmin = ε and
tmax = 1 − ε, for a small number ε. This adjustment helps avoid self-intersections due to numerical imprecision; using floating-point mathematics, the surface on which P lies may intersect our ray at a small, nonzero value of t. For non-point lights the light’s primitive should not occlude the shadow ray, so we shorten the interval using tmax = 1 − ε. With perfect mathematics, this problem disappears using an open interval, ignoring intersections at precisely t = 0 and 1. Since floating-point precision is limited, use of ε fudge factors are a common solution. See Chapter 6 for more information about how to avoid self-intersections.
当相交点(hits)超过最大距离时将被不再会被考虑。对于阴影光线(shadow rays),如果假设我们要在P处着色(shading)并想知道一个在L处的光源在此处的可见性是多少。首先我们需要创建一个阴影光线,设置起点O为P。未被标准化的方向向量d = L - P,
, 且
=1。如果这个相交对应的t在范围[0,1]内,则看作光线与遮挡体相交。实际上,我们通常设置
且
,ε是一个很小的值。这个调整可以帮助避免由于数值不准确(numerical imprecision)带来的自相交(self-intersection)。如果使用浮点数来表示,P点所在的表面可以只以一个非常小但非零的
值与光线相交。用数学的方式,我们以一个间隔(open interval open啥意思)来忽略点恰好在
和
时的情况。由于浮点精度的限制,因此使用ε软化因子是常见的解决方案。在第六章中可以看到更多有关如何避免自相交问题的讨论。
In implementations using normalized ray directions, we could instead use O = P, L-P d= L-P ,tmin =ε,andtmax =l−ε,wherel=‖L−P‖is the distance to the light source L. Note that this epsilon must be different than the previous epsilon, as t now has a different range.
在使用标准化光线方向的实现中,我们可以使用 和 ,其中 是光源(light source)的距离。注意此处的 不同于上面的 ,因为此时的 已不在同一个范围。
Some renderers use unit-length vectors for all or some ray directions. Doing so allows efficient cosine computations via dot products with other unit vectors, and it can make it easier to reason about the code, in addition to making it more readable. As noted earlier, a unit length means that the ray parameter t can be interpreted as a distance without scaling by the direction vector’s length. However, instanced geometry may be represented using a transformation for each instance. Ray/object intersection then requires transforming the ray into the object’s space, which changes the length of the direction vector. To properly compute t in this new space, this transformed direction should be left unnormalized. In addition, normalization costs a little performance and can be unnecessary, as for shadow rays. Because of these competing benefits, there is no universal recommendation of whether to use unit direction vectors.
一些渲染器对所有或某些光线方向使用单位长度向量。这样做可以通过与其他单位向量的点积进行有效的余弦计算,并且除了使代码更具可读性之外,还可以使代码推理更加容易。如前所述,单位长度意味着光线参数 可以解释为距离,而无需按方向矢量的长度进行缩放。但是,可以为每个实例使用转换来表示实例几何。然后,光线和物体的相交需要将光线转换到物体的空间,从而改变方向矢量的长度。为了在这个新空间中正确地计算 ,这个变换的方向应该不归一化。此外,归一化只需要很少的性能,就象阴影射线一样,可能是不必要的。由于具有这些优势,因此没有关于是否使用单位方向向量的通用建议。
2.3 RAYS IN DXR
This section presents the definition of a ray in DirectX Raytracing [3]. In DXR, a ray is defined by the following structure:
本节介绍DirectX光线追踪[3]中的光线定义。 在DXR中,光线由以下结构定义:
The ray type is handled differently in DXR, where a certain shader program is associated with each different type of ray. To trace a ray with the TraceRay() functioninDXR,aRayDescisneeded.The RayDesc::Originissettotheorigin O of our ray, the RayDesc::Direction is set to the direction d, and the t-interval (RayDesc::TMin and RayDesc::TMax) must be initialized as well. For example, for aneyeray(RayDesc eyeRay)weseteyeRay.TMin = 0.0andeyeRay.TMax = FLT_MAX, which indicates that we are interested in all intersections that are in front of the origin.
在DXR中,不同光线类型的处理方式有所不同,其中某些着色器程序(shader program)与每种不同类型的光线相关联。要使用DXR中的TraceRay
()函数来追踪光线,需要使用一个RayDesc
。将RayDesc :: Originisset
设置为该光线的起点O,将RayDesc :: Direction
设置为方向d,并将
间隔设置为(RayDesc :: TMin和RayDesc :: TMax )
。 例如,对于一个eye ray(RayDesc eyeRay),我们设置eyeRay.TMin = 0.0
和eyeRay.TMax = FLT_MAX
,这表明我们对原点前面的所有交叉点都感兴趣。
2.4 CONCLUSION
This chapter shows how a ray is typically defined and used in a ray tracer, and gave the DXR API’s ray definition as an example. Other ray tracing systems, such as OptiX [1] and the Vulkan ray tracing extension [2], have minor variations. For example, OptiX explicitly defines a ray type, such as a shadow ray. These systems have other commonalities, such as the idea of a ray payload. This is a data structure that can be defined by the user to carry additional information along with the ray that can be accessed and edited by separate shaders or modules. Such data is application specific. At the core, in every rendering system that defines a ray, you will find the ray’s origin, direction, and interval.
本章以DXR API的光线定义为例介绍了通常会如何在光线追踪器(ray tracer)中定义和使用光线。对于其它光线追踪系统,例如OptiX [1]和Vulkan光线追踪扩展[2],都还有一些微小的不同。 例如在OptiX中明确定义了光线的类型,例如阴影光线。这些系统也具有共性,例如光线有效载荷的概念。这是一种可以由用户来定义以包含更多光线相关的信息的数据结构,它们可以被单独的着色器或模块访问和编辑。这类数据是特定于应用程序的。但主要是,在每一种定义了光线的渲染系统中,我们都可以找到光线的起点、方向和间隔。
转载:https://blog.csdn.net/Chen_2018k/article/details/108119461