在加载和保存期间,DirectX中的PNG纹理缺少某些颜色?

Pol*_*hic 8 c++ directx png colors directx-11

我使用标准的DirectX函数(比如CreateTexture2D,D3DX11SaveTextureToFileD3DX11CreateShaderResourceViewFromFile)来加载PNG图像,在新创建的纹理上渲染它,然后保存到文件中.所有纹理都是两种尺寸的力量.

但在此期间,我注意到,PNG的某些颜色有点破坏(类似但与源纹理的颜色不同).透明度相同(适用于0和100%透明度部分,但不适用于例如34%).

是否有一些大的颜色近似或我做错了什么?如果是这样,我该如何解决?

以下是这两个图像(左边是源:底部有一些不同的颜色和一些渐变透明度;右边是加载第一个图像后的图像,并在新纹理上渲染,然后保存到文件中):

源图像 新图片

我不知道是什么导致这种行为,也许是新纹理的描述:

textureDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
Run Code Online (Sandbox Code Playgroud)

我试图改变它DXGI_FORMAT_R32G32B32A32_FLOAT,但效果更奇怪:

使用DXGI_FORMAT_R32G32B32A32_FLOAT

以下是在新纹理上渲染源纹理的代码:

context->OMSetRenderTargets(1, &renderTargetView, depthStencilView); //to render on new texture instead of the screen
float clearColor[4] = {0.0f, 0.0f, 0.0f, 0.0f}; //red, green, blue, alpha
context->ClearRenderTargetView(renderTargetView, clearColor);
//clear the depth buffer to 1.0 (max depth)
context->ClearDepthStencilView(depthStencilView, D3D11_CLEAR_DEPTH, 1.0f, 0);
//rendering
turnZBufferOff();
shader->set(context);
object->render(shader, camera, textureManager, context, 0);
swapChain->Present(0, 0);
Run Code Online (Sandbox Code Playgroud)

并在object->render():

UINT stride;
stride = sizeof(Vertex);
UINT offset = 0;
context->IASetVertexBuffers( 0, 1, &buffers->vertexBuffer, &stride, &offset ); //set vertex buffer
context->IASetIndexBuffer( buffers->indexBuffer, DXGI_FORMAT_R16_UINT, 0 ); //set index buffer
context->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST ); //set primitive topology

if(textureID){
    context->PSSetShaderResources( 0, 1, &textureManager->get(textureID)->texture);
}

ConstantBuffer2DStructure cbPerObj;
cbPerObj.positionAndScale = XMFLOAT4(center.getX(), center.getY(), halfSize.getX(), halfSize.getY());
cbPerObj.textureCoordinates =  XMFLOAT4(textureRectToUse[0].getX(), textureRectToUse[0].getY(), textureRectToUse[1].getX(), textureRectToUse[1].getY());
context->UpdateSubresource(constantBuffer, 0, NULL, &cbPerObj, 0, 0);
context->VSSetConstantBuffers(0, 1, &constantBuffer);
context->PSSetConstantBuffers(0, 1, &constantBuffer);

context->DrawIndexed(6, 0, 0);
Run Code Online (Sandbox Code Playgroud)

着色器非常简单:

VS_OUTPUT VS(float4 inPos : POSITION, float2 inTexCoord : TEXCOORD)
{

    VS_OUTPUT output;
    output.Pos.zw = float2(0.0f, 1.0f);

    //inPos(x,y) = {-1,1}
    output.Pos.xy = (inPos.xy * positionAndScale.zw) + positionAndScale.xy;
    output.TexCoord.xy = inTexCoord.xy * (textureCoordinates.zw - textureCoordinates.xy) + textureCoordinates.xy;

    return output;
}


float4 PS(VS_OUTPUT input) : SV_TARGET
{
return ObjTexture.Sample(ObjSamplerState, input.TexCoord);
}
Run Code Online (Sandbox Code Playgroud)

对于一些优化,我将精灵的大小解析为着色器的参数(它工作正常,纹理的大小,边框等是正确的).

Ser*_*rgi 2

我建议您的问题源于导入分层 Fireworks PNG 文件。当导入 Flash 和 Freehand 等其他软件时,Fireworks 分层 PNG 会保留其图层。但是,为了在 Photoshop 中精确复制分层 Fireworks PNG,需要将该分层 PNG 导出为扁平 PNG。因此,在 Photoshop 中打开它并拼合它并不是解决方案;解决方案在于将其打开并在 Fireworks 中压平。(注意:PNG 可以是 8、24 或 32 位......也许需要在分析中考虑到这一点。)