将均匀颜色设置为像素着色器

时间:2014-06-18 09:54:38

标签: c++ hlsl directx-11

我是DirectX11的新手,对于一个沉闷的问题感到抱歉。 我有一个像素着色器:

struct PixelShaderInput
{
    float4 pos : SV_POSITION;   
    float2 texCoord : TEXCOORD0;
};

Texture2D s_texture : register(t0);

SamplerState s_sampleParams
{
    Filter = MIN_MAG_MIP_LINEAR;
    AddressU = CLAMP;
    AddressV = CLAMP;
};

float4 main(PixelShaderInput input) : SV_TARGET
{
    float4 t = s_texture.Sample(s_sampleParams, input.texCoord);
    return t;
}

现在我想为着色器添加一种颜色:

struct PixelShaderInput
{
    float4 pos : SV_POSITION;   
    float2 texCoord : TEXCOORD0;
};

Texture2D s_texture : register(t0);
float4 s_color;

SamplerState s_sampleParams
{
    Filter = MIN_MAG_MIP_LINEAR;
    AddressU = CLAMP;
    AddressV = CLAMP;
};

float4 main(PixelShaderInput input) : SV_TARGET
{
    float4 t = s_texture.Sample(s_sampleParams, input.texCoord);
    return t * s_color;
}

如何从C ++代码设置s_color?我必须使用m_d3dContext->PSSetConstantBuffers吗?在这种情况下,我应该改变

`float4 s_color;`

cbuffer ColorOnlyConstantBuffer : register(b0)
{
    float4 m_color;
};

,对吧?

或者我可以保持简单的定义float4 s_color;并以其他方式从C ++设置它?

1 个答案:

答案 0 :(得分:0)

据我记忆,您可以使用特定结构指定顶点着色器的输入项:

D3D11_INPUT_ELEMENT_DESC inputLayoutDesc[2] =
{
    { "Position",
        0,
        DXGI_FORMAT_R32G32B32_FLOAT,
        0,
        D3D11_APPEND_ALIGNED_ELEMENT,
        D3D11_INPUT_PER_VERTEX_DATA,
        0
    },
    { "Color",
      0,
      DXGI_FORMAT_R32G32B32_FLOAT,
      0,
      D3D11_APPEND_ALIGNED_ELEMENT,
      D3D11_INPUT_PER_VERTEX_DATA,
      0
    }
};

此结构用于创建ID3D11InputLayout

const UINT inputLayoutDescCount = 2;

hr = device->CreateInputLayout(
    inputLayoutDesc,
    inputLayoutDescCount,
    compiledVsShader->GetBufferPointer(),
    compiledVsShader->GetBufferSize(),
    &inputLayout);

然后,您可以使用语义来指定哪个元素表示哪个条目:

struct VS_INPUT
{
    float4 Pos : POSITION;
    float4 Col : COLOR;
};

编辑:以回应评论。

抱歉,没有得到。你需要一个恒定的缓冲区。代码的相关(样本)部分如下。只需根据您的需要进行修改:

struct PixelConstantBuffer
{
    XMFLOAT4 lightPos;
    XMFLOAT4 observerPos;
};

// ***

D3D11_BUFFER_DESC pixelConstantBufferDesc;
pixelConstantBufferDesc.ByteWidth = sizeof(PixelConstantBuffer);
pixelConstantBufferDesc.Usage = D3D11_USAGE_DEFAULT;
pixelConstantBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
pixelConstantBufferDesc.CPUAccessFlags = 0;
pixelConstantBufferDesc.MiscFlags = 0;
pixelConstantBufferDesc.StructureByteStride = 0;

hr = device->CreateBuffer(&pixelConstantBufferDesc, nullptr, &pixelConstantBuffer);

// ***

context->PSSetConstantBuffers(1, 1, &pixelConstantBuffer);
context->PSSetShader(pixelShader, nullptr, 0);

// ***

PixelConstantBuffer pcBuffer;
pcBuffer.lightPos = XMFLOAT4(lightPos.m128_f32[0], lightPos.m128_f32[1], lightPos.m128_f32[2], lightPos.m128_f32[3]);
pcBuffer.observerPos = XMFLOAT4(camPos.m128_f32[0], camPos.m128_f32[1], camPos.m128_f32[2], camPos.m128_f32[3]);

context->UpdateSubresource(pixelConstantBuffer, 0, nullptr, &pcBuffer, 0, 0);

// *** (hlsl)

cbuffer PixelConstantBuffer : register(b1)
{
    float4 LightPos;
    float4 ObserverPos;
}