0
\$\begingroup\$

I have a lightstruct in C++ which holds the color and direction of the light.

    const int NUM_LIGHTS = 1;

struct lightStruct {
    XMFLOAT4 Color;
    XMFLOAT4 Direction;
};

And this is how I create my buffer and update it.

    void PBRMaterial::CreateLightBuffer(ID3D11Device* device, ID3D11Buffer** lightBuffer, std::vector<lightStruct*> lightStructs){

    D3D11_BUFFER_DESC cbDesc;
    cbDesc.ByteWidth = sizeof(lightStruct) * NUM_LIGHTS;
    cbDesc.Usage = D3D11_USAGE_DYNAMIC;
    cbDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
    cbDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
    cbDesc.MiscFlags = 0;
    cbDesc.StructureByteStride = 0;

    D3D11_SUBRESOURCE_DATA InitData;
    InitData.pSysMem = &lightStructs[0];
    InitData.SysMemPitch = 0;
    InitData.SysMemSlicePitch = 0;

    if (FAILED(device->CreateBuffer(&cbDesc, &InitData, lightBuffer)))
    {
        throw GameException("ID3D11Device::CreateLightBuffer() failed.");
    }
}

void PBRMaterial::SetLightBuffer(ID3D11DeviceContext* deviceContext, ID3D11Buffer** lightBuffer){

    deviceContext->VSSetConstantBuffers(0, 1, lightBuffer);
}

On the shader side I declare my variables as such:

    #define NUM_LIGHTS 1

    struct DIRECTIONAL_LIGHT_DATA {
        float4 Color;
        float4 Direction;
    };

    cbuffer cbDirectionalLight : register(b0)
    {
        DIRECTIONAL_LIGHT_DATA directionalLights[NUM_LIGHTS];
    };

Now, I don't get any errors but my shader only outputs black. I have been stuck on this for two days now and I can't come up with a solution. For debug purposes I also tried outputting the light's color directly like this:

    OUT.rgb = directionalLights[0].Color.rgb;// ambient + diffuse + specular;
OUT.a = 1;

But that also just shows up black. Anyone have a thought on what the issue might be? Thanks!

EDIT: Complete shader code:

    #include "include\\Common.fxh"

    #define NUM_LIGHTS 1

    struct DIRECTIONAL_LIGHT_DATA {
float4 Color;
float4 Direction;
    };

    cbuffer cbDirectionalLight : register(b0)
    {
        DIRECTIONAL_LIGHT_DATA directionalLights[NUM_LIGHTS];
    };

    float4x4 WorldViewProjection : WORLDVIEWPROJECTION; 
    float4x4 World : WORLD;

    float3 CameraPosition : CAMERAPOSITION;
    float4 AmbientColor : AMBIENTCOLOR = { 1.0f, 1.0f, 1.0f, 1.0f };

    Texture2D ColorTexture;
    Texture2D NormalMap;
    Texture2D SpecularMap;
    Texture2D GlossMap;

    RasterizerState DisableCulling { CullMode = NONE; };
    SamplerState ColorSampler { Filter = MIN_MAG_MIP_LINEAR; AddressU =                 WRAP; AddressV = WRAP; 
    };


    struct VS_INPUT
    {
        float4 ObjectPosition: POSITION;
        float2 TextureCoordinate : TEXCOORD;
        float3 Normal : NORMAL;
        float3 Tangent: TANGENT;
    };

    struct VS_OUTPUT 
    {
        float4 Pos: SV_Position;
        float3 Normal : NORMAL;
        float3 Tangent : TANGENT;
        float3 Binormal : BINORMAL;
        float2 TextureCoordinate : TEXCOORD;
        float3 LightDirection : TEXCOORD1;
        float3 ViewDirection : TEXCOORD2;
    };


    VS_OUTPUT vertex_shader(VS_INPUT IN)
    {
        VS_OUTPUT OUT = (VS_OUTPUT)0;

        OUT.Pos = mul(IN.ObjectPosition, WorldViewProjection);
        OUT.Normal = normalize(mul(float4(IN.Normal, 0), World).xyz);
        OUT.Tangent = normalize(mul(float4(IN.Tangent, 0), World).xyz);
        OUT.Binormal = cross(OUT.Normal, OUT.Tangent);
        OUT.TextureCoordinate = get_corrected_texture_coordinate(IN.TextureCoordinate);
        OUT.LightDirection = normalize(-directionalLights[0].Direction.xyz);

        float3 worldPosition = mul(IN.ObjectPosition, World).xyz;
        OUT.ViewDirection = normalize(CameraPosition - worldPosition);

        return OUT;
    }


    float4 pixel_shader(VS_OUTPUT IN) : SV_Target
    {
        float4 OUT = (float4)0;

        float3 sampledNormal = (2 * NormalMap.Sample(ColorSampler, IN.TextureCoordinate).xyz) - 1;
        float3x3 tbn = float3x3(IN.Tangent, IN.Binormal, IN.Normal);
        sampledNormal = mul(sampledNormal, tbn);
        float3 lightDirection = normalize(IN.LightDirection);
        float3 viewDirection = normalize(IN.ViewDirection);
        float n_dot_l = dot(lightDirection, sampledNormal);

        float4 color = ColorTexture.Sample(ColorSampler, IN.TextureCoordinate);

        float3 ambient = AmbientColor.rgb * AmbientColor.a * color.rgb;

        float3 diffuse = (float3)0;
        float3 specular = (float3)0;

        if (n_dot_l > 0)
        {
            diffuse = directionalLights[0].Color.rgb * directionalLights[0].Color.a *saturate(n_dot_l) * color.rgb;

            float4 sampledSpecular = SpecularMap.Sample(ColorSampler, IN.TextureCoordinate);
            half smoothness = GlossMap.Sample(ColorSampler, IN.TextureCoordinate);
            float SpecularPower = pow(2, 1 + smoothness * 10);

            float3 reflectionVector = normalize(2 * n_dot_l * sampledNormal - lightDirection);


            specular = sampledSpecular * min(pow(saturate(dot(reflectionVector, viewDirection)), SpecularPower), color.w);
        }

        OUT.rgb = ambient + diffuse + specular;
        OUT.a = color.a;
        return OUT;
    }

    technique11 main11
    {
        pass p0
        {
            SetVertexShader(CompileShader(vs_5_0, vertex_shader()));
            SetGeometryShader(NULL);
            SetPixelShader(CompileShader(ps_5_0, pixel_shader()));

            SetRasterizerState(DisableCulling);
        }
    }
\$\endgroup\$
1
\$\begingroup\$

Just change

std::vector< lightStruct* >

to

std::vector< lightStruct >

\$\endgroup\$
  • 2
    \$\begingroup\$ This answer would benefit from an additional information on why the suggested change fixes the problem. \$\endgroup\$ – bornander Nov 17 '16 at 14:50
  • \$\begingroup\$ That’s because std::vector< LightStruct* > is a linear array of pointers to the data. But InitData.pSysMem should be initialized with a pointer to the data. \$\endgroup\$ – Tima Tcvetkov Nov 18 '16 at 10:02
0
\$\begingroup\$

I dont know which editor you are using, but Visual Studio contains a HLSL shader debugger. So you can select a pixel/fragment and see which DXCalls influenced the pixels color.

Start your program from Debug -> Graphics -> Start Diagnostics (or hit Alt + F5), then press „Print“ to capture the last rendered frame.

Hope that helps! If not, can you show the pixel shader you are using?

\$\endgroup\$
  • \$\begingroup\$ I tried your suggestion of debugging via the diagnostics but I cant capture any frames. When I press Print it keeps showing the moving blue dots. I will edit the original post with the complete shader source. \$\endgroup\$ – Wouter de Vries Oct 11 '16 at 10:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.