Windows 8 Store App DirectX 11.1 Активиране на Blendstate със заредена PNG текстура с алфа

Зареждам PNG с прозрачност към текстура със следния код:

ComPtr<IWICStream> stream;
ComPtr<IWICBitmapDecoder> bitmapDecoder;
ComPtr<IWICBitmapFrameDecode> bitmapFrame;
ComPtr<IWICFormatConverter> formatConverter;
unsigned int width, height
D3D11_SUBRESOURCE_DATA resourceData;

ZeroMemory(&resourceData, sizeof(resourceData));

DX::ThrowIfFailed( m_wicFactory->CreateStream(&stream) );
DX::ThrowIfFailed( stream->InitializeFromMemory( rawFileBytes->Data, rawFileBytes->Length) );
DX::ThrowIfFailed( m_wicFactory->CreateDecoderFromStream( stream.Get(), nullptr, WICDecodeMetadataCacheOnDemand, &bitmapDecoder ) );
DX::ThrowIfFailed( bitmapDecoder->GetFrame(0, &bitmapFrame) );
DX::ThrowIfFailed( m_wicFactory->CreateFormatConverter(&formatConverter) );
DX::ThrowIfFailed( formatConverter->Initialize( bitmapFrame.Get(), GUID_WICPixelFormat32bppPBGRA, WICBitmapDitherTypeNone, nullptr, 1.0f /* some docs set this to 0.0f */, WICBitmapPaletteTypeCustom ) );
DX::ThrowIfFailed( bitmapFrame->GetSize(&width, &height) );

std::unique_ptr<byte[]> bitmapPixels(new byte[width * height * 4]);
DX::ThrowIfFailed( formatConverter->CopyPixels( nullptr, width * 4, width * height * 4, bitmapPixels.get() ) );

resourceData.pSysMem = bitmapPixels.get();
resourceData.SysMemPitch = width * 4;
resourceData.SysMemSlicePitch = 0;

CD3D11_TEXTURE2D_DESC textureDesc( DXGI_FORMAT_B8G8R8A8_UNORM, width, height, 1, 1 );
DX::ThrowIfFailed( m_d3dDevice->CreateTexture2D( &textureDesc, &resourceData, &texture2D ) );

if ( textureView != nullptr ) {
  CD3D11_SHADER_RESOURCE_VIEW_DESC shaderResourceViewDesc( texture2D.Get(), D3D11_SRV_DIMENSION_TEXTURE2D );
  DX::ThrowIfFailed( m_d3dDevice->CreateShaderResourceView( texture2D.Get(), &shaderResourceViewDesc, &shaderResourceView ) );
}

И за да настроя моето състояние на смесване в различен раздел от кода:

Microsoft::WRL::ComPtr<ID3D11BlendState1> blendState;

D3D11_BLEND_DESC1 desc;
ZeroMemory( &desc, sizeof( desc ) );
desc.IndependentBlendEnable = FALSE;
desc.AlphaToCoverageEnable = FALSE;
desc.RenderTarget[0].BlendEnable = TRUE;
desc.RenderTarget[0].LogicOpEnable = FALSE;
desc.RenderTarget[0].SrcBlend = D3D11_BLEND::D3D11_BLEND_SRC_ALPHA;
desc.RenderTarget[0].DestBlend = D3D11_BLEND::D3D11_BLEND_INV_SRC_ALPHA;
desc.RenderTarget[0].BlendOp = D3D11_BLEND_OP::D3D11_BLEND_OP_ADD;
desc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND::D3D11_BLEND_ONE;
desc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND::D3D11_BLEND_ONE;
desc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP::D3D11_BLEND_OP_ADD;
desc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;

direct3d.device->CreateBlendState1( &desc, blendState.GetAddressOf() );
direct3d.context->OMSetBlendState( blendState.Get(), NULL, 0xffffffff );

С цялата тази настройка все още получавам черен фон там, където трябва да има алфа.

Пояснение: Имам набор от 48 квадратни панела, които се наслагват един върху друг от z 0.0f до 48.0f, но всичко, което мога да видя, е самата предна текстура 48.0f. Вместо прозрачните зони да са прозрачни, те се изобразяват като черни.

Редактиране: Ето моя пикселен шейдър:

Texture2D Texture : register(t0);
SamplerState Sampler : register(s0);

struct sPSInput
{
    float4 pos : SV_POSITION;
    float3 norm : NORMAL;
    float2 tex : TEXCOORD0;
};

float4 SimplePixelShader(sPSInput input) : SV_TARGET
{
  float4 textured = Texture.Sample(Sampler, input.tex);
  return textured;
}

person OzBarry    schedule 13.02.2013    source източник


Отговори (2)


Това

    desc.RenderTarget[0].SrcBlend = D3D11_BLEND::D3D11_BLEND_ONE;

трябва да е това

   desc.RenderTarget[0].SrcBlend = D3D11_BLEND::D3D11_BLEND_ALPHA;

също AlphaToCoverageEnable трябва да бъде зададено false за вашите нужди

Освен това трябва да деактивирате Z буфера. Активираният Z буфер предотвратява изчертаването на всички обекти зад обекта отпред.

person thumbmunkeys    schedule 13.02.2013
comment
Актуализирах моя горен кодов фрагмент до това, което моят blendState изглежда сега, но това не оказа никакво влияние върху проблема ми :( - person OzBarry; 14.02.2013
comment
И така, в крайна сметка успях да видя каквито и панели да начертах между -0,9 и 0,9, и всички те бяха закръглени до 0,0f и се появиха на един и същи z слой. Веднага щом преведа който и да е модел извън този диапазон, те просто изчезват. - person OzBarry; 14.02.2013
comment
Да, опитах да деактивирам z буфера без резултат - изглежда, че някъде в моя код има нещо, което се задава, което ми пречи да превеждам z на моите модели. Нямам идея защо. Мога да публикувам целия си начален код, ако смятате, че това ще помогне. - person OzBarry; 15.02.2013
comment
това ще ми помогне да ти помогна :) сигурен ли си, че текстурите имат алфа канал? - person thumbmunkeys; 15.02.2013
comment
Ето моя начален код. Текстурите определено имат алфа канал. Направих малко хакерска и статична корекция за сега, където посочих z координатите директно в модела, тъй като те в момента са само плоски равнини в момента - направих това, защото трябва да демонстрирам това приложение след две седмици, така че просто имам нужда от нещо това работи засега и винаги мога да се върна и да поправя проблема с превода. Ето моите подходящи матрични класове. Камерата и прожекцията работят добре, затова не качих. - person OzBarry; 15.02.2013
comment
С твърдото z в моделите алфата работи безупречно. - person OzBarry; 15.02.2013
comment
така че вашите правоъгълници вероятно се изрязват, защото са извън зоната за гледане? - person thumbmunkeys; 15.02.2013
comment
Позиционирам камерата си на -1000.0f, znear/far е от 0.1f до 2000.0f, обектите ми са на z 0.0f. Мога да преведа x и y без никакви проблеми. Нямам представа защо биха били подрязани, ако са. - person OzBarry; 15.02.2013
comment
-1000 е доста далеч, освен ако нямате огромни обекти. но мисля, че вашият проблем не е някакво състояние на дълбочина/смесване, а матрицата на прожекцията на изгледа. обръщате ли го преди да изобразите обектите? също така публикуването на код за шейдър на върха би помогнало - person thumbmunkeys; 15.02.2013
comment
Да, можете да видите как камерата е обърната в съответните матрични класове Свързах се с преди, както и с вертекс шейдър. Току-що качих класа си за матрица на камера тук. - person OzBarry; 15.02.2013
comment
Наистина не съм сигурен за това, но си струва да опитате: умножете матриците във вашия вертекс шейдър в обратен ред. Мисля, че това е необходимо, защото транспонирате матриците преди умножението (A*B)T = BT * AT. - person thumbmunkeys; 16.02.2013
comment
Когато обърна това, не мога да видя нищо, което се изобразява. - person OzBarry; 16.02.2013
comment
хм, тогава съм без идеи. Но съм почти сигурен, че редът на вашите умножения е грешен - person thumbmunkeys; 16.02.2013

Трябва да нормализирате своите Z-стойности в диапазона 0.0f (близо) - 1.0f (далеч).

Правилно ли настройвате своя ViewPort?

D3D11_VIEWPORT Viewport =
{
    0.0f,                           // TopLeftX
    0.0f,                           // TopLeftY
    <width>,                        // Width
    <height>,                       // Height
    0.0f,                           // MinDepth
    1.0f };                         // MaxDepth
person d7samurai    schedule 07.02.2015