3

我有一个应用程序可以在本质上是 2D 上下文中渲染多个纹理四边形(图像),效果很好。然而,在修改它以使某些纹理的部分透明之后,我停下来试图让它以一种看似标准的、理论上简单的方式表现:我只是希望它按顺序绘制纹理(就像它一直在做的那样),并且当纹理具有透明像素时,显示之前在这些点中绘制的任何内容。

但它所做的是在透明部分后面显示每个先前绘制的纹理的缩放版本,而不是渲染目标的先前渲染部分。因此,例如,如果我尝试绘制一个不透明的背景纹理,然后绘制一个较小的完全透明的纹理,那么背景会绘制得很好,但是透明图像会显示整个背景缩放到新透明图像的大小/位置。

随后的渲染纹理以这种方式继续,显示之前渲染的纹理最终结果(包括之前的纹理中的元素)。

我显然遗漏了一些关于 DirectX 中的纹理/像素着色器如何工作的基本知识(这并不奇怪,因为我对它比较陌生),但是在阅读了所有在线内容之后,我可以搜索并以无数种方式进行实验,我仍然无法弄清楚我需要做什么。

我在像素着色器中使用了一个纹理,这可能是问题的一部分,也可能不是问题的一部分。每次渲染场景时,我都会循环遍历所有要渲染的纹理,调用 PSSetShaderResources() 将不同的纹理绑定到该像素着色器纹理,每次循环,并在每次更改后调用 DrawIndexed()。这似乎是一种有效的方法,因为当像素着色器似乎无法使用任意一个着色器时,拥有大量着色器纹理似乎没有意义(它需要预编译,不?)。

无论如何,我希望这些症状足以让比我更有知识的人立即意识到我所犯的错误。这些领域的代码非常简单,但我不妨包括几个部分:

曾经的场景,对于每个着色器RV:

        m_pd3d11ImmDevContext->PSSetShaderResources(0, 1, &shaderRV);
        m_pd3d11ImmDevContext->DrawIndexed( ... )

着色器:

Texture2D aTexture : register(t0);

SamplerState samLinear : register(s0);

struct VS_INPUT
{
    float3 position  : POSITION;
    float3 texcoord0 : TEXCOORD0;
};

struct VS_OUTPUT
{
    float4 hposition : SV_POSITION;
    float3 texcoord0 : TEXCOORD0;
};

struct PS_OUTPUT
{
    float4 color : COLOR;
};

// vertex shader
VS_OUTPUT CompositeVS( VS_INPUT IN )
{
    VS_OUTPUT OUT;

    float4 v = float4( IN.position.x,
                       IN.position.y,
                       0.1f,
                       1.0f );

    OUT.hposition = v; 
    OUT.texcoord0 = IN.texcoord0;
    OUT.texcoord0.z = IN.position.z ;

    return OUT;
}

// pixel shader
PS_OUTPUT CompositePS( VS_OUTPUT IN ) : SV_Target
{
    PS_OUTPUT ps;

ps.color = aTexture.Sample(samLinear, IN.texcoord0);

return ps;
}

混合描述设置(不要认为问题出在此处): blendDesc.RenderTarget[0].BlendEnable = true;

    blendDesc.RenderTarget[0].SrcBlend      =  D3D11_BLEND_SRC_ALPHA;
    blendDesc.RenderTarget[0].DestBlend     =  D3D11_BLEND_INV_SRC_ALPHA;
    blendDesc.RenderTarget[0].BlendOp       =  D3D11_BLEND_OP_ADD;
    blendDesc.RenderTarget[0].SrcBlendAlpha =  D3D11_BLEND_ZERO;
    blendDesc.RenderTarget[0].DestBlendAlpha=  D3D11_BLEND_ZERO;
    blendDesc.RenderTarget[0].BlendOpAlpha  =  D3D11_BLEND_OP_ADD;

请让我知道是否有任何其他代码段有用!

4

0 回答 0