0

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;

1 Answers1

0

The line

n = cross(df_dx, df_dy);

seems weird - I believe cross expects 3d vectors as arguments, but df_dx and df_dy appear to be scalars.

Perhaps the vectors you want here are (1.f,0.f,df_dx) and (0.f,1.f,df_dy)?

Ap31
  • 3,244
  • 1
  • 18
  • 25
  • Even with that addition there is no change to the lighting in the scene, when i remove the wave movement and the normal recalculations the lighting works fine but with the movement and recalculated normals there is no specular lighting on the waves. – Niall Clarke Feb 28 '17 at 21:19
  • maybe your normal is inversed and you need to swap the vectors you pass to `cross`. At this point you need to figure out what's going on with your normals, so you can replace the pixel shader output with `0.5f*(input.normal + 1.f)` – Ap31 Mar 01 '17 at 06:41
  • Yeah that still makes no change, am I calculating the normals correctly for the equation im using to create the waves? – Niall Clarke Mar 02 '17 at 19:09
  • you mean the derivatives? yeah, they seem to be ok, can you upload a screenshot with normal-coloring? – Ap31 Mar 02 '17 at 19:17
  • ok well it's definetly has to do with the normals, can you do the normal coloring as I said? just `colour.rgb=0.5f*(input.normal + 1.f);` in the end of pixel shader – Ap31 Mar 03 '17 at 05:17
  • https://ibb.co/mkjSTv This has the wave movement on, the lights move with the in the direction the waves are moving. – Niall Clarke Mar 03 '17 at 21:06
  • first of all, why is it still textured? are you sure you've inserted `colour.rgb=0.5f*(input.normal + 1.f);` at the *very end*? Anyway, I've noticed you're ignoring the z coordinate of the cross product, why is that? Should be just `input.normal = cross(df_dx, df_dy);` – Ap31 Mar 04 '17 at 05:46
  • Yeah sorry I put it in after i returned the colour, ive made both those changes now and still no change, im really stuck on whats going wrong. https://ibb.co/nkpQFa – Niall Clarke Mar 05 '17 at 15:11
  • That's ok, it's just somewhat hard to debug. By the way you can debug shaders for a specific pixel if you want, I just feel like there is no need for that is this case. From your screenshot you can see that the normal is the same for all the pixels, so this is not quite right. You can try assigning `sin(input.position.xyz)` to the `output.normal` just to check if input position changes at all and that it reaches the pixel shader – Ap31 Mar 05 '17 at 20:33