0
\$\begingroup\$

I am currently having issues with HLSL shaders. I am trying to implement point lights but I am getting unusual data when debugging the shader in Visual Studio.

I have read on several sites that say that the data stored in CBuffers should be aligned to 4 bytes, thus I added padding where it was needed (is this correct?).

When I set the data in c++, some of it comes through alright but other data is not. For example the color comes through alright but the range is being displayed as NaN in the VS graphics debugger.

Is there something wrong with the code below? (All structs are the same as those in c++ structs)

Please ask if there is anything else you would like to see code wise. Thanks!

PointLight Code:

float4 calcPointLight(PointLight pointLight, float3 normal, float3 worldPos0, float4 specularMap, float4 diffuseTex)
{
    float3 lightDirection = worldPos0 - pointLight.pos;
    float distanceToPoint = length(lightDirection);

    //  if (distanceToPoint > pointLight.range)
   //   return float4(0, 0, 0, 0);

    lightDirection = normalize(lightDirection);

    float4 color = calcLight(pointLight.base, lightDirection, normal, worldPos0, specularMap);

    float attenuation = pointLight.atten[0] +
    pointLight.atten[1] * distanceToPoint +
    pointLight.atten[2] * distanceToPoint * distanceToPoint +
    0.0001;

    return color / attenuation;
}


float4 calcLight(BaseLight base, float3 direction, float3 normal, float3 worldPos0, float4 specularMap)
{
    float diffuseFactor = (dot(normal, -direction));

    float4 diffuseColor = float4(0, 0, 0, 0);
    float4 specularColor = float4(0, 0, 0, 0);

    if (diffuseFactor > 0.0f)
    {
        diffuseColor = base.color * base.intensity * diffuseFactor;
        diffuseColor = saturate(diffuseColor);

        float3 directionToEye = normalize(cameraPos - worldPos0);
        float3 reflectDirection = normalize(reflect(direction, normal));

        float specularFactor = dot(directionToEye, reflectDirection);
        specularFactor = pow(abs(specularFactor), specularPower);

        if (specularFactor > 0)
        {
            specularColor = base.color * 1.0f * specularFactor;
        }
        if (specularMap.a > 0.0f)
            specularColor = specularColor * specularMap;
    }


    return saturate(ambient + diffuseColor + specularColor);
}

Structs

struct BaseLight
{
    float4 color;
    float intensity;

    float3 padding3; //TEST
};

struct DirectionalLight
{
    BaseLight base;
    float3 direction;
};

struct PointLight
{
    BaseLight base;
    float3 atten;
    float padding;
    float3 pos;
    float range;
};

CBuffers

    cbuffer MatrixBuffer : register(b0)
{
    matrix worldMatrix;
    matrix viewMatrix;
    matrix projectionMatrix;
};


cbuffer LightingBuffer : register(b1)
{
    float4 ambient;

    float specularPower;
    float3 padding3;

    PointLight pointLight;
    //DirectionalLight light;

 };


 cbuffer CameraBuffer : register(b2)
{
    float4 cameraPos;
};
\$\endgroup\$
1
\$\begingroup\$

Verdict: One of the cBuffers was set to the incorrect stage.

Edit: I'll leave this here because it was irrelevant, but not entirely worthless in the future.

If your structs are cbuffers, they should be of type cbuffer.

cbuffer cbBaseLight : register(b0) //16*2=32-bytes
{
    float4 color;
    float4 intensity;
};
cbuffer cbDirectionalLight : register(b1) //16*3=48-bytes
{
    cbBaseLight base;
    float4 direction;
};
cbuffer cbPointLight : register(b1) //16*5=80-bytes
{
    cbBaseLight base;
    float4 atten;
    float4 pos;
    float4 range;
};

Pay attention to the registers; I'm assuming only one of PointLight/Directional will be set at a time.

NAN

"NAN", within PIX, means the GPU believes the value is constant and unused and is, therefore, not worth calculating (even to show you the value).

UV *= 1; //For a variable/vertex value
output.XXX = float4(UV, 0, 0); //For a constant value

will make the value appear. You just need to "use" the value.

\$\endgroup\$
  • \$\begingroup\$ Also I cannot do UV *=1; because they are considered constant without compatibility mode. \$\endgroup\$ – Nick Apr 4 '15 at 18:27
  • \$\begingroup\$ Good catch, forgot about constant buffers being constant :) \$\endgroup\$ – Jon Apr 4 '15 at 18:31
  • \$\begingroup\$ Haha ^^, the issue that I am having right now is this: imgur.com/cfQLBKq as you can see the light is there on the ball but there is this weird cone thing \$\endgroup\$ – Nick Apr 4 '15 at 18:33
  • \$\begingroup\$ You will use a struct on the CPU side, it becomes a "cbuffer" on the GPU which is the fancy HLSL word for 16-byte aligned struct. \$\endgroup\$ – Jon Apr 4 '15 at 18:38
  • \$\begingroup\$ So I should change my structs on the GPU side to being Cbuffers? \$\endgroup\$ – Nick Apr 4 '15 at 18:39

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.