无痛醒砖工

码着码着,就湿了
[转]热浪扭曲效果
 
热浪扭曲
          每个人都对自然界中的这种大气效果很熟悉
          光线在穿过不同密度的介质时会弯曲
 
热微光
          热空气密度比冷空气小
          密度影响介质的折射率
          热空气上升的同时会被冷空气替代, 这会改变光射入眼睛的路线
 
          渲染场景到RGBA离屏缓存(可渲染的纹理)
          颜色写入RGB值
          扭曲度写入Alpha通道
          绘制全屏长方形到后备缓冲区
          对离屏缓冲采样以获得扭曲度
          用扰动贴图来确定扰动向量, 用扭曲度放缩后偏移原始纹理坐标
          基于扰动纹理坐标的可增长泊松分布(根据扭曲度来进行偏移)
 
扭曲度
          逐像素判断当前像素被扭曲的程度
          当光线穿过更多的气体时, 折射程度也相应增加
          扭曲随场景深度增加
     开始时把渲染目标的Alpha通道清为1.0,表示最大深度
     Pixel shader把每个像素的深度写入alpha通道
 
          深度提供了一个很好的全局扭曲方案, 但是你的美工们希望局部控制
          热浪几何体可以用来定义扭曲范围, 如热空气出口和喷气发动机尾
          热浪纹理可以使热浪几何本上的扭曲动起来
 
热度几何体 & 热度纹理
          像素扭曲度来源来热度纹理
          扭曲度被深度放大
          用高度进一步放大 (纹理坐标) 并且 N.V 来避免生硬的边缘
          扭曲度被写入Alpha通道
 
全屏矩形
 
          全屏矩形用离屏缓存(可渲染的纹理)来绘制并且用扰动贴图作为纹理
 
扰动贴图
          一个2D向量储存在红色和绿色通道内
          在全屏矩形两个方向上卷动贴图并采样两次
          平均两次采样并把值变换到 [-1.0, 1.0] 的范围内
          用扭曲度放缩向量
          结果就是扭曲向量
 
扭曲向量
          扭曲向量用于偏移原始纹理坐标
          向量的大小取决于扭曲度
          这个新的扰动纹理用于读入离屏缓存
 
可增长泊松分布
          模糊中心在扰动纹理坐标的中间
          偏移基于扭曲度
 
扭曲 Shader
float4 main (PsInput i) : COLOR
{
   // fetch from perturbation map with scrolling texture coords
   float3 vPerturb0 = tex2D (tPerturbationMap, i.texCoord1);
   float3 vPerturb1 = tex2D (tPerturbationMap, i.texCoord2);
           
   // scale and bias: (color - 0.5f)*2.0f
   vPerturb0 = SiConvertColorToVector(vPerturb0);
   vPerturb1 = SiConvertColorToVector(vPerturb1);
 
   // average perturbation vectors
   float2 offset = (vPerturb0.xy + vPerturb1.xy) * 0.5f;
 
   // get distortion weight from renderable texture (stored in alpha)
   float4 cDistWeight = tex2D (tRBFullRes, i.texCoord0);
 
   // square distortion weight
   cDistWeight.a *= cDistWeight.a;
 
   // compute distorted texture coords
   offset.xy = ((offset.xy * cDistWeight.a) * fPerturbScale) + i.texCoord0;
 
   // fetch the distorted color
   float4 o;
   o.rgb = SiPoissonDisc13RGB(tRBFullRes, offset, 1.0f/screenRes.xy, cDistWeight.a);
   o.a = 1.0f;
   return o;
}
 
可增长泊松分布 Shader
float3 SiGrowablePoissonDisc13FilterRGB
(sampler tSource, float2 texCoord, float2 pixelSize, float discRadius)
{
   float3 cOut;
   float2 poisson[12] = {float2(-0.326212f, -0.40581f),
                         float2(-0.840144f, -0.07358f),
                         float2(-0.695914f, 0.457137f),
                         float2(-0.203345f, 0.620716f),
                         float2(0.96234f, -0.194983f),
                         float2(0.473434f, -0.480026f),
                         float2(0.519456f, 0.767022f),
                         float2(0.185461f, -0.893124f),
                         float2(0.507431f, 0.064425f),
                         float2(0.89642f, 0.412458f),
                         float2(-0.32194f, -0.932615f),
                         float2(-0.791559f, -0.59771f)};
   // Center tap
   cOut = tex2D (tSource, texCoord);
   for (int tap = 0; tap < 12; tap++)
   {
      float2 coord = texCoord.xy + (pixelSize * poisson[tap] * discRadius);
 
      // Sample pixel
      cOut += tex2D (tSource, coord);
   }
   return (cOut / 13.0f);
}
 

posted on 2013-01-22 11:56  cydonia  阅读(2507)  评论(0编辑  收藏  举报