简体   繁体   English

像素着色器中的c ++ DirectX照明问题

[英]c++ DirectX lighting in pixel shader issue

I have a problem that I cant manage to figure out. 我有一个无法解决的问题。 I just added a point light to my project and it makes the textures go completely black. 我刚刚在项目中添加了一个点光源,它使纹理完全变成黑色。 I have no idea why. 我不知道为什么。

I think that it might be either the normal that is not updating correctly or it might be calculation of sx, sy and sz 我认为这可能是未正确更新的正常现象,也可能是sx,sy和sz的计算

I would be very happy if someone had time to take a look at it and help me. 如果有人有时间看看它并为我提供帮助,我将非常高兴。 Thanks. 谢谢。

So. 所以。 Here is my pixel shader : 这是我的像素着色器:

Texture2D txDiffuse : register(t0);
SamplerState sampState;
cbuffer PointLight : register(b0)
{
    float3 Pos;
    float diff;
    float amb;
    float spec;
    float range;
    float intensity;
};
struct VS_IN
{
    float4 Pos : SV_POSITION;
    float2 Tex : TEXCOORD;
    float4 Norm : NORMAL;
    float4 Pos2 : POSITION;
};
float4 PS_main(VS_IN input) : SV_Target
{
    float3 s = txDiffuse.Sample(sampState, input.Tex).xyz;

    float3 lightPos = Pos;

    float3 lightVector = lightPos - input.Pos2;
    lightVector = normalize(lightVector);
    float nDotL = dot(lightVector, input.Norm);

    float diff1 = 0.8;
    float amb1 = 0.1;

    s.x = (s.x * diff * nDotL + s.x * amb);
    s.y = (s.y * diff * nDotL + s.y * amb);
    s.z = (s.z * diff * nDotL + s.z * amb);



    return float4(s, 0.0);

};

Geometry shader : 几何着色器:

cbuffer worldMatrix : register(b0)
{
    matrix world;
}
cbuffer viewMatrix : register(b1)
{
    matrix view;
}
cbuffer projectionMatrix : register(b2)
{
    matrix projection;
}
struct VS_IN
{
    float4 Pos : SV_POSITION;
    float2 Tex : TEXCOORD;
};
struct VS_OUT
{
    float4 Pos : SV_POSITION;
    float2 Tex : TEXCOORD;
    float4 Norm : NORMAL;
    float4 Pos2 : POSITION;
};

[maxvertexcount(6)]
void main(triangle VS_IN input[3] : SV_POSITION, inout TriangleStream< VS_OUT > output2)
{

    matrix wvp = mul(projection, mul(world, view));
    matrix worldView = mul(world, view);


    float4 normal = float4(cross(input[1].Pos - input[0].Pos, input[2].Pos - input[0].Pos), 0.0f);
    normal = normalize(normal);

    float4 rotNorm = mul(worldView, normal);
    rotNorm = normalize(rotNorm);

    VS_OUT output[3];
    for (uint i = 0; i < 3; i++)
    {
        output[i].Pos = input[i].Pos;
        output[i].Pos = mul(wvp, input[i].Pos);
        output[i].Tex = input[i].Tex;
        output[i].Norm = rotNorm;
        output[i].Pos2 = mul(worldView, output[i].Pos);
        output2.Append(output[i]);
    }
    output2.RestartStrip();

    VS_OUT outputcopy[3];
    for (uint i = 0; i < 3; i++)
    {
        outputcopy[i].Pos = input[i].Pos + (normal);
        outputcopy[i].Pos = mul(wvp, outputcopy[i].Pos);
        outputcopy[i].Tex = input[i].Tex;
        outputcopy[i].Norm = rotNorm;
        outputcopy[i].Pos2 = mul(worldView, outputcopy[i].Pos);
        output2.Append(outputcopy[i]);
    }

    output2.RestartStrip();
}

Code to initializing the point light: 初始化点光源的代码:

struct PointLight
{
    Vector3 Pos;
    float diff;
    float   amb;
    float   spec;
    float   range;
    float   intensity;

};
PointLight* pointLight = nullptr;
PointLight PL =
    {
    Vector3(0.0f, 0.0f, -3.0f),
    0.8f,
    0.2f,
    0.0f,
    100.0f,
    1.0f
    };

    pointLight = &PL;

    D3D11_BUFFER_DESC lightBufferDesc;
    memset(&lightBufferDesc, 0, sizeof(lightBufferDesc));
    lightBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
    lightBufferDesc.Usage = D3D11_USAGE_DEFAULT;
    lightBufferDesc.StructureByteStride = 0;
    lightBufferDesc.MiscFlags = 0;
    lightBufferDesc.ByteWidth = sizeof(PointLight);

    D3D11_SUBRESOURCE_DATA pointLightData;
    memset(&pointLightData, 0, sizeof(pointLightData));
    pointLightData.pSysMem = &PL;

    gDevice->CreateBuffer(&lightBufferDesc, &pointLightData, &lightBuffer);

and in render() i run 并在render()中运行

gDeviceContext->PSSetConstantBuffers(0, 1, &lightBuffer);

Texture will be black if sx , sy , sz equal to zero. 如果sxsysz等于零,则纹理将为黑色。

s.x = (s.x * diff * nDotL + s.x * amb);
s.y = (s.y * diff * nDotL + s.y * amb);
s.z = (s.z * diff * nDotL + s.z * amb);

Try to change diff and amb with a non-zero constant so that you can be sure that you set contant buffer correctly or not. 尝试使用非零常数更改diffamb ,以确保可以正确设置contant缓冲区。 If after you change them, it's still black then it must be nDotL and/or sampled texture that is zero. 如果更改它们后,它仍然是黑色,则它必须是nDotL和/或采样纹理为零。 Then try with non-zero constant for texture sample. 然后尝试使用非零常数进行纹理采样。 If they're still causing texture to look black then your light vector calculation is the culprit. 如果它们仍然导致纹理看起来很黑,那么您的光矢量计算就是元凶。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM