我有一個相當簡單的像素着色器集alpha通道爲零並返回。自定義WPF ShaderEffect alpha通道具有不尋常的行爲
sampler2D tex : register(s0);
float4 PS(float2 uv : TEXCOORD) : COLOR
{
float4 color = tex2D(tex, uv);
color.a = 0;
return color;
}
我會認爲這會導致它應用到的圖像完全看不見。然而這不是看起來正在發生的事情。相反,生成的圖像將在白色背景中變得不可見,但是在黑色背景下它將保持不變。看起來這個着色器在某種程度上導致了在前景和背景之間調用「添加」功能。
例如,以下代碼加載前景和背景圖像,將上述着色器效果應用於前景,將它們呈現爲位圖,並將位圖寫入文件。
public sealed partial class MainWindow
{
public MainWindow()
{
InitializeComponent();
}
void Button_Click(object sender, RoutedEventArgs e)
{
const int width = 1024;
const int height = 768;
var sz = new Size(width, height);
var background = new Image { Source = new BitmapImage(new Uri(@"c:\background.jpg")) };
background.Measure(sz);
background.Arrange(new Rect(sz));
var foreground = new Image { Source = new BitmapImage(new Uri(@"c:\foreground.jpg")), Effect = new Alpha() };
foreground.Measure(sz);
foreground.Arrange(new Rect(sz));
var target = new RenderTargetBitmap(width, height, 96d, 96d, PixelFormats.Default);
target.Render(background);
target.Render(foreground);
var jpg = new JpegBitmapEncoder();
jpg.Frames.Add(BitmapFrame.Create(target));
using (var fileStream = File.OpenWrite(@"c:\output.jpg"))
{
jpg.Save(fileStream);
}
}
}
// Standard ShaderEffect stuff here, nothing exciting.
public sealed class Alpha : ShaderEffect
{
static readonly PixelShader Shader = new PixelShader{UriSource = new Uri("pack://application:,,,/Alpha.ps", UriKind.RelativeOrAbsolute)};
public static readonly DependencyProperty InputProperty = RegisterPixelShaderSamplerProperty("Input", typeof(Alpha), 0);
public Alpha()
{
PixelShader = Shader;
UpdateShaderValue(InputProperty);
}
public Brush Input
{
get { return (Brush)GetValue(InputProperty); }
set { SetValue(InputProperty, value); }
}
}
這產生了當施加到兩個Win7的樣品圖像的以下:
這是相同的行爲我在屏幕上看到,當我應用效果在XAML一個Image
,另一個Image
或其他背後的東西。
注意圖像是相同的,如果前景和背景相反,所以如果它不是「添加」,它至少是可交換的東西。我認爲這是「添加」。
電腦通常是正確的,所以我認爲這是用戶錯誤,但爲什麼設置阿爾法爲零不給我一個透明的圖像?如果有,我如何獲得透明圖像? (我顯然希望最終做一些更復雜的着色器(特別是綠屏),但爲了讓它起作用,我必須先讓着色器工作,所以不要只說「設置不透明度屬性」)。