YUV到RGB着色器边框工件

时间:2015-03-22 17:30:33

标签: c++ directx hlsl

我有YUV到RGB转换着色器。

struct Pixel_INPUT
{
    float4 pos  : SV_POSITION;
    float2 tex  : TEXCOORD0;
};

Texture2D textureY : register(t0);
Texture2D textureU : register(t1);
Texture2D textureV : register(t2);

SamplerState samstate
{
    MinFilter     = Anisotropic;
    MagFilter     = Anisotropic;
AddressU = Clamp;
AddressV = Clamp;
};

float4 PS(Pixel_INPUT input) : SV_Target
{
    float y = (1.1643f * textureY.Sample(samstate,input.tex) - 0.0625f);
    float u = textureU.Sample(samstate,input.tex) - 0.5f;
    float v = textureV.Sample(samstate,input.tex) - 0.5f;

   float r = y + 1.5958f * v;
   float g = y - 0.39173f * u - 0.81290f * v;
   float b = y + 2.017f * u;

   return float4(r,g,b,1);
}

但是我的图像右侧有一条绿线: enter image description here

我使用Clamp地址模式,图像比原始颜色更黄。

2 个答案:

答案 0 :(得分:1)

我有采样器状态

  samplerDesc.Filter   = D3D10_FILTER_ANISOTROPIC;
  samplerDesc.AddressU  = D3D10_TEXTURE_ADDRESS_MIRROR;
  samplerDesc.AddressV   = D3D10_TEXTURE_ADDRESS_MIRROR;
  samplerDesc.AddressW    = D3D10_TEXTURE_ADDRESS_MIRROR;
  samplerDesc.MaxAnisotropy = 8;
  samplerDesc.ComparisonFunc = D3D10_COMPARISON_NEVER;


   pDevice->CreateSamplerState(&samplerDesc,&SampState);

关于Y U和V纹理分辨率:U和V纹理分辨率始终是Y分辨率的一半。

答案 1 :(得分:0)

我假设(因为您使用YUV的三平面版本),你的FourCC是I420,如here所述

由于SV_Position为您提供了精确的像素坐标,因此您可以避免使用采样器(在技术上应该采用点模式进行此类操作)。

这是一个在您的用例中加载数据的简单示例(请注意我只提供加载代码,而不是转换本身)。

struct Pixel_INPUT
{
    float4 pos  : SV_POSITION;
    float2 tex  : TEXCOORD0;
};

Texture2D textureY : register(t0);
Texture2D textureU : register(t1);
Texture2D textureV : register(t2);

float4 PS(Pixel_INPUT input) : SV_Target
{
    int3 pixelLocation = int3(input.pos.xy, 0)); //0 is miplevel

    //Get y component
    float y = textureY.Load(pixelLocation).r;

    //now since u and v are half resolution, we need to divide location by 2
    pixelLocation.xy /= 2;

    //Load our u and v components
    float u = textureU.Load(pixelLocation).r;
    float v = textureV.Load(pixelLocation).r;

    //Perform your conversion and return
}