You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

双Pass Direct2D模糊效果输出纹理尺寸异常问题排查

双Pass模糊效果第二Pass采样异常问题

我正在实现一个带遮罩支持的简单双Pass模糊效果:

  • 仅输出第一Pass结果时,图像能铺满整个画布,符合预期:
var bitmapProps = new SharpDX.Direct2D1.BitmapProperties1(
    new SharpDX.Direct2D1.PixelFormat(SharpDX.DXGI.Format.B8G8R8A8_UNorm, SharpDX.Direct2D1.AlphaMode.Premultiplied),
    TargetBitmap!.DotsPerInch.Width, TargetBitmap.DotsPerInch.Height, SharpDX.Direct2D1.BitmapOptions.Target);

//Copy the current content of the canvas/TargetBitmap into the new source bitmap.
using var effectSource = new SharpDX.Direct2D1.Bitmap1(DeviceContext, new SharpDX.Size2(CanvasWidth, CanvasHeight), bitmapProps);
effectSource.CopyFromBitmap(TargetBitmap);

_blurEffect1.SetInput(0, effectSource, true);

DeviceContext.DrawImage(_blurEffect1, new SharpDX.Mathematics.Interop.RawVector2(0, 0));
  • 但将第一Pass结果传入第二Pass输出时,图像无法铺满画布,剩余区域显示随机颜色:
_blurEffect1.SetInput(0, effectSource, true);
    
_blurEffect2.SetInput(0, effectSource, true);
_blurEffect2.SetInput(1, _blurEffect1.Output, false);
            
//Draw to canvas
DeviceContext.DrawImage(_blurEffect2, new SharpDX.Mathematics.Interop.RawVector2(0, 0));

图像尺寸异常

通过GetImageLocalBounds获取两者分辨率,结果一致:

var aa = DeviceContext.GetImageLocalBounds(_blurEffect1.Output);
var bb = DeviceContext.GetImageLocalBounds(_blurEffect2.Output);

第二Pass的HLSL代码逻辑简单:

Texture2D OriginalTexture : register(t0);
Texture2D BlurredInputTexture : register(t1);
SamplerState InputSampler : register(s0);

float4 main(float4 pos : SV_POSITION, float4 posScene : SCENE_POSITION, float4 uv0 : TEXCOORD0) : SV_Target
{   
    float2 uv = uv0.xy;

    float mask = ComputeShapeMask(uv);
    float4 original = OriginalTexture.Sample(InputSampler, uv);
    
    if (mask == 0.0)
        return original;

    return BlurredInputTexture.Sample(InputSampler, uv);
}

请问是什么原因导致第二Pass的输入采样异常?


问题原因及解决方案

核心原因

  1. 输入边界参数错误:设置第二Pass输入时,对_blurEffect1.Output使用了false参数,Direct2D没有保留输入图像的完整边界信息,导致模糊后的纹理有效区域被截断,超出部分采样出现随机颜色。
  2. UV坐标不匹配:直接使用uv0.xy作为采样坐标,没有考虑模糊效果可能改变的纹理UV空间范围,部分区域采样坐标越界。
  3. 采样器地址模式问题:默认采样器地址模式可能为Wrap,越界采样时会循环取数,表现为随机颜色。

修复步骤

  1. 修正输入边界保留参数
    将第二Pass输入1的参数改为true,确保Direct2D传递完整的模糊纹理区域:

    _blurEffect2.SetInput(1, _blurEffect1.Output, true);
    
  2. 适配UV坐标到纹理空间
    改用posScene计算准确的UV坐标,确保适配模糊后的纹理尺寸:

    float2 uv = posScene.xy / float2(OriginalTexture.Width, OriginalTexture.Height);
    
  3. 设置采样器为Clamp模式
    修改采样器状态,越界时取边缘像素,避免随机颜色:

    SamplerState InputSampler : register(s0)
    {
        Filter = MIN_MAG_MIP_LINEAR;
        AddressU = CLAMP;
        AddressV = CLAMP;
    };
    

内容的提问来源于stack exchange,提问作者Nicke Manarin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 02:52:40