I'm researching simple shaders to add to my DirectX 11 project such as a per-vertex diffuse shader plus specular reflection component.
I'll begin with the results:
Seems specular reflection is working, but do you see the border and upper objects? They don't seem to be lit well, as a shader based on this lighting equation is not supposed to gray-scale the diffuse component (excepting when dot product < 0 in backfaces,etc).
My HLSL vertex shader rationale is as follows, I dont know at this point of the day, if i'm missing something.
Vertex shader input / Output structs are defined as:
// Output and Input Structs
// ------------------------
struct VS_OUTPUT {
float4 pos : SV_POSITION;
float4 color : COLOR;
};
struct VS_INPUT {
float4 pos : POSITION;
float4 norm: NORMAL;
};
1) Transform the input position to world coordinates:
vo.pos = mul(vi.pos, worldMatrix);
2) Transform normal to world and normalize:
float4 N = normalize(mul(vi.norm, worldMatrix));
3) Calculate the vector from the light position to the current vertex position. Lighting is already in world coordinates. w=1.0, so:
float4 L = float4(normalize(float4(light[0].pos.xyz,1.0f) - vo.pos));
I have camera position in world coordinates passed through Cbuffer, so camera minus vertex position yields V vector.
float4 V = normalize(cameraPos - vo.pos);
4) Use reflect intrinsic to calculate R, negating L since it's pointing towards light.
float4 R = reflect(-L, N);
5) Finally I calculate the color to pass to the pixel shader, and transform the vertex position with the view/projection matrices.
vo.color = ka + ke + kd * saturate(dot(N, L)) + (ks * pow(saturate(dot(V, R)), specp));
vo.pos = mul(mul(vo.pos, viewMatrix), projMatrix);
return vo;
Just for completion, here are the constant buffers:
#define MAX_LIGHTS 16
cbuffer bufWorldMatrix : register (b0) {
float4x4 worldMatrix;
}
cbuffer bufViewProjMatrix : register (b1) {
float4x4 viewMatrix;
float4x4 projMatrix;
float4 cameraPos;
}
cbuffer materialProperties : register (b2) {
float4 kd;
float4 ka;
float4 ks;
float4 ke;
float specp; // Specular-power (shininess)
}
struct LightBase {
float3 pos;
float3 color;
float intensity;
float isOn;
};
THanks, any help is appreciated. I'm sure normals are OK, but I can recheck in case. I can post additional debugging/ code if it's required.
dot(N, L))
is negative, specular should not be added. \$\endgroup\$materialProperties
not being a multiple of 4? \$\endgroup\$