我正在尝试根据用户输入显示纹理的单独 R、G、B 和 A 通道。我正在使用 Image 类来显示具有 alpha 通道的纹理。这些纹理被加载到 BitmapSource 对象中,并具有 Bgra32 格式。问题是,当我将 Image 的 Source 设置为 BitmapSource 时,如果我显示 R、G 或 B 通道的任何组合,我总是会得到预先乘以 alpha 值的像素。我写了一个非常简单的着色器,预编译它,并使用 ShaderEffect 类分配给 Image 的 Effect 属性以分离和显示单独的通道,但显然,着色器在 WPF 预乘后被赋予纹理alpha 值到纹理上。
下面是设置图片来源的代码片段:
BitmapSource b = MyClass.GetBitmapSource(filepath);
// just as a test, write out the bitmap to file to see if there's an alpha.
// see attached image1
BmpBitmapEncoder test = new BmpBitmapEncoder();
//test.Compression = TiffCompressOption.None;
FileStream stest = new FileStream(@"c:\temp\testbmp2.bmp", FileMode.Create);
test.Frames.Add(BitmapFrame.Create(b));
test.Save(stest);
stest.Close();
// effect is a class derived from ShaderEffect. The pixel shader associated with the
// effect displays the color channel of the texture loaded in the Image object
// depending on which member of the Point4D is set. In this case, we are showing
// the RGB channels but no alpha
effect.PixelMask = new System.Windows.Media.Media3D.Point4D(1.0f, 1.0f, 1.0f, 0.0f);
this.image1.Effect = effect;
this.image1.Source = b;
this.image1.UpdateLayout();
这是着色器代码(它非常简单,但我想我会包含它只是为了完整性):
sampler2D inputImage : register(s0);
float4 channelMasks : register(c0);
float4 main (float2 uv : TEXCOORD) : COLOR0
{
float4 outCol = tex2D(inputImage, uv);
if (!any(channelMasks.rgb - float3(1, 0, 0)))
{
outCol.rgb = float3(outCol.r, outCol.r, outCol.r);
}
else if (!any(channelMasks.rgb - float3(0, 1, 0)))
{
outCol.rgb = float3(outCol.g, outCol.g, outCol.g);
}
else if (!any(channelMasks.rgb - float3(0, 0, 1)))
{
outCol.rgb = float3(outCol.b, outCol.b, outCol.b);
}
else
{
outCol *= channelMasks;
}
if (channelMasks.a == 1.0)
{
outCol.r = outCol.a;
outCol.g = outCol.a;
outCol.b = outCol.a;
}
outCol.a = 1;
return outCol;
}
这是上面代码的输出:(
对不起,我没有足够的声誉点来发布图片或显然超过 2 个链接)
在 photoshop 中将文件保存到磁盘 (C:\temp\testbmp2.bmp):http:
//screencast.com/t/eeEr5kGgPukz
在我的 WPF 应用程序中显示的图像(使用上面代码片段中的图像掩码):
http ://screencast.com/t/zkK0U5I7P7