Here is my HLSL code for the wave in the vertex shader:
// Change the position vector to be 4 units for proper matrix calculations. input.position.w = 1.0f;
// Offset position based on sine wave
input.position.y = height * sin(input.position.x + time) * sin(input.position.y + time);
df_dx = height*cos(input.position.x + time)*sin(input.position.y + time); //tangent along x axis
df_dy = height*sin(input.position.x + time)*cos(input.position.y + time); //tangent along y axis
/*
k = height*(sin(input.position.x + time)*cos(input.position.y + time) - cos(input.position.x + time)*sin(input.position.y + time));
n = (-input.position.y*k, input.position.x*k, 0.0f);
*/
n = cross(df_dx, df_dy);
input.normal.x = n.x;
input.normal.y = n.y;
// Calculate the normal vector against the world matrix only.
output.normal = mul(input.normal, (float3x3)worldMatrix);
// Normalize the normal vector.
output.normal = normalize(output.normal);
And the code for my pixel shader, I pass the viewDirection in from the vertex shader aswell as the normals:
float4 textureColour;
float3 lightDir;
float lightIntensity;
float4 colour;
float4 specular;
// Sample the pixel color from the texture using the sampler at this texture coordinate location.
textureColour = shaderTexture.Sample(SampleType, input.tex);
// Invert the light direction for calculations.
lightDir = -lightDirection;
// Set the default light value for all pixels
colour = (0.5f, 0.5f, 0.1f, 0.5f);
specular = (0.0f, 0.0f, 0.0f, 0.0f);
// Calculate the amount of light on this pixel.
lightIntensity = saturate(dot(input.normal, lightDir));
// Determine the final amount of diffuse color based on the diffuse color combined with the light intensity.
if (lightIntensity > 0.0f)
{
colour += (diffuseColour * lightIntensity);
// Saturate the ambient and diffuse Colour
colour = saturate(colour);
// Calculate the reflection vector based on the light intensity, normal vector and light direction.
reflection = normalize(2 * lightIntensity * input.normal - lightDir);
//reflection = reflect(-lightDir, input.normal);
// Determine the amount of specular light based on the reflection vector, viewing direction, and specular power
specular = pow(saturate(dot(reflection, input.viewDirection)), SpecularPower);
// Sum up Specular light
//finalSpec = SpecularColor * specular;
}
// Multiply the texture pixel and the final diffuse color to get the final pixel color result.
colour = colour * textureColour;
// Add the specular component last to the output colour
colour = saturate(colour + specular / 2);
return colour;