Directional Lighting

Started by
2 comments, last by Aqua Costa 10 years, 9 months ago

Hello all,

I've been trying to get some basic lighting to work with my application. So I've have had limited success due to my lack of knowledge of HLSL and thought I would bring my shader here

The goal was to get basic diffuse and ambient light working with a simple Quad

these structures sit at the very top of the Quad.cpp file right after the PreProcessor directives

struct Light
{
XMFLOAT3 dir;
XMFLOAT4 ambient;
XMFLOAT4 diffuse;
float pad;
};

Light light;

struct cbPerFrame
{
Light light;
};

cbPerFrame constBuffer;

the code for the lighting shader is as follows:

Texture2D colorMap : register( t0 );
SamplerState colorSampler : register( s0 );


cbuffer cbChangesEveryFrame : register( b0 )
{
matrix worldMatrix;
};

cbuffer cbNeverChanges : register( b1 )
{
matrix viewMatrix;
};

cbuffer cbChangeOnResize : register( b2 )
{
matrix projMatrix;
};



struct Light
{
float3 dir;
float4 ambient;
float4 diffuse;
};



cbuffer cbPerFrame
{
Light light;
};

struct VS_Input
{
float4 pos : POSITION;
float2 tex0 : TEXCOORD0;
float3 norm : NORMAL;
};

struct PS_Input
{
float4 pos : SV_POSITION;
float2 tex0 : TEXCOORD0;
float3 norm : NORMAL;
};


PS_Input VS_Main( VS_Input vertex )
{
PS_Input vsOut = ( PS_Input )0;
vsOut.pos = mul( vertex.pos, worldMatrix );
vsOut.pos = mul( vsOut.pos, viewMatrix );
vsOut.pos = mul( vsOut.pos, projMatrix );

vsOut.norm = mul( vertex.norm, worldMatrix);

vsOut.tex0 = vertex.tex0;

vsOut.norm = normalize(vsOut.norm);

return vsOut;
}


float4 PS_Main( PS_Input input ) : SV_TARGET
{
input.norm = normalize(input.norm);

float4 textureColor = colorMap.Sample(colorSampler, input.tex0);

float lightIntensity = saturate(dot(input.norm, light.dir));

float4 color = saturate(light.diffuse * lightIntensity);

color = color * textureColor;

return color;
}

One of the Constant Buffers as you see is cbPerFrame which contains the Light Structure member

This is my input Layout Description, its called after the shaders have been compiled in Quad.cpp.

D3D11_INPUT_ELEMENT_DESC inputE[] =
{
{"POSITION", NULL, DXGI_FORMAT_R32G32B32_FLOAT, NULL, NULL, D3D11_INPUT_PER_VERTEX_DATA, NULL},
{"TEXCOORD", NULL, DXGI_FORMAT_R32G32_FLOAT, NULL, 12, D3D11_INPUT_PER_VERTEX_DATA, NULL},
{"NORMAL", NULL, DXGI_FORMAT_R32G32B32_FLOAT, NULL, 20, D3D11_INPUT_PER_VERTEX_DATA, NULL},
};

This code Is called after the shaders have been compiled during runtime and the inputLayout is filled out

/*light.dir = XMFLOAT3(0.0f, 0.0f, 1.0f);
light.ambient = XMFLOAT4(0.0f, 0.0f, 0.0f, 0.0f);
light.diffuse = XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f);
*/

This is the code in my Render Function thats suppose to pass the light structure that I filled out after initalizing the shaders to the constBuffer.

I pass to the constant buffer inside the .fx file with the updateSubresource and the PSSetConstantBuffers call

constBuffer.light = light;
devcon->UpdateSubresource(cbPerFrameBuffer, 0, 0, &constBuffer, 0, 0);
devcon->PSSetConstantBuffers(0, 1, &cbPerFrameBuffer);

So I'm just wondering what am I overlooking? I figured there wouldn't be any easy way to ask this without posting 100+ lines of code. But if anyone could point out something thats off in the blocks of code that I have provided it would be greatly appreciated!

-Marcus

Advertisement

First of all use


[code][/code]

blocks to put your code. It makes posts a lot easier to read.

Do you have any idea of what is the problem? Have you checked if the shader is getting the cbuffer data correctly?

Anyway, there are some problems in your code:

1-The padding variable is incorrect. It should be:


struct Light
{
    XMFLOAT3 dir;
    float pad;
    XMFLOAT4 ambient;
    XMFLOAT4 diffuse;
};

2-Are you sure cbPerFrame is assigned to the slot 0? Because you're not specifying the register in the shader... It might be, but add : register(b0) just to be sure.

Also,

If you want the light direction to be (0.0f, 0.0f, 1.0f), the light direction the shader uses must be (0.0f, 0.0f, -1.0f), so the dot product will return a positive value when the angle between the light dir and the normal is < 90º.

Either pass the correct value to the shader or modify the shader with this line:


float lightIntensity = saturate(dot(input.norm, -light.dir));

Thank you very much, it turns out that changing the direction to -1.0f instead of 1.0f and also me forgetting to set the cbPerFrame register to b0 where the culprits.

Also sorry about the pasting of the code incorrectly, I should have probably read the rules pertaining to posting code, won't happen again.

Once again thanks a bunch!

-Marcus

Glad to know it's working smile.png

Don't forget to replace the padding variable position! Your application is working correctly because you're not using the ambient light color and the light diffuse alpha but once you starting using them incorrect padding will cause errors.

This topic is closed to new replies.

Advertisement