OK. So I implemented lighting from this tutorial: http://www.catalinzima.com/xna/tutorials/deferred-rendering-in-xna/directional-lights/
Why do I've wrong specular highlights? directional light's direction is (0.0f, -1.0f, 0.0f)
it is straight down so why are specular hightlights wrong (at up)?
My deferred renderer:
#include "LightHelper.fx"
//================================
//DeferredRenderer: Renders lighting info to gbuffers
//DefferedRenderer.fx by newtechnology
//================================
cbuffer cbPerObject
{
float4x4 gWorld;
float4x4 gWorldViewProj;
float4x4 gWorldInvTranspose;
float4x4 gTexTransform;
Material gMaterial;
};
cbuffer cbFixed
{
const float AOFactor = 0.4f;
const float SpecIntensity = 0.8f;
const float specPower = 0.5;
};
struct VertexIn
{
float3 PosL : POSITION;
float3 NormalL : NORMAL;
float2 Tex : TEXCOORD;
float3 TangentL : TANGENT;
};
struct VertexOut
{
float4 PosH : SV_POSITION;
float3 PosW : POSITION;
float3 NormalW : NORMAL;
float2 Tex : TEXCOORD;
float3 TangentW : TANGENT;
};
SamplerState samLinear
{
Filter = MIN_MAG_MIP_LINEAR;
AddressU = WRAP;
AddressV = WRAP;
};
Texture2D gDiffuseMap;
Texture2D gNormalMap;
VertexOut VS(VertexIn vin)
{
VertexOut vout;
vout.PosW = mul(float4(vin.PosL, 1.0f), gWorld).xyz;
vout.NormalW = mul(vin.NormalL, (float3x3)gWorldInvTranspose);
vout.TangentW = mul(vin.TangentL, (float3x3)gWorld);
vout.PosH = mul(float4(vin.PosL, 1.0f), gWorldViewProj);
vout.Tex = mul(float4(vin.Tex, 0.0f, 1.0f), gTexTransform).xy;
return vout;
}
struct PixelOut
{
float4 Color : SV_Target0;
float4 Normal : SV_Target1;
float4 Position : SV_Target2;
};
PixelOut PS(VertexOut pin) : SV_Target
{
PixelOut Out;
pin.NormalW = 0.5f * (normalize(pin.NormalW) + 1.0f);
float3 color = gDiffuseMap.Sample(samLinear, pin.Tex).rgb;
//output lighting info to gbuffer
Out.Color = float4(color, specPower);
Out.Normal = float4(pin.NormalW, SpecIntensity);
Out.Position = float4(pin.PosW, AOFactor);
return Out;
}
technique11 BuildGBuffers
{
pass P0
{
SetVertexShader( CompileShader(vs_4_0, VS() ) );
SetGeometryShader( NULL );
SetPixelShader( CompileShader(ps_4_0, PS() ) );
}
}
My Directional light:
#include "LightHelper.fx"
SamplerState samPoint
{
Filter = MIN_MAG_MIP_POINT;
AddressU = CLAMP;
AddressV = CLAMP;
};
cbuffer cbPerObject
{
float4x4 gWorldViewProj;
};
cbuffer cbPerFrame
{
float3 gEyePosW;
Material gMaterial;
DirectionalLight gLight;
};
//gbuffers
Texture2D gColorMap;
Texture2D gNormalsMap;
Texture2D gPositionMap;
struct VertexIn
{
float3 PosL : POSITION;
float2 tex : TEXCOORD;
};
struct VertexOut
{
float4 PosH : SV_POSITION;
float2 tex : TEXCOORD;
};
VertexOut VS(VertexIn vin)
{
VertexOut vout;
vout.PosH = mul(float4(vin.PosL, 1.0f), gWorldViewProj);
//no transformation required here
vout.tex = vin.tex;
return vout;
}
float4 PS(VertexOut pin) : SV_Target
{
//Sample textures (gbuffers)
float4 color = gColorMap.Sample(samPoint, pin.tex);
float4 normal = gNormalsMap.Sample(samPoint, pin.tex);
float4 position = gPositionMap.Sample(samPoint, pin.tex);
//extract material properties from alpha channel of all 3 textures
float specPower = color.a * 255;
float specIntensity = normal.a;
float AOFactor = position.a;
float3 normalW = 2.0f * normal.rgb - 1.0f;
float3 lightVector = float3(0.0f, 1.0f, 0.0f); // -(0.0f, -1.0f, 0.0f) = (0.0f, 1.0f, 0.0f); -> -(-1) = +1
lightVector = normalize(lightVector);
float NdL = saturate(dot(lightVector, normalW));
float3 DirectionToCamera = normalize(gEyePosW - position.xyz);
float3 reflectionVector = normalize(reflect(lightVector, normalW));
float SpecularLight = specIntensity * pow(saturate(dot(reflectionVector, DirectionToCamera)), specPower);
// float3(1.0f, 1.0f, 1.0f) is light's color
float3 DiffuseLight = (NdL * float3(1.0f, 1.0f, 1.0f)) + AOFactor;
float3 finalcolor = color.rgb * DiffuseLight + SpecularLight;
return float4(finalcolor, 1.0f);
}
technique11 DeferredLighting
{
pass P0
{
SetVertexShader( CompileShader( vs_4_0, VS() ) );
SetGeometryShader( NULL );
SetPixelShader( CompileShader( ps_4_0, PS() ) );
}
};