使用不同大小的像素着色器采样器创建 WPF 效果

本文关键字:采样器 创建 效果 WPF 像素 | 更新日期: 2023-09-27 18:32:06

我想创建一个效果,在其中我使用相当大的图像通过 WPF 效果使用 HLSL 生成较小的图像。但似乎由于某种原因,WPF 将所有输入图像的大小调整为呈现的大小,这不是我想要的,因为它会大量裁剪我的一个图像并使我的最终图像看起来不太好。

这就是我设置它的方式。我有一个大小为 2592x1944 的图像(视频),在 MediaElement 中播放。我将效果应用于大小为 800x600 的边框(或其他元素),并将 MediaElement 绑定到该效果,以便能够将要渲染的表面(边框)和要渲染的源(MediaElement)发送到像素着色器。

但是由于源的大量裁剪,生成的图像非常像素化。

有谁知道是否有办法让 WPF 不裁剪像素着色器示例?

我发现Greg Schecter的这篇博文有点像我想做的事,但反过来说:http://blogs.msdn.com/b/greg_schechter/archive/2008/09/27/a-more-useful-multi-input-effect.aspx他缩小了一个图像,但我想把它放大。问题是他使用ImageBrush,而我得到了VisualBrush,因为我使用UIElements而不是图像。不知道有没有办法做他在VisualBrush上做的事情。

使用不同大小的像素着色器采样器创建 WPF 效果

在 WPF Visual中,您无法执行任何操作,因为如果图像源的大小大于呈现大小,则 WPF PixelShader损失质量。如果图像源的大小小于渲染大小,则可以使用 PaddingTopPaddingBottomPaddingLeftPaddingRight 。只有一种方法可以帮助您保存全部质量:

使用"Image"或"ImageBrush"并将"Stretch"设置为 None 。通过这种方式,您将完整图像(Textura)发送到PixelShader。您必须在自定义ShaderEffect中具有DependencyPRoperty

public static readonly DependencyProperty ViewAspectProperty = DependencyProperty.Register(nameof(ViewAspect), typeof(Point), typeof(CustomEffect), new UIPropertyMetadata(new Point(1D, 1D), PixelShaderConstantCallback(0)));
    public Point ViewAspect
    {
        get => (Point)GetValue(ViewAspectProperty);
        set => SetValue(ViewAspectProperty, value);
    }

在Shader.fs中:

float2 ViewAspect : register(C0) = float2(1, 1);
sampler2D Input : register(s0);
struct VS_OUTPUT
{
    float4 Position : POSITION;
    float4 Color : COlOR;
    float2 UV : TEXCOORD;
};
float4 main(VS_OUTPUT input) : COlOR
{
  float2 uv = input.UV;  
    uv.x *= ViewAspect.x;
    uv.y *= ViewAspect.y;
    return tex2D(Input, uv);
}

当呈现控件更改大小时,您需要:

        ViewAspectX = ViewWidth > 0 ? FrameWidth / ViewWidth : 1;
        ViewAspectY = ViewHeight > 0 ? FrameHeight / ViewHeight : 1;

其中 ViewWidth и ViewHeight 是渲染框架元素的大小,FrameWidth и FrameHeight是源图像的大小 通过这种方式,您可以在不损失质量的情况下调整输入图像的大小