Specular Highlight - fx-File - Vertexshader only

Started by
1 comment, last by Nicholas1991 11 years, 8 months ago
Hi guys,

I had to stop working on my Game for quiete some time but now I am continuing with Susanne Wigard's Book on how to programm a basic game engine.

Now I copied the fx-File from the CD that came with the book but for some reason my specular-light-dot is not behaving as planned (see pictures below).
The fx-File:

//--------------------------------------------------------------------------------------
// Datei: Glanzlicht.fx
//
// Glanzlicht
//
// Susanne Wigard 2009
//--------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------
// Global variables
//--------------------------------------------------------------------------------------
cbuffer cb0 //Standardshader
{
float4 g_MaterialAmbientColor; // Material's ambient color
float4 g_MaterialDiffuseColor; // Material's diffuse color
float3 g_vLightDir; // Light's direction in world space, normalized
float4 g_LightDiffuse; // Light's diffuse color
float g_fTime; // App's time in seconds
float4x4 g_mWorld; // World matrix for object
float4x4 g_mWorldViewProjection; // World * View * Projection matrix
}
cbuffer cb1 //Für Glanzlicht
{
float4 g_LightSpecular = float4(1, 1, 1, 1);
float g_SpecularPower;

float4x4 g_mView;
float4x4 g_mProj;
}
//--------------------------------------------------------------------------------------
// Vertex shader output structure
//--------------------------------------------------------------------------------------
struct VS_OUTPUT
{
float4 Position : SV_Position; // vertex position
float4 Diffuse : COLOR0; // vertex diffuse color (note that COLOR0 is clamped from 0..1)
float2 TextureUV : TEXCOORD0; // vertex texture coords
};
//--------------------------------------------------------------------------------------
// Vertexshader mit Glanzlicht
//--------------------------------------------------------------------------------------
VS_OUTPUT RenderMitGlanzlichtVS( float4 vPos : POSITION,
float3 vNormal : NORMAL)
{
VS_OUTPUT Output;
float4 worldPos = mul(vPos, g_mWorld);
float4 cameraPos = mul(worldPos, g_mView); //Position im Koordinatensystem der Kamera
Output.Position = mul(cameraPos, g_mProj);
float3 vNormalWorldSpace;
vNormalWorldSpace = normalize(mul(vNormal, (float3x3)g_mWorld)); // normal (world space)
float3 halfAngle = normalize(normalize(-cameraPos) + g_vLightDir);
float NDotH = max(0, dot(halfAngle, vNormalWorldSpace));
Output.Diffuse.rgb = g_MaterialDiffuseColor * g_LightDiffuse *
max(0,dot(vNormalWorldSpace, g_vLightDir))
+ g_LightSpecular * pow(NDotH, g_SpecularPower)
+ g_MaterialAmbientColor;
Output.Diffuse.a = 1.0f;

return Output;
}
//--------------------------------------------------------------------------------------
// Standard-Pixelshader ohne Textur
//--------------------------------------------------------------------------------------
float4 SimplePS( VS_OUTPUT In ) : SV_Target
{
return In.Diffuse;
}
//--------------------------------------------------------------------------------------
// Rendern mit Glanzlicht ohne Textur
//--------------------------------------------------------------------------------------
fxgroup Glanzlicht
{
technique11 RenderMitGlanzlicht
{
pass P0
{
SetVertexShader( CompileShader(vs_4_0, RenderMitGlanzlichtVS()));
SetGeometryShader( NULL );
SetPixelShader( CompileShader(ps_4_0, SimplePS()));
}
}
}



What happens is.... strange. The diffuse and the ambient light work as intended. The specular lighting however screws up.
Lets say the Sphere is always centered around (0,0,0) and has a radius of 2.0f.
The Camera starts at (0.0f, 0.0f, 5.0f) and is directed towards (0,0,0).
The light source ist at (0,0,10.0f) and it's direction vector is (0,0,1.0f).

Then I see the following:
(pictures attached with 1_ prefix)
[attachment=11126:1_beginning.png]
[attachment=11127:1_looking_up_slightly.PNG]
[attachment=11128:1_moving_to_the_right_looking_down_slightly.png]

However, if I change the light source to (10.0f, 0, 0) pointing at (1.0f,0,0) I see the following:
(pictures attached with 2_ prefix)
[attachment=11129:2_beginning.png]
[attachment=11130:2_moving_to_the_left.png]
[attachment=11131:2_moving_to_the_left_and_up.png]

As you can see in the second setup the white spot is not moving at all.

I mean the view matrix is used for the specular highlight but also for the calculation of the output position, so I assume it is correctly set. Maybe something went wrong during vector conversions (3 and 4 entries)? Or is it something more obvious? biggrin.png

Yours,
Nicholas


P.S.: I've only started working with different rendering techniques. Up until now I always used a default fx-file so please keep it simple ;).
Advertisement
When calculating the half vector, what you want is the view direction. This is a normalized vector pointing from the surface towards the camera. What you're doing is taking the view space position and negating it, which is equivalent to (0, 0, 0) - viewSpacePosition gives you the view direction in view space. However your normal and I'm assuming your light direction are in world space, so you'll want the world space view direction. You should pass in the world space camera position through a constant buffer, then use normalize(g_cameraPositionWorldSpace - worldPos.xyz) when calculating your half vector.
Thank you,
works like a charm!

Yours,
Nicholas

This topic is closed to new replies.

Advertisement