XNA Shader编程教程13-Alpha映射
这个教程我们将实现一个简单但重要的shader:Alpha贴图!当你想绘制一个部分透明的3D物体时使用Alpha贴图是很有用的。比如一个有窗框的窗户,可以让窗框不透明而使其他部分透明!你可以在很多场合使用Alpha贴图,比如冰面、皮肤、花、昆虫翅膀等。
Alpha映射
这个shader的基本思路是使用一张纹理:alpha贴图。这个纹理是一张灰度图,其中黑色表示完全透明,灰色表示介于透明和不透明之间,而白色表示完全不透明。你可以将这张纹理想象成一张包含物体透明信息的图片,其中的灰度颜色代表透明百分比。颜色0.0(黑色)表示透明,颜色0.5(灰色)表示半透明,而1.0(白色)表示不透明。
所以shader需要两张纹理:
ColorMap代表物体颜色,AlphaMap代表透明度。
实现Shader
本教程只使用Diffuse Shader,并支持Alpha映射,当然你也可以在shader中实现任何你想要的效果。首先定义两个纹理:Color Map,Alpha Map。并添加到shader中:
texture ColorMap; sampler ColorMapSampler = sampler_state { Texture = <ColorMap>; MinFilter = Linear; MagFilter = Linear; MipFilter = Linear; AddressU = Mirror; AddressV = Mirror; }; texture AlphaMap; sampler AlphaMapSampler = sampler_state { Texture = <AlphaMap>; MinFilter = Linear; MagFilter = Linear; MipFilter =Linear; AddressU = Mirror; AddressV = Mirror; };
然后设置color的alpha通道并返回存储在Alpha贴图中的值,这一步在Pixel Shader中进行:
Color = (Ai*Ac*Color)+(Color*Di*Dd); Color.a = tex2D(AlphaMapSampler, Tex).r; return Color;
这里我们和以前一样计算了漫反射颜色。接着处理Colors.a分量,这个分量是Colors的alpha通道,并将这个分量设置为alpha贴图中的值。Alpha贴图中的所有分量都是相同的(因为它是一张灰度图),所以你用r、g、b通道皆可,我使用了r通道: Technique代码如下:
technique DiffuseShader { pass P0 { AlphaBlendEnable = True; SrcBlend = SrcAlpha; DestBlend = InvSrcAlpha; Sampler[0] = (ColorMapSampler); Sampler[1] = (AlphaMapSampler); VertexShader = compile vs_2_0 VertexShader(); PixelShader = compile ps_2_0 PixelShader(); } }
如你所见,我们将AlphaBlendEnable设置为true,并使用SrcAlpha/InvSrcAlpha作为混合函数,这意味着我们使用alpha通道使物体透明。
使用shader
使用shader没什么新的东西,别忘了将color和alpha纹理传递到shader中。
我还添加了一个叫做m_Overlay的overlay纹理。这个纹理用来覆盖在整个屏幕之上,使用了这个.PNG文件的alpha值,这些alpha值可以在Photoshop或其他图像编辑器中设置。
spriteBatch.Begin(SpriteBlendMode.AlphaBlend, SpriteSortMode.Immediate, SaveStateMode.SaveState); { spriteBatch.Draw(m_Overlay, new Rectangle(0, 0, 800,600), Color.White); } spriteBatch.End();
发布时间:2009/5/4 下午1:26:20 阅读次数:9063