# Doubts with results of per-vertex lighting shader

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.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.

• I don't know if it's the only issue but, if dot(N, L)) is negative, specular should not be added.
– Jon
Mar 15, 2016 at 2:02
• Also, does DX not complain about materialProperties not being a multiple of 4?
– Jon
Mar 15, 2016 at 2:20
• materialProperties is already padded to multiple of 16-bytes in the constant buffer creation (CPU-side). 2) I do [ sat(V*R) ]^s where s=specular power. Sat(x) clamps the dot product between 0 and 1. Thanks. Mar 15, 2016 at 3:10
• If you are, for some reason, actually drawing backfaces: CPU-side, please normalize (1,-1,0), reflect it against both (0,1,0) and (0,-1,0), and inspect the results.
– Jon
Mar 15, 2016 at 4:49