Hello, I want to add a directional light calculation to my HLSL code. What is the correct calculation of that, please somebody explain it to me !
DX11-HLSL Directional light calculation ?
Hi,
There are many ways to do directional light calculation based on your requirements.
one way to do this is by defining a light struct in your HLSL code containing a light vector member which holds your light direction , a light intensity vector and ambient light vector which roughly approximates your total ambient light since you are not calculating light bounces:
struct Directional_light
{
float3 Direction;
float pad1;
float3 Intensity;
float pad2;
float3 Ambient;
float pad3;
};
CBs in dx11 are 16 byte aligned and this is were you are going to access the light object that you map from your application. so you will have something like :
cbuffer MainCB
{
Directional_light light;
//other cb information go below
}
The second part is defining your per object material data which you can put in a sepearate constant buffer, this has to be put in a separate cbuffer because the update frequency is higher than the main scene cb. Normarlly you'll include data like roughness of the object and the diffuse albedo.
You'll typically want to do lighting in your pixel shader if performance is not your concern. So the lighting can be done by separating your ambient light contribution, diffuse term which is normally done with Lambert 's cosine law(this is easily done with dot poduct between direction light vector and the vertex normal) and specularity which measures object shininess. You do these calculations separately and add them to get the final color:
cbuffer MaterialCB
{
float4 diffuseAlbedo;
}
float4 PixelShader(float3 normal: NORMAL) : SV_TARGET
{
float4 totallight(.0f,.0f,.0f,.0f);
//caculate ambient light seperately. This just done with component wise vector multiplication
float4 ambient = light.ambient * diffuseAlbedo;
//normalise light vector.. also invert incident vector for lambert cosign law calculation
float3 lightvec = -(normalise(light.direction));
//lamberts cosine law.. the idea is if you have a small angle between light vector and vertex normal you will end up with a smaller
//value when you perform dot product. this simply says light reflection at a point increaseses intesity as the angle between the light
//vec and normal gets smaller this is (view point independent)
float diffuseStrength = max(dot(lightvec, normal), 0.0f);
float4 diffuse = diffuseStrength * diffuseAlbedo;
float4 totallight = ambient + diffuse;
return totallight;
}
I think this is the general idea. I've skipped most details out .