您的位置:首页 > Web前端

翻译 shaderX2 Deferred Shading with Multiple Render Target

2010-07-12 11:32 483 查看
来自shaderX2 Deferred Shading with Multiple Render Target 中间一段.

延时光照上篇只是简单实现,他的麻烦在于你渲染的流程改动较大.很多原有的技术需要你亲自去重新实现.这篇文章分析了关于延时渲染支持的相关技术与解决方案.

翻译不好,只是自己学习用,附上原文.欢迎指正

下一篇继续翻译后面,主要讲解deferred shading的优化.

Advanced Shading Passes
The simple lighting pass shown above is only the beginning of what can be achieved with deferred shading. Because shading passes are no longer geometry-dependent and only applied to visible geometry, their utilization is optimal.This performance saving can be used to implement more complex shaders or effects.

高级光照shader

上边简单的光照shader只是实现延迟光照的基本.由于shader的pass不再是几何依赖并且只用于可见的几何体.他们的利用时优化的.此性能节省可以用于实现跟复杂的shaders或者效果.

Better Lighting
A “real” specular calculation based on the camera reflection vector is straightforward to implement, since both the pixel and camera position are known. That is, instead of calculating(H .N) ,the light reflection vector around the normal (given by R = 2 X (N. L) X N - L) can be calculated and used in a dot product operation with the view vector. The specular properties of each pixel could be stored in the attribute buffer (e.g., using the alpha of the diffuse texture in our implementation) and used as the power of the specular calculation. Different types of light can be implemented, from directional and point lights to spotlights or custom-shaped lights (light volumes are discussed later in this article). More complex light attenuation models can be implemented using math instructions inside the pixel shader instead of a texture lookup. Light maps can be used for custom-shaped lights or when there is a need to restrict light contribution to a defined area. The demo on the CD offers some implementations of the effects mentioned above.

更好的光照

一个真实的镜面反射计算基于摄像机的反射向量是可以简单实现的因为像素和摄像机的位置都知道.那样的话,取代计算(H.N),光的反射向量通过法线向量(通过R=2 X (N . L) X N- L)可以计算出来并且用于同视线(view)向量点乘计算.镜面反射光的每个像素属性就可以被存储在属性缓冲里面(在我们程序里通过使用漫反射贴图的alpha通道),用于镜面高光的参数的计算.

不同类型的灯光可以被实现.从方向光和点光源到聚光灯或者自定义形式的灯光(体积光在后面将会被讨论),跟多复杂的灯光衰减模型可以再ps里面用数学的方式去实现从而代替纹理查找.光照图可以用于自定义形式的光照或者当在某个某个地方定义限制光照的贡献

Extended Attribute Buffer
Providing memory storage and bandwidth are not limiting factors (see later in this article for a discussion about bandwidth considerations), the attribute buffer can be used to store additional data relevant to the scene properties, allowing more complex effects to be implemented later on in the shading passes. In the example shown in this article, the material properties are simply approximated to a diffuse color issued from each model’s diffuse map. Other properties, like specular maps, specular power maps, detail maps, tangent vectors for anisotropic lighting, a Fresnel term, BRDF data, etc., could be stored in the attribute buffer. There are potentially so many material properties to store that there might not be enough space to accommodate them. Various tricks can be used to effectively compress as much data as possible in a reasonably allocated MRT space, like storing material IDs, using volume textures, etc.

扩展属性缓冲

假设内存和带宽不是限制因素的话(这篇问斩的后面会讨论到带宽),属性缓冲可以用来存储额外的数据,例如场景属性之类,可以允许在后面的shader过程中实现更复杂的效果.

在这篇文章的例子里面,材质的属性石很简单大略的从每个模型的漫反射贴图获得漫反射颜色.其他的属性,例如镜面反射贴图,镜面高光贴图,细节图,切线向量的各向异性照明,一个fresnel term,brdf等等.都可以存储在属性缓存中.有个问题是这么多的材质属性去存储,但是没有足够的空间去容纳他们.很多办法用来有效的压缩尽可能多的书籍进入MRT的控件.例如存储材质的id,使用体积纹理等等.

Shadows
Deferred shading is fully compatible with the rendering of shadows within the scene. Let’s consider stencil shadows (as used in the demo). In the traditional rendering case (e.g., Doom III-style rendering), each shadow-casting light requires the scene geometry to be submitted (on top of shadow volumes) so that only non-shadowed areas are affected by the lighting calculations. When a high number of lights are used, the number of geometry passes quickly becomes overwhelming. With deferred shading, only the shadow volumes and a full-screen quad per
light are required:
Building pass
For each light:
Clear stencil buffer, disable color writes

Render shadow volumes onto stencil buffer
Enable color writes, stencil test passes for non-shadowed areas
Light pass
Shadow maps are also compatible with deferred shading. Since the world space pixel position can be stored in the attribute buffer, the distance from the pixel to the current light can be calculated in the shading pass. It can then be compared to the depth value in the shadow map to determine if the pixel is in shadow or not. This technique is sometimes referred to as forward shadow mapping.

阴影

延时光照完全支持场景内的实时阴影

让我们看看模板阴影.在传统的绘制其概况.每个阴影投掷的灯光需要场景几何被提交(在阴影体的最上面).所以只有没有阴影的区域被光照计算所影响.当大量的灯光使用的时候,几何的pass变得不可预计.通过延时光站,只有阴影体和一个对于每个灯光的全屏的四边形:

Building pass

For each light:

Clear stencil buffer, disable color writes

Render shadow volumes onto stencil buffer

Enable color writes, stencil test pass for non-shadowed areas

Light pass

Shadowmap 也是可以和延时光照并存的.因为世界空间的像素位置是存在属性缓冲中的,像素与当前的光源的位置是可以再shader中计算出来的,它可以再shadowmap里面跟深度进行比较来决定哪个像素在阴影里面哪个不再.这种技术有时被称为正向阴影映射。

Higher Color Range
DirectX 9 does not allow blending into floating-point render targets. Because of this limitation, alpha blending cannot be used to accumulate high dynamic range lighting calculation results into a destination frame buffer in float format. With fixed-point render targets, color channels are automatically clamped to 1.0 during the blending process, and so if a higher color range is not needed, it is more economical and straightforward to blend all shading contributions into a fixed-point frame buffer. High color range effects, however, require an alternative solution. The most obvious workaround to this limitation is to ignore the hardware blending capabilities and perform alpha blending on the pixel shader manually. The idea is to alternate between two floating-point render targets; one contains the current contents of all shading contributions prior to the current pass and is set as a texture input to the pixel shader, while the other is set as the destination render target and receives the new color values updated with the contributions of the current pass.

High Color Range

DX9不支持浮点render target混合.由于这个限制,在浮点格式下alpha混合不能去用做积累高动态范围光照的计算的结果作为目的缓冲.通过使用顶点render target,颜色通道会自动的被裁减到1.0在混合过程中.所以如果高范围的颜色不需要,可以节约并且简单的混合所有的shader的贡献在定点帧缓冲.高范围颜色效果需要不同寻常的解决方式.

最明显的解决这个限制的是忽略硬件混合功能,手动执行alhpa混合在ps里面.这种想法交替两张浮点render target;在当前pass, 一张包含之前的所有的shader贡献的内容,并且作为一张纹理输入pixel shader.另一张作为目标render target,接受新的颜色值并且更新当前pass的贡献值.

Translucency
In traditional rendering, alpha-blended polygons require a rendering pass of their own. With deferred shading, alpha polygons requiring shading (e.g., stained-glass objects) also need separate processing, although punch-through polygons (i.e., alpha-tested) can be sent with all other opaque triangles during the building pass.
This is because the attribute buffer can only store properties for a single pixel; thus, any translucent pixels rendered on top of these would need to be stored elsewhere. Unless additive blending is used, real translucent pixels (using an order-dependent blending mode like SRCALPHA-INVSRCALPHA) need to be blended with the back buffer only once to avoid repeated contributions from themselves. Hence, all shading passes need to be performed on the translucent pixels before any blending with the background takes place. Another problem is overlapping translucency; any translucent pixel rendered on top of a previously rendered translucent pixel will need to take into account the new pixel color at this location (i.e., resulting from the previous blending). These two points are of paramount importance, since ignoring them can cause visual errors in the resulting render. Unfortunately, there is no easy way to overcome these problems. For a real-time application relying on performance, the best idea is probably to avoid using translucent objects that require lighting (light-independent translucent objects like explosions, laser beams, smoke, etc., are unaffected because they typically do not need to be shaded). One could attempt to concatenate all shading
passes in one large shader and gross-sort the translucent triangles from back to ront using this shader. However, this might not be practical because of the sampler and instruction limits in the pixel shader. Furthermore, this might not be ompatible with some shadowing techniques like stencil buffering. If lit translucent objects are a requirement of your scene and you are prepared to “go all the way,” then a solution is depth peeling (i.e., shading each “layer” of translucency separately before blending it with the frame buffer). In practice the additional memory, performance, and complexity caused by depth peeling do not make it a very attractive solution to the translucency problem inherent in deferred shading.

透明.

传统的渲染,alhpa混合多边形需要一个属于他们自己的单独的渲染pass.对于延时光照,带alpha的多边形需要进行shader,也需要单独的一个过程,尽管punch-through 多边形可以和其他所有不透明的三角形一起被发送到建立通路阶段.这是因为属性缓冲只能为单独一个像素存贮属性.因此,这些顶部的呈现任何半透明的像素将需要存储其他的地方。除非额外添加的混合使用,真正透明的像素(使用一种顺序依赖的混合方式如SRCALPHA-INVSRCALPHA)只会和后备缓冲混合一次以避免自己的重复的贡献.因此,所有的shander通路对于透明像素的执行必须在任何同后备缓冲混合之前.另一个问题是透明重叠;任何一个透明的像素绘制在之前的透明像素之上的话都要考虑到新的像素的颜色.(结果来自原先的混合).这两点是至关重要的.如果忽略他们将引起最后的渲染错误.

不幸运的是,没有简单的方法可以解决这些问题.对于一个实时渲染的应用程序是注重性能的,最好的方法可能是避免使用需要光照的透明物体(光照无关的透明物体例如鲍照了,激光束,烟等等,他们不收影响,因为他们不需要).一种方案是尝试连接所有的shader通路在一个大的shader里面并且透明物体简单由后到前排序在shader里面.但是这不现实,因为由于在ps里面采样和指令限制.并且这样可能不能和阴影技术很好的结合起来例如模板缓冲.如果光照所有透明物体时你的项目必须的,并且你愿意实现.一个解决方案 depth peeling(对每个透明的层单独进行shader,在混合帧缓冲之前).在实际,额外的内存,性能和复杂度,对于这些从延时光照带来的透明问题,depth peeling解觉得不是很完美 .
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: