Мое рендеринг изображения и рендеринга в текстуру теряет ровно один пиксель по ширине и высоте - PullRequest
3 голосов
/ 10 апреля 2019

Я преобразовал изображение UYVY в RGB в пиксельном шейдере, и отрисованная цель в текстуру растрового изображения RGB теряет ровно один пиксель как по ширине, так и по высоте.

Я пробовал, если это проблема области просмотра или нет. Перед рендерингом области просмотра первые четыре значения с плавающей точкой (TopLeftX, TopLeftY, Width, Height) равны (0,0f, 0,0f, 768.0f, 576.0f) . Я проверил алгоритм преобразования из UYVY в RGB в шейдере. Если что-то не так с алгоритмом шейдера, изображение покажет неверные данные о пикселях, которых нет. Но меня беспокоит описание сэмплера, которое я использовал. Описание моего сэмплера следующее:

const D3D11_SAMPLER_DESC samplerDesc = {
            D3D11_FILTER_MIN_MAG_POINT_MIP_LINEAR,
            D3D11_TEXTURE_ADDRESS_WRAP, 
            D3D11_TEXTURE_ADDRESS_WRAP, 
            D3D11_TEXTURE_ADDRESS_WRAP,
            0, 1, D3D11_COMPARISON_NEVER,
            {0.0f, 0.0f, 0.0f, 0.0f}, 0, FLT_MAX };

Я теряю ровно одну ширину пикселя и одну высоту пикселя. Мое преобразованное изображение предназначено для 768 x 576. Но изображение показывает 767 x 575. Один пиксель черной рамки показывает справа и снизу при рендеринге к изображению, а также при рендеринге. Однопиксельная рамка имеет черный цвет, потому что изначально я очистил целевой вид в черном цвете.

Если кто-то может указать, куда мне следует обратиться, чтобы решить эту проблему, это будет полезно для меня.

Обновление:

Формат ввода:

const std::array<D3D11_INPUT_ELEMENT_DESC, 2> PosTexMixVideoLayout =
{
    {
        { "POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
        { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 },
    }
};

Структура ввода:

struct VSPosTextOverlay
{
    float4 position : POSITION0;
    float2 texOverlay : TEXCOORD0;
    float2 texImage : TEXCOORD1;
};

struct VSPosVideoTexture
{
    float4 position : POSITION0;
    float2 texOverlay : TEXCOORD0;
    float2 texImage : TEXCOORD1;
};

Преобразование UYVY в RGB в пиксельных шейдерах:

/// <summary>Function to convert Uyvy to Rgb.</summary>
/// <param name="texImage">The tex image.</param>
/// <returns>A float4 value of RGB.</returns>
/// <remarks>
/// This function converts the Uyvy data contained in the input X8R8G8B8 texture
/// to Rgb. For even pixels the luminance value .g ist used, for odd pixels .a.
///
///      Formula for color values in the range 0-255:
///      R = 1.164(Y-16) + 1.596(Cr-128)
///      G = 1.164(Y-16) - 0.813(Cr-128) - 0.391(Cb-128)
///      B = 1.164(Y-16) + 2.018(Cb-128)
///      Note that the color values returned from the texture sampler are
///      in the range 0-1.
/// </remarks>
static inline float4 Uyvy2Rgb(in float2 texImage)
{
    // check whether we render an odd or even pixel
    // odd == 0.0 for even and odd == 1.0 for odd pixels
    float odd = step(frac(texImage.x * halfWidth), 0.5f);

    float4 uyvyColor = float4(uyvyImageTexture.Sample(uyvyImageSampler, texImage));

    float y = lerp(uyvyColor.a, uyvyColor.g, odd);

    y = 1.164f * (y - 0.0625f);
    uyvyColor.r -= 0.5f;
    uyvyColor.b -= 0.5f;
    uyvyColor.r *= saturation;
    uyvyColor.b *= saturation;

    float4 rgbColor;
    rgbColor.a = 1.0f;
    rgbColor.r = y + 1.596f * uyvyColor.r;
    rgbColor.g = y - 0.813f * uyvyColor.r - 0.391f * uyvyColor.b;
    rgbColor.b = y + 2.018f * uyvyColor.b;
    return rgbColor;
}

1 Ответ

0 голосов
/ 26 июня 2019

Из-за проблемы с половиной пикселей DirectX 9 требовалось смещение для настройки чертежей в области просмотра. Это смещение является причиной потери 1 пикселя вправо и влево, масштабируемой из области просмотра в реализации DirectX 11, поскольку она решена в более поздних версиях DirectX. Таким образом, это выглядит как граница в 1 пиксель в цвете фона. Если мы удалим применение смещений - граница больше не будет существовать.

...