GPU Pro 2 ------ Volume Decals

花了$60买了正版的GPU Pro2。坚持每天学一点。

边学习边翻译,希望也能对别人有些益处。从Volume Decals 开始,可以从Emil Persson 的官网上下到源代码 http://www.humus.name/index.php?page=3D&ID=83


Volume Decals

                           Emil Persson

5.1 介绍

贴花通常应用于放置在场景几何体面上的贴图。在大部分情况下,这个应用都表现的很好。用贴图四边形来做贴花会造成Z-fighting的问题。在下面的几何体可能不平坦,造成贴花就绘制在了几向体的下面。在边缘处,贴花也有可能出现悬挂的情况。解决这个问题通常的办法是对贴花引入裁剪或者在这种情况下就不做贴花。将贴花合适的贴在任意的模型上需要很复杂的代码,必须要取得模型的顶点。在PC上意味着如果要取得很好的性能,就必须把模型几何体信息拷贝一份到内存中。有一个典型的例子,向一块石头射击,贴花可能没有跟对齐中心。这篇文章用体积贴花投影到场景几何体上的方法解决了所有的问题,这里面用到了深度缓存。


5.2 体积贴花

5.2.1 找到场景坐标

这个技术的想法是在选中的区域把贴花当成一个体积来渲染。任何一种凸的几何体都可以,但一般都用球或者盒子。通过采样深度缓存,fragment shader 计算在下面的几何体的位置。可以通过下面的方法实现:

// texCoord is the pixel's normalized screen position
float depth = DepthTex.Sample(Filter, texCoord);
float4 scrPos = float4(texCoord, depth, 1.0);
float4 wPos = mul(scrPos, ScreenToWorld);

图 5.1 贴花实例

float3 pos = wPos.xyz /wPos.w;
// pos now contains pixel position in world space

ScreenToWorld 矩阵是一个复合矩阵,包含了两个转换:从屏幕坐标系到裁剪坐标系,从裁剪坐标系到世界坐标系。从世界坐标到裁剪坐标是由ViewProjection矩阵完成的,所以这里要用这个矩阵的逆。裁剪空间范围x和y是从-1到1,然而贴图坐标是从0到1,所以我们需要一个对齐的操作。由以下的代码完成:

float4 ScaleToWorld = Scale(2, -2, 1) * Tranlate(-1, 1, 0) * Inverse(ViewProj);

我们感兴趣的是体积贴花和这个局部位置的关系。这个局部位置会被当成贴图坐标去采样一个体积贴花。因为这个贴花是个体积贴图,它会非常好的包裹着非连续性的特殊的图形(图5.2)。为了给每一个贴花唯一表现,可以给这个矩阵加一个随机的旋转。可以通过下面来构造:


float4 ScreenToLocal = Scale(2, -2, 1) * Translate(-1, 1, 0) * Inverse(ViewProj) * DecalTranslation * DecalScale * DecalRotation;

全部的fragment shader如下:

Texture2D<float> DepthTex;
SamplerState DepthFilter;

Texture3D<float4> DecalTex;
SamplerState DecalFilter;

cbuffer Constants
{
    float4x4 ScreenToLocal;
    float2 PixelSize;
};

float4 main(PsIn in) : SV_Target
{
    // Compute normalized screen position
    float2 texCoord = In.Position.xy * PixelSize;

    // Comput local position of scene geometry
    float depth = DepthTex.Sample(DepthFilter, texCoord);
    float4 scrPos = float4(texCoord, depth, 1.0f);
    float4 wPos = mul(scrPos, ScreenToLocal);

    // Sample decal
    float3 coord = wPos.xyz / wPos.w;
    return DecalTex.Sample(DecalFilter, coord);
}

5.2.2 开发和问题

这个系统可以在延迟渲染技术中实现的相当完美。贴花可以在geometry buffer (G-buffer) pass之后渲染,而且还可以将一些diffuse color,specularity color应用上去。这个技术同样适用于预渲染,意味着在贴花中还可以应用光照信息。

在前向渲染系统中,贴花必须在光照计算之后。举例说一些情况,爆炸后的烧焦的样子呀,贴花可以很好的与目标缓存进行试算。更复杂的一些情况是,用alpha 进行混合,常用于子弹打出一个洞,这种情况下,必须考虑到光照。其中一个解决方案是,当渲染时,在shader中的alpha通道中保存所有光照的亮度;在贴花时能将每个颜色通道预乘以alpha,在混合器中与目标透明度相乘以得到较好的效果。这并没有将灯光的颜色考虑在内,但如果灯光是清楚的白色,结果还是很好的。另一个解决办法是利用最近一个灯光的衰减数,不考虑法线。相应的,法线可以从深度缓存中得到,尽管这会很慢。

这种贴花技术有一个问题是,会在体积贴花内的所有的物体上应用上贴花。对于静态物体这没有问题,但如果你有一个巨大的贴花,然后有一些动态的物体在其内移动,这些动态的物体会得到贴花污点在其上面,举个例子,比如之前有一个炸弹在道路上弹了,之后有一个汽车从上面开过。这个问题可以通过在贴花之后渲染动态物体来解决。一个更好的解决办法是按出现的先后顺序去渲染,这样之后移动到贴花上的物体就不会受到贴花的影响。还有一个解决办法,是使用物体的ID号,贴花可以记录会应用贴图的物体。


5.2.3 优化

在一些平台上支持depth-bounds测试,depth-bounds测试会用于提高性能 。在其它一些平台上,动态分支会用于仿真这一功能,通过对比采样的深度缓存和depth-bounds。无论如何,这样Shader会短一些,很大一部分fragment 可以避免做深度测试。在一些情况下,如果不裁剪任何东西会更快一些。

第一部分 几何操作(Geometry Manipulation) 1. 动态GPU地形(Dynamic GPU Terrain) 2. 在GPU上通过镶嵌的带宽高效程序化网格(Bandwidth-Efficient Procedural Meshes in the GPU via Tessellation) 3. 物体碰撞时细分表面的实时形变(Real-Time Deformation of Subdivision Surfaces on Object Collisions) 4. 游戏中的逼真体积爆炸(Realistic Volumetric Explosions in Games)   第二部分 渲染(Rendering) 1. 《神偷》中的下一代渲染技术(Next-Generation Rendering in Thief) 2. 草地渲染和使用LOD的模拟(Grass Rendering and Simulation with LOD) 3. 混合重建抗锯齿(Hybrid Reconstruction Antialiasing) 4. 使用预计算散射的基于物理的云层实时渲染(Real-Time Rendering of Physically Based Clouds Using Precomputed Scattering) 5. 稀疏程序化体渲染(Sparse Procedural Volume Rendering)   第三部分 光照(Lighting) 1. 使用光照链表的实时光照(Real-Time Lighting via Light Linked List) 2. 延迟归一化的辐照度探针(Deferred Normalized Irradiance Probes) 3. 体积雾与光照(Volumetric Fog and Lighting) 4. GPU上基于物理的光照探针(Physically Based Light Probe Generation on GPU) 5. 使用薄片的实时全局光照(Real-Time Global Illumination Using Slices)     第四部分 阴影(Shadows) 1. 实用屏幕空间软阴影(Practical Screen-Space Soft Shadows) 2. 基于分块的全方位阴影(Tile-Based Omnidirectional Shadows) 3. 阴影贴图轮廓的重新矢量化(Shadow Map Silhouette Revectorization)     第五部分 移动设备(Mobile Devices) 1. PowerVR GPU上的混合光线追踪(Hybrid Ray Tracing on a PowerVR GPU2. 实现一个仅有GPU的粒子碰撞系统,使用自适应可伸缩纹理压缩3D纹理和OpenGL ES 3.0(Implementing a GPU-Only Particle-Collision System with ASTC 3D Textures and OpenGL ES 3.0) 3. 针对移动设备的动画角色毛皮(Animated Characters with Shell Fur for Mobile Devices) 4. 移动GPU的高动态范围计算摄影(High Dynamic Range Computational Photography on Mobile GPUs)   第六部分 计算(Compute) 1. 基于计算的分块剔除(Compute-Based Tiled Culling) 2. 在GPU光线追踪器上渲染矢量位移映射表面(Rendering Vector Displacement-Mapped Surfaces in a GPU Ray Tracer) 3. 对体渲染的平滑概率环境光遮蔽(Smooth Probabilistic Ambient Occlusion for Volume Rendering)   第七部分 3D引擎设计(3D Engine Design) 1. 用于快速光线投射操作的分块线性二元方格(Block-Wise Linear Binary Grids for Fast Ray-Casting Operations) 2. 采用Shader Shaker基的于语义的着色器生成(Semantic-Based Shader Generation Using Shader Shaker) 3. ANGL: 将OpenGL ES引入桌面端(ANGLE: Bringing OpenGL ES to the Desktop)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值