Real-Time Rendering——7.3 Shadow Volumes阴影体积

Presented by Heidmann in 1991 [701], a method based on Crow’s shadow volumes [311] can cast shadows onto arbitrary objects by clever use of the stencil buffer. It can be used on any GPU, as the only requirement is a stencil buffer. It is not image based (unlike the shadow map algorithm described next) and so avoids sampling problems,thus producing correct sharp shadows everywhere. This can sometimes be a disadvantage.For example, a character’s clothing may have folds that give thin, hard shadows that alias badly. Shadow volumes are rarely used today, due to their unpredictable cost [1599]. We give the algorithm a brief description here, as it illustrates some important principles and research based on these continues.

Heidmann于1991年[701]提出了一种基于乌鸦阴影体积[311]的方法,通过巧妙使用模板缓冲区,可以将阴影投射到任意对象上。它可以在任何GPU上使用,因为唯一的要求是一个模板缓冲区。它不是基于图像的(不像下面描述的阴影贴图算法),因此避免了采样问题,从而在任何地方产生正确的清晰阴影。这有时可能是一个缺点。例如,一个角色的衣服可能有褶皱,产生的阴影又细又硬,混叠得很糟糕。由于其不可预测的成本,现在很少使用卷影[1599]。我们在这里给这个算法一个简短的描述,因为它说明了一些重要的原理和基于这些继续的研究。

To begin, imagine a point and a triangle. Extending the lines from a point through the vertices of a triangle to infinity yields an infinite three-sided pyramid. The part under the triangle, i.e., the part that does not include the point, is a truncated infinite pyramid, and the upper part is simply a pyramid. This is illustrated in Figure 7.7. Now imagine that the point is actually a point light source. Then, any part of an object that is inside the volume of the truncated pyramid (under the triangle) is in shadow. This volume is called a shadow volume.

首先,想象一个点和一个三角形。从一个点通过三角形的顶点延伸直线到无限远会产生一个无限长的三边棱锥。三角形下面的部分,即不包括该点的部分,是一个截顶的无限金字塔,上面的部分只是一个金字塔。这如图7.7所示。现在想象这个点实际上是一个点光源。然后,位于截棱锥体(三角形下方)内部的对象的任何部分都处于阴影中。这个卷称为阴影卷。

Figure 7.7. Left: the lines from a point light are extended through the vertices of a triangle to form an infinite pyramid. Right: the upper part is a pyramid, and the lower part is an infinite truncated pyramid, also called the shadow volume. All geometry that is inside the shadow volume is in shadow. 

图7.7。左图:点光源发出的光线延伸穿过三角形的顶点,形成一个无限的金字塔。右图:上半部分是金字塔,下半部分是无限截棱锥,也叫阴影体。阴影体积内的所有几何体都在阴影中。

Say we view some scene and follow a ray from the eye through a pixel until the ray hits the object to be displayed on screen. While the ray is on its way to this object, we increment a counter each time it crosses a face of the shadow volume that is frontfacing (i.e., facing toward the viewer). Thus, the counter is incremented each time the ray goes into shadow. In the same manner, we decrement the same counter each time the ray crosses a backfacing face of the truncated pyramid. The ray is then going out of a shadow. We proceed, incrementing and decrementing the counter until the ray hits the object that is to be displayed at that pixel. If the counter is greater than zero, then that pixel is in shadow; otherwise it is not. This principle also works when there is more than one triangle that casts shadows. See Figure 7.8.

比方说,我们观看某个场景,跟随眼睛发出的光线穿过一个像素,直到光线碰到屏幕上要显示的对象。当光线在到达这个物体的途中时,每当它穿过阴影体的正面(即,面向观察者)时,我们就增加一个计数器。因此,每次光线进入阴影时,计数器都会增加。以同样的方式,每当光线穿过截顶棱锥的背面时,我们减少相同的计数器。然后光线从阴影中消失。我们继续进行,递增和递减计数器,直到射线击中要在该像素上显示的对象。如果计数器大于零,则该像素处于阴影中;否则就不是。当有不止一个三角形投射阴影时,这个原则也适用。参见图7.8。

Figure 7.8. A two-dimensional side view of counting shadow-volume crossings using two different counting methods. In z-pass volume counting, the count is incremented as a ray passes through a frontfacing triangle of a shadow volume and decremented on leaving through a backfacing triangle. So, at point A, the ray enters two shadow volumes for +2, then leaves two volumes, leaving a net count of zero, so the point is in light. In z-fail volume counting, the count starts beyond the surface (these counts are shown in italics). For the ray at point B, the z-pass method gives a +2 count by passing through two frontfacing triangles, and the z-fail gives the same count by passing through two backfacing triangles. Point C shows how z-fail shadow volumes must be capped. The ray starting from point C first hits a frontfacing triangle, giving −1. It then exits two shadow volumes (through their endcaps, necessary for this method to work properly), giving a net count of +1. The count is not zero, so the point is in shadow. Both methods always give the same count results for all points on the viewed surfaces. 

图7.8。使用两种不同的计数方法计数阴影体积交叉的二维侧视图。在z通道体积计数中,当光线穿过阴影体积的前向三角形时,计数增加,当光线穿过后向三角形时,计数减少。因此,在点A,光线进入两个+2的阴影体积,然后离开两个体积,留下的净计数为零,因此该点在光线中。在z-fail体积计数中,计数从表面之外开始(这些计数以斜体显示)。对于B点的光线,z-pass方法通过穿过两个面向前的三角形给出+2计数,z-fail通过穿过两个面向后的三角形给出相同的计数。C点显示了z-fail阴影卷必须如何封顶。从C点开始的射线首先碰到一个朝前的三角形,给出1。然后,它退出两个阴影体(通过它们的端盖,这是该方法正常工作所必需的),给出净计数+1。计数不为零,所以点在阴影中。这两种方法对于所观察表面上的所有点总是给出相同的计数结果。

Doing this with rays is time consuming. But there is a much smarter solution [701]: A stencil buffer can do the counting for us. First, the stencil buffer is cleared. Second, the whole scene is drawn into the framebuffer with only the color of the unlit material used, to get these shading components in the color buffer and the depth information into the z-buffer. Third, z-buffer updates and writing to the color buffer are turned off (though z-buffer testing is still done), and then the frontfacing triangles of the shadow volumes are drawn. During this process, the stencil operation is set to increment the values in the stencil buffer wherever a triangle is drawn. Fourth, another pass is done with the stencil buffer, this time drawing only the backfacing triangles of the shadow volumes. For this pass, the values in the stencil buffer are decremented when the triangles are drawn. Incrementing and decrementing are done only when the pixels of the rendered shadow-volume face are visible (i.e., not hidden by any real geometry). At this point the stencil buffer holds the state of shadowing for every pixel. Finally, the whole scene is rendered again, this time with only the components of the active materials that are affected by the light, and displayed only where the value in the stencil buffer is 0. A value of 0 indicates that the ray has gone out of shadow as many times as it has gone into a shadow volume—i.e., this location is illuminated by the light.

绘制三角形。只有当渲染的阴影体表面的像素是可见的(即,没有被任何真实的几何图形隐藏)时,才进行递增和递减。此时,模板缓冲区保存每个像素的阴影状态。最后,再次渲染整个场景,这一次仅使用受灯光影响的活动材质的组件,并且仅在模板缓冲区中的值为0时显示。值为0表示光线离开阴影的次数与进入阴影体积的次数相同,即该位置被灯光照亮。

This counting method is the basic idea behind shadow volumes. An example of shadows generated by the shadow volume algorithm is shown in Figure 7.9. There are efficient ways to implement the algorithm in a single pass [1514]. However, counting problems will occur when an object penetrates the camera’s near plane. The solution, called z-fail, involves counting the crossings hidden behind visible surfaces instead of in front [450, 775]. A brief summary of this alternative is shown in Figure 7.8.

这种计数方法是阴影体积背后的基本思想。图7.9显示了一个由阴影体积算法生成的阴影的例子。有一些有效的方法可以在一次通过中实现该算法[1514]。但是,当物体穿透相机的近平面时,会出现计数问题。被称为z-fail的解决方案包括计算隐藏在可见表面后面而不是前面的交叉点。图7.8显示了这种替代方案的简要总结。

Figure 7.9. Shadow volumes. On the left, a character casts a shadow. On the right, the extruded triangles of the model are shown. (Images from Microsoft SDK [1208] sample “ShadowVolume.”) 

图7.9。阴影体积。在左边,一个角色投下了阴影。在右侧,显示了模型的拉伸三角形。(图片来自微软SDK [1208]示例“阴影卷”)

Creating quadrilaterals for every triangle creates a huge amount of overdraw. That is, each triangle will create three quadrilaterals that must be rendered. A sphere made of a thousand triangles creates three thousand quadrilaterals, and each of those quadrilaterals may span the screen. One solution is to draw only those quadrilaterals along the silhouette edges of the object, e.g., our sphere may have only fifty silhouette edges, so only fifty quadrilaterals are needed. The geometry shader can be used to automatically generate such silhouette edges [1702]. Culling and clamping techniques can also be used to lower fill costs [1061].

为每个三角形创建四边形会产生大量的透支。也就是说,每个三角形将创建三个必须渲染的四边形。一个由一千个三角形组成的球体产生了三千个四边形,而这些四边形中的每一个都可以跨越整个屏幕。一种解决方案是只沿着对象的轮廓边缘绘制那些四边形,例如,我们的球体可能只有五十个轮廓边缘,因此只需要五十个四边形。几何着色器可用于自动生成这样的轮廓边缘[1702]。剔除和夹紧技术也可用于降低填充成本[1061]。

However, the shadow volume algorithm still has a terrible drawback: extreme variability. Imagine a single, small triangle in view. If the camera and the light are in exactly the same position, the shadow-volume cost is minimal. The quadrilaterals formed will not cover any pixels as they are edge-on to the view. Only the triangle itself matters. Say the viewer now orbits around the triangle, keeping it in view. As the camera moves away from the light source, the shadow-volume quadrilaterals will become more visible and cover more of the screen, causing more computation to occur. If the viewer should happen to move into the shadow of the triangle, the shadow volume will entirely fill the screen, costing a considerable amount of time to evaluate compared to our original view. This variability is what makes shadow volumes unusable in interactive applications where a consistent frame rate is important. Viewing toward the light can cause huge, unpredictable jumps in the cost of the algorithm, as can other scenarios.

然而,阴影体算法仍然有一个可怕的缺点:极端的可变性。想象一个单独的小三角形。如果摄影机和灯光在完全相同的位置,阴影体的成本是最小的。形成的四边形不会覆盖任何像素,因为它们是视图的边缘。只有三角形本身是重要的。假设观察者现在围绕三角形旋转,保持它在视野中。随着相机远离光源,阴影体四边形将变得更加可见,并覆盖更多的屏幕,从而导致更多的计算发生。如果观察者碰巧移动到三角形的阴影中,阴影体积将完全充满屏幕,与我们的原始视图相比,花费相当多的时间来评估。这种可变性使得阴影体在交互式应用中不可用,在交互式应用中,一致的帧速率是重要的。向光看可能会导致算法成本的巨大、不可预测的跳跃,其他场景也是如此。

For these reasons shadow volumes have been for the most part abandoned by appli- cations. However, given the continuing evolution of new and different ways to access data on the GPU, and the clever repurposing of such functionality by researchers, shadow volumes may someday come back into general use. For example, Sintorn et al. [1648] give an overview of shadow-volume algorithms that improve efficiency and propose their own hierarchical acceleration structure.

由于这些原因,阴影体在很大程度上已被应用所抛弃。然而,鉴于在GPU上访问数据的新方法和不同方法的不断发展,以及研究人员对这种功能的巧妙重新利用,阴影卷可能有一天会重新投入使用。例如,Sintorn等人[1648]给出了提高效率的阴影体算法的概述,并提出了他们自己的分层加速结构。

The next algorithm presented, shadow mapping, has a much more predictable cost and is well suited to the GPU, and so forms the basis for shadow generation in many applications.

提出的下一个算法,阴影映射,具有更可预测的成本,并且非常适合GPU,因此在许多应用中形成了阴影生成的基础。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

椰子糖莫莫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值