我们要在非浮点纹理下边实现HDR,需要将所有的浮点数可渲染纹理(前几个例子中的格式都是A16R16G16B16F)修改为A8R8B8G8,修改完之后发现,Exposure_level只能控制图像的亮度,但是Glow效果没有了。

       这是因为浮点数纹理在绘制背景及茶壶时使用的如下的语句:

       return color * ((1.0+(color.a*64.0))* Exposure_Level);

       因为浮点数纹理(A16R16G16B16F存储精度要远远大于常规纹理(A8R8B8G8),我给该颜色乘以一个 Exposure_Level,颜色亮度增加了,后边的Glow效果也增加了,但是还没有达到浮点数可以溢出的值(颜色中会将其CLAMP到最大值),所以Glow效果会随这 Exposure_Level值的变大而越加明显。

       反观如果我是用了常规纹理(A8R8B8G8,可能在当前Exposure_Level值下,Glow效果无(或者有,但是十分不明显),我们将Exposure_Level值变大,但是很有可能在Exposure_Level即将变大到Glow效果可以明显显示的时候,常规纹理的存贮精度已经不能够容纳return color * ((1.0+(color.a*64.0))* Exposure_Level)的返回值了,这样即便Exposure_Level增加,可渲染纹理表示解释不了这么大的亮度,只能CLAMP掉,这样,就出现了,无论Exposure_Level如何增加,Glow效果都没不会出现的情况。

       书中给出的Solution:

       将曝光因子存储在常规可渲染纹理(A8R8B8G8)的α通道,在存储时先除以64然后在最终的Pixel Shader中重新再乘以64。

       Vertex Shader Code:    

1 sampler Texture0;
2 float Exposure_level;
3 
4 float4 ps_main(float2 Tex  : TEXCOORD0) : COLOR0
5 {   
6    float4 color = float4(tex2D(Texture0,Tex).xyz,0);
7    return float4(color.rgb, ((1 + color.a * 64) * Exposure_level)/64);
8 }

 

     Pixel Shader Code:  

 1 sampler Texture0;
 2 sampler Texture1;
 3 sampler Texture2;
 4 float Glow_Factor1;
 5 float Glow_Factor2;
 6 float Glow_Factor3;
 7 
 8 float SourceAlpha;
 9 
10 float4 ps_main(float2 Tex  : TEXCOORD0) : COLOR0
11 {   
12      float4 col1 = tex2D(Texture0,Tex);
13      float4 col2 = tex2D(Texture1,Tex);
14      float4 col3 = tex2D(Texture2,Tex);
15      
16    return  
17      float4((col1.xyz * col1.a * 64 ) * Glow_Factor1,SourceAlpha) +
18      float4((col2.xyz * col2.a * 64 ) * Glow_Factor2,0) +
19      float4((col3.xyz * col3.a * 64 ) * Glow_Factor3,0);    
20 }

      

       另外一个问题,本Demo我在实现时碰到的一个问题,最后的图像左侧有几列像素发白:

      

        后来发现是因为每一个小尺寸的Render Target α通道每次清除为255所致,将它设置为0即可。

      

      

 

 

      

posted on 2013-08-15 19:00  infinityward  阅读(308)  评论(0编辑  收藏  举报