Search code examples
directx-11hlsldirect3ddirect2d

Texture split when resolution is high in HSLT custom Direct2D effect


This is weird. I'm trying to implement transitions as Direct2d effects.

On implementing a simple pixel shader from gl-transitions:

fxc /Zi /T ps_4_0 warp.hlsl /D D2D_FULL_SHADER /D D2D_ENTRY=main /E main /Fo warp.cso /Fh "warp.h" /nologo /I "c:\wk\10\Include\10.0.19041.0\um"

#define D2D_INPUT_COUNT 2
#define D2D_INPUT0_COMPLEX
#define D2D_INPUT1_COMPLEX
#define D2D_REQUIRES_SCENE_POSITION // The pixel shader requires the SCENE_POSITION input.
#include "d2d1effecthelpers.hlsli"
cbuffer constants : register(b0)
{
 ....
};

float4 transition(float2 uv)
{
    float2 direction = float2(p1, p2);
    const float smoothness = p3;
    const float2 center = float2(p4, p5);
    
    float2 v = normalize(direction);
    v /= abs(v.x) + abs(v.y);
    float d = v.x * center.x + v.y * center.y;
    float m = 1.0f - smoothstep(-smoothness, 0.0, v.x * uv.x + v.y * uv.y - (d - 0.5f + progress * (1.0f + smoothness)));
    return lerp(D2DSampleInput(0, (uv - 0.5f) * (1.0f - m) + 0.5f), D2DSampleInput(1,(uv - 0.5f) * m + 0.5f), m);
}
D2D_PS_ENTRY(main)
{  
float4 s = D2DGetInputCoordinate(0);
float4 v = transition(s.xy);
return v;
}

When the input texture is small in my previewer, it renders correctly. Here is a 974x548 preview:

Small

When the rendering is big, then it's split, depending on how big the rendering is: Here is a preview of 1696x954:

Medium

And here is a bigger preview (2730x1536): enter image description here

What could be the reason for it and how do I resolve it? It is possible that not the entire texture is passed to the shader?

I took another look at "Custom D2D Effects", I could extend the rect by implementing MapInputRectsToOutputRect(). However don't I just need to pass an empty {0,0,0,0} opaque rect so the effect will take the entire output.

It seems to me that Direct2D is parallelizing the effect by passing it in steps, but I don't want that for no 1:1 effects.

Many thanks.


Solution

  • I found again the answer.

    It's the rendering controls which by default start with 1024x1024 tiles. Altering that before drawing to the actual width/height of the context worked fine.