模板缓冲_模板缓冲以及如何使用它可视化体积相交
模板緩沖
介紹 (Introduction)
The trendy thing in real-time rendering these days is ray-tracing. However, traditional rasterization hasn’t disappeared, and it won’t in the near future. I recommend this blog post on the subject: A hybrid rendering pipeline for realtime rendering: (When) is raytracing worth it?
如今,實時渲染中的流行趨勢是光線追蹤 。 但是,傳統的柵格化還沒有消失,并且在不久的將來也不會消失。 我推薦有關此主題的博客文章: 用于實時渲染的混合渲染管道:(何時)光線跟蹤值得嗎?
I find that one of the most neglected elements in the rasterization pipeline is the Stencil Buffer. To get an idea of how neglected it is, I’ve checked the number of appearances of the stencil buffer in the approximately 1000 pages of “Real-Time Rendering”[1]: it appears just 5 times, and there are no more than 4 paragraphs dedicated to it. At least for me, it’s hard to get my head around the stencil buffer because it’s not fully programmable, so I tend to avoid using it. You can only configure it, and to do so you have to think of Boolean algebra, but in 3D.
我發現柵格化管道中最被忽略的元素之一是模板緩沖區 。 為了了解它是如何被忽略的,我檢查了大約1000頁“實時渲染” [1]中模版緩沖區的出現次數:它僅出現5次,并且不超過專門針對它的4個段落。 至少對我來說,很難完全繞過模板緩沖區,因為它不是完全可編程的,因此我傾向于避免使用它。 您只能對其進行配置,并且必須這樣做,但必須考慮布爾代數,但要使用3D。
This blog post is an attempt to demystify the stencil buffer. I will briefly review the rendering pipeline, to see where the stencil sits, and then explain how the stencil works. I will use an example application in WebGL that we use to detect volume intersections, and explain the steps to convert the algorithm in my head to a tabular format that can be used to configure the stencil.
這篇博客文章試圖揭開模板緩沖區的神秘面紗。 我將簡要回顧渲染管線,以查看模板位于何處,然后解釋模板的工作方式。 我將在WebGL中使用一個示例應用程序,該示例程序用于檢測體積相交,并說明將我頭腦中的算法轉換為可用于配置模具的表格格式的步驟。
柵格化渲染管道 (The Rasterization Rendering Pipeline)
Rasterization Rendering Pipeline in the GPU. Some stages are fully programmable, others are configurable, and others are completely fixed.GPU中的柵格化渲染管線。 一些階段是完全可編程的,其他階段是可配置的,而其他階段則是完全固定的。Virtually every GPU implements a rendering pipeline like the one above. In the middle row I tried to illustrate the transformations that we apply to our models until they become an image on the screen. In the vertex shader, we receive the triangles that make up the surface of our 3D model. Then, our vertex shader will apply a series of matrix multiplications to those triangles to convert from the model space (origin of coordinates centered around the model), to world space (origin of coordinates in the world origin), and then to camera space (origin of coordinates in the camera). Then, we apply a projection transform (perspective or orthographic), so the camera frustum becomes a unit cube. Whatever is outside that unit cube gets clipped, and mapped to screen coordinates. Then the rasterizer converts those triangles into pixels, interpolating color values between vertices. Then we can apply operations per pixel in our pixel shader, and blend the result into the frame buffer that we see on screen, in the merger stage.
實際上,每個GPU都像上面那樣實現渲染管線。 在中間的一行中,我試圖說明我們應用于模型的轉換,直到它們成為屏幕上的圖像為止。 在頂點著色器中,我們接收到構成3D模型表面的三角形。 然后,我們的頂點著色器將對這些三角形應用一系列矩陣乘法,以從模型空間(以模型為中心的坐標原點),世界空間(世界原點坐標的原點),然后到相機空間進行轉換(相機中的坐標原點)。 然后,我們應用投影變換(透視圖或正交投影),使攝像機視錐變成一個單位立方體。 該單元多維數據集之外的任何內容都會被裁剪,并映射到屏幕坐標。 然后,光柵化器將這些三角形轉換為像素,在頂點之間插入顏色值。 然后,在合并階段,我們可以在像素著色器中對每個像素應用操作,并將結果混合到屏幕上看到的幀緩沖區中。
合并階段:混合,Z緩沖區和模具 (The merger stage: blending, Z-buffer, and stencil)
That merger stage does mainly 2 types of operations: blending and discarding pixels. The blending, or Alpha Blending, blends pixel colors of our object with the colors already in the frame buffer based on the alpha value of the texture of the object. The alpha value is typically 8-bit, so there are only 256 possible values. We can also use the alpha value to discard pixels as well, based on a threshold. Pixels with a value smaller than the threshold will be discarded. That’s referred to as alpha masking.
合并階段主要執行兩種類型的操作: 混合和丟棄像素。 blending或Alpha Blending基于對象紋理的alpha值將對象的像素顏色與幀緩沖區中已經存在的顏色進行混合 。 alpha值通常為8位,因此只有256個可能的值。 我們還可以根據閾值使用alpha值丟棄像素。 值小于閾值的像素將被丟棄。 這就是所謂的Alpha遮罩。
Pixels can also be discarded thanks to the Z-buffer. The Z-buffer contains the distance (Z) from the camera to the objects in the scene. Say we have rendered the mountain from the illustration above, and now we try to render a tree that’s behind the mountain. The Z-buffer contains the distance to the camera for every pixel of the mountain. We can compare the Z values of the tree, and discard them if the new Z value is greater than the Z we have already. The tree won’t render. Notice that if we change the rendering order and render the tree first, it will get rendered. However, once we draw the mountain the Z-test won’t fail, so the mountain will be rendered on top. So some pixels will be drawn over several times. That’s what we call the overdraw, which can be used to measure efficiency. Sorting the scene is a way of reducing the overdraw.
借助Z緩沖區,像素也可以被丟棄。 Z緩沖區包含從攝像機到場景中的對象的距離(Z)。 假設我們已根據上圖繪制了山峰,現在我們嘗試繪制山峰后面的一棵樹。 Z緩沖區包含山的每個像素到相機的距離。 我們可以比較樹的Z值,如果新的Z值大于我們已有的Z,則將其丟棄。 樹不會渲染。 注意,如果我們更改渲染順序并首先渲染樹,則它將被渲染。 但是,一旦繪制了山峰,Z檢驗就不會失敗,因此山峰將呈現在頂部。 因此一些像素將被繪制多次。 這就是我們所說的透支 ,可以用來衡量效率。 對場景進行排序是減少透支的一種方法。
Lastly, we can use the stencil buffer to discard pixels as well. The stencil buffer is typically an 8-bit buffer, so 256 distinct values are possible. In its simplest form, it can be used as an alpha mask. Say that we are seeing the mountain through a window, and we want to hide everything else. We can mark the pixels that belong to the window with an arbitrary number in the stencil buffer, e.g. a 1 signifies a pixel from the window, and then we configure the stencil buffer to discard everything that it’s not labeled as “window”. When combined with the Z-buffer, the stencil buffer can be used as a powerful tool to create volumetric effects, as we will see in the example later on.
最后,我們也可以使用模板緩沖區來丟棄像素。 模板緩沖區通常是8位緩沖區,因此可以有256個不同的值。 以其最簡單的形式,它可用作alpha蒙版。 假設我們正在透過窗戶看到這座山,而我們想隱藏其他所有東西。 我們可以在模板緩沖區中使用任意數字標記屬于窗口的像素,例如1表示窗口中的像素,然后配置模板緩沖區以丟棄所有未標記為“窗口”的內容。 當與Z緩沖區結合使用時,模版緩沖區可以用作創建體積效果的強大工具,我們將在后面的示例中看到。
模板緩沖區配置 (Stencil buffer configuration)
To configure the stencil buffer we have 3 types of settings:
要配置模板緩沖區,我們有3種類型的設置:
Comparison functions. This is the function used to decide whether to discard a pixel or not. For instance, “greater than”, or “less than”. See: available stencil functions in WebGL.
比較功能 。 這是用于決定是否丟棄像素的功能。 例如,“大于”或“小于”。 請參閱: WebGL中可用的模具功能 。
Mask values. These are 8-bit binary masks. There are 3 types of masks: reference, read mask, and write mask. In WebGL, the reference and read mask are set with the stencil function, whereas the write mask is set with the stencil mask. The reference and read mask are used in conjunction with the comparison function. For instance, if the comparison is set to “greater than”, the stencil test will pass if (refMask & readMask) > (stencil & readMask), where "&" is a bitwise binary AND operation. The write mask gets applied to what we write to the stencil buffer if the test passes and we decide to update it.
掩碼值 。 這些是8位二進制掩碼。 屏蔽有3種類型:參考屏蔽,讀取屏蔽和寫入屏蔽。 在WebGL中,參考和讀取掩碼是通過模板功能設置的,而寫掩碼是通過模板掩碼設置的。 參考和讀取掩碼與比較功能結合使用。 例如,如果將比較設置為“大于”,則如果(refMask & readMask) > (stencil & readMask) (其中“&”是按位二進制AND運算(refMask & readMask) > (stencil & readMask) ,則模板測試將通過。 如果測試通過并且我們決定更新它,則將寫掩碼應用于我們寫入模板緩沖區的內容。
Stencil operations. These are actions that can be configured in case of a successful or a failed test. You can do things like keep the current stencil value, replace it, or increment it. See: available stencil ops in WebGL. The actions can be configured for the 3 following conditions:
模具操作 。 這些是可以在測試成功或失敗的情況下配置的操作。 您可以執行諸如保留當前模板值,替換它或增加它的操作。 請參閱: WebGL中可用的模具操作 。 可以針對以下三種情況配置操作:
Writing it down as one big logical operation, for each pixel, the new value of the stencil buffer can be computed as follows:
將其記為一項大的邏輯運算,對于每個像素,可以如下計算模板緩沖區的新值:
if (refMask & readMask) Comparison (stencil & readMask):It does sound very abstract, doesn’t it? How do all these logical operations become something useful? I hope with the example in the next section you learn how to configure the stencil.
聽起來很抽象,不是嗎? 所有這些邏輯運算如何變得有用呢? 我希望通過下一節中的示例學習如何配置模板。
使用模板緩沖區可視化體積相交 (Visualizing volume intersections with the stencil buffer)
Visualization of cube intersections and back faces立方體相交和背面的可視化問題定義 (Problem definition)
Let start with the problem definition. We want to visualize the volume intersections in a mesh, and any open areas of the mesh. This is a quick way of visually detecting if a mesh is watertight, i.e. the mesh contains no holes and it’s clearly defined inside. Holes are easy to visualize if we render the object in 2 passes. A vertex has 2 sides, front and back. Whether a side is front or back is decided by an arbitrary vertex winding order (it can be configured). When rendering, back faces are usually not rendered, but this culling is one of those things that can be configured in the render pipeline. So we can do a first pass where we render only the back faces in a bright green color, and then a normal pass where we render the rest. If we see green on screen that means that the mesh has a hole in there.
讓我們從問題定義開始。 我們要可視化網格中的體積相交以及網格的任何開放區域。 這是一種直觀地檢測網格是否防水的快速方法,即該網格不包含任何Kong,并且在內部明確定義。 如果我們通過2次渲染對象,則Kong很容易可視化。 一個頂點有2個面,正面和背面。 側面是正面還是背面取決于任意頂點纏繞順序(可以配置)。 渲染時,通常不渲染背面,但是這種剔除是可以在渲染管道中配置的那些東西之一。 因此,我們可以進行第一遍,僅以明亮的綠色渲染背面,然后進行普通遍,以渲染其余部分。 如果我們在屏幕上看到綠色,則表示網格中有一個Kong。
體交的配置 (Configuration for volume intersection)
For the volume intersection things get a bit more complicated. I know that the stencil should be useful in this, but how do we set it up? I always start writing down on the white board all the examples of triangle layerings that I can think of. Then, I know that in the end I want a stencil mask that marks exactly the intersection area in the given example. What operations can take me there? There are multiple. The challenge is to find one that works for all the examples you’ve written down. There must be a better way to draw this, but this is what I got:
對于體積相交,情況變得更加復雜。 我知道模版應該在其中有用,但是我們如何設置它呢? 我總是開始在白板上寫下我能想到的所有三角形分層示例。 然后,我知道最后我需要一個模版遮罩,以精確標記給定示例中的相交區域。 什么手術可以帶我到那里? 有多個。 面臨的挑戰是找到一個適用于您編寫的所有示例的示例。 必須有更好的方法來繪制此圖形,但這就是我得到的:
Stencil Configuration by Example. We are trying to figure out a way to create mask for areas of volume intersections.模板配置示例。 我們正在嘗試找出一種為體積相交區域創建蒙版的方法。Then, once I think I have all the cases I need, I try to fill in a table with all the stencil configuration per render pass. From the picture above, you can see that the way I designed it, I’m going to need at least 3 passes:
然后,一旦我認為我有所有需要的情況,便嘗試使用每個渲染遍歷在表格中填寫所有模具配置。 從上面的圖片中,您可以看到我的設計方式,我至少需要3次通過:
- one to render the back faces, where I count the number of back-facing polygons; 一個用于渲染背面,我在其中計算背面多邊形的數量;
- a second pass to render the front faces and decrease the counter if the z-test fails. We will avoid writing onto the Z-buffer so we can distinguish those 2 circled cases (where front-face B is rendered before front-face A). Because during the back pass we update the Z-buffer, the Z-buffer before starting the 2nd pass contains the z value of the back face closer to the camera. In the non-intersecting example, the order doesn’t matter, because whether the Z-buffer contains the z of the back-face or the z of B, we can detect a z-test failure when trying to draw A and decrease the counter. But in the intersecting example, if we draw face B first and update the Z-buffer, when trying to draw face A the z-test will fail and we will wrongly decrease the counter. To solve this without having to sort the geometry, we will stop all Z-buffer updates (Z-write off) during this pass. 如果z測試失敗,則進行第二次渲染以渲染正面并減少計數器。 我們將避免寫入Z緩沖區,因此我們可以區分這2個帶圓圈的情況(正面B在正面A之前渲染)。 因為在后退過程中我們更新了Z緩沖區,所以在開始第二遍之前的Z緩沖區包含了更靠近相機的背面的z值。 在非相交的示例中,順序無關緊要,因為Z緩沖區是包含背面的z還是B的z,我們在嘗試繪制A并減小A時可以檢測到z檢驗失敗。計數器。 但是在相交的示例中,如果我們首先繪制面B并更新Z緩沖區,則在嘗試繪制面A時z測試將失敗并且我們將錯誤地減少計數器。 要解決此問題而不必對幾何進行排序,我們將在此過程中停止所有Z緩沖區更新(取消Z寫入)。
- a third pass to create a binary mask with the intersection area. 第三遍創建具有交叉區域的二進制蒙版。
- I can add an optional 4th pass to render the lighting of the non-intersecting volumes. 我可以添加可選的第4遍以渲染非相交體積的照明。
Here’s my final stencil table:
這是我最終的模具表:
If you want to check how that translates into code, check this pull request in GitHub: self-intersections for WebGL Model Viewer.
如果要檢查如何將其轉換為代碼,請在GitHub中檢查此拉取請求: WebGL Model Viewer的自相交 。
可視化結果 (Visualization results)
Here’s a video of the WebGL Model Viewer in action:
這是運行中的WebGL Model Viewer的視頻:
The green areas are back faces, so holes in the mesh, whereas the red areas are the volume intersections. One application of this is to help us spot issues in poses in our avatars. If part of the arm intersects with the chest, we will have problems when trying to dress the avatar with a shirt, because the sleeve will also try to enter the chest and the cloth simulation will struggle. See example below:
綠色區域是背面,因此網格中有Kong,而紅色區域是體積相交。 一種應用是幫助我們發現化身中姿勢中的問題。 如果手臂的一部分與胸部相交,則在嘗試使用襯衫為化身打扮時會遇到問題,因為袖子還會嘗試進入胸部,而布料模擬會很困難。 請參見下面的示例:
The visualization of volume intersections (middle) can warn us about future problems in cloth simulation (right).體積相交的可視化(中間)可以警告我們布料模擬中的未來問題(右)。結論 (Conclusion)
Rasterization is still the most used rendering pipeline in real time graphics. Inside the rasterizer, the Stencil Buffer seems to be the ugly duckling no one wants to hang around with, perhaps only reserved to big graphic gurus. I have showed you with a practical example that we can use the stencil buffer to visualize volume intersections in real time, and that the stencil is not as scary if we describe the problem with examples and in tabular form.
柵格化仍然是實時圖形中最常用的渲染管道。 在光柵化器內部,“模板緩沖區”似乎是一個丑陋的小鴨,沒人愿意與它混在一起,也許只保留給大型圖形大師使用。 我已經通過一個實際示例向您展示了我們可以使用模板緩沖區實時顯示體積相交,并且如果我們以示例和表格形式描述問題,模板并不那么令人恐懼。
Visualizing volume intersections in real time has a practical application for us. When we author poses for our avatars, we can immediately see if a pose will end up having cloth simulation problems, and correct the limb position accordingly.
實時可視化體積相交對我們來說具有實際應用。 當我們為化身創作姿勢時,我們可以立即查看姿勢是否最終會遇到布料模擬問題,并相應地校正肢體位置。
For more applications of the stencil buffer, check the “Real-Time Rendering” book [1], and the Wikipedia article.
有關模板緩沖區的更多應用,請查看“實時渲染”一書[1]和Wikipedia文章 。
Originally published at https://tech.metail.com on July 3, 2020.
最初于 2020年7月3日 在 https://tech.metail.com 上 發布 。
翻譯自: https://medium.com/real-time-rendering/the-stencil-buffer-and-how-to-use-it-to-visualize-volume-intersections-34dc1d205ebc
模板緩沖
總結
以上是生活随笔為你收集整理的模板缓冲_模板缓冲以及如何使用它可视化体积相交的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 高性能MySQL 第3版(中文)pdf
- 下一篇: java面试宝典pdf,给大家安排上!