   What's wrong with my Phong?
  Hi,I cribbed the Phong shader from Rendermonkey into my program, removing the texturing to just get a pure Phong without a base map.  It works nicely in Rendermonkey, but my version of it produces the following result (YouTube):">Wrong Phong I put the camera/eye-point at 0, -2, -2 (the quad is defined in the XY plane at 0, 0) and the light position at 0, 0, -4.  I can't get my head around what's going on here - the light seems to be stuck to the surface as if it's a texture.  I'm sending in the view matrix from the camera ok as far as I can see.Here's the code:float4x4 MyWorldMatrix;float4x4 MyViewMatrix;float4x4 MyProjectionMatrix;float4 MyLightPosition;float4 MyEyePosition;float4 MyAmbientColour;float4 MySpecularColour;float4 MyDiffuseColour;float MySpecularPower;struct Vertex{float4 xyz: POSITION;  float3 ViewDirection: TEXCOORD0;float3 LightDirection: TEXCOORD1;float3 Normal: TEXCOORD2;};Vertex VERTEXMAIN(float4 xyz: POSITION,float4 normal : NORMAL){float4 view;view = mul(xyz, MyWorldMatrix);   float4 screen;screen = mul(view, MyViewMatrix);Vertex result;result.xyz = mul(screen, MyProjectionMatrix);float3 objectPosition = mul(xyz, MyViewMatrix).xyz;result.ViewDirection = (MyEyePosition.xyz - objectPosition);result.LightDirection = (MyLightPosition.xyz - objectPosition);result.Normal = mul(normal, MyViewMatrix).xyz;return (result);}struct Pixel{    float4 rgba : COLOR0;  // Pixel color    };Pixel PIXELMAIN(Vertex vertex) { float3 lightDirection = normalize(vertex.LightDirection);float3 normal = normalize(vertex.Normal);float3 viewDirection = normalize(vertex.ViewDirection);float normalDotLight = dot(normal, lightDirection); float3 reflection = normalize(((2.0f * normal) * (normalDotLight)) - lightDirection);float reflectionDotViewDirection = max(0.0f, dot(reflection, viewDirection));float4 totalDiffuse = MyDiffuseColour * normalDotLight;float4 totalSpecular = MySpecularColour * pow(reflectionDotViewDirection, MySpecularPower);Pixel colour;colour.rgba = saturate(MyAmbientColour + totalDiffuse + totalSpecular);return colour;}If anyone has any thoughts occur, I'd really appreciate hearing them ;).Thanks.   
  Hi,I'm not sure if I understood it right, but it seems to me you are forgetting something atfloat3 objectPosition = mul(xyz, MyViewMatrix).xyz;Why would you transform it by the view, instead of the modelview?Also, if you convert your object to the camera coordinate system, you should convert the light and the camera too (which you could then just use as the origin).Good Luck, and let us know if it worked :)   ;Thanks, I appreciate your reply.  The only reason I was transforming by the view matrix was because that's what the Rendermonkey "default" textured-phong shader does (math isn't my strong point, so I was cribbing this stuff from elsewhere). Anyway I changed it to transform the object position with the (world * view) matrix (is that what you mean by modelview?) and I get a result:">Wrong Phong II(^ note that this shows what I'm trying to do here - I have an emissive surface height-field with a border and base I'd like to render with Phong).  As you can see from the movie, the borders aren't showing the shading correctly and neither is the base, although the base is something of an improvement from the previous attempt.)I'm pretty sure my normals are all screwed up though; I should point out that I have a non-uniform scale in the world matrix for that object.  For various reasons the geometry is defined from 0..1 on all 3 axes and then scaled to whatever the UI needs to display (in this case it's 3 x 1.5 x 0.8 high).  I do this because I need to keep the field in a fixed screen position of fixed size to perform zoom and pan without changing the camera.  In fact I zoom and pan the field by changing the index buffer, rather than by moving the camera.  I read somewhere that a non-uniform scale screws up the normals.  I also read that you can unscrew them by multiplying the inverse transpose of the world matrix and then re-normalising.  I tried this but it didn't work out - I just got some vague greyness all over, so I'm not sure what to do next.Note that I know the surface winding order must be ok, because I've got CULL_CCW switched on, so I'm guessing if they weren't some bits of geometry would have gone AWOL.;  Did you try to multiply the light coordinates by the modelview? (yes, this is what I mean by modelview)Also, you could try to substitute your eyePosition then by (0,0,0) which would give you a "result.ViewDirection = (MyEyePosition.xyz)."The normals should indeed be multiplied by the inverse transpose of the modelview. You are multiplying only by the view right now.You must think like that:object coordinates --[model matrix]--> world coordinates ---[view matrix]--> camera coordinates --[projection matrix]--> screen coordinates.If you don't have all your variables in the same coordinate system, you'll never be able to make a decent calculation. I advice you to transform everything to the camera coordinates, this way you don't have to worry about where your camera is.Good Luck,;  Ok, so the following:float3 objectPosition = mul(xyz, MyModelViewMatrix).xyz;result.ViewDirection = (MyViewDirection - objectPosition);result.LightDirection = (MyLightDirection - objectPosition);result.Normal = mul(normal, MyModelViewMatrix).xyz;should be something like:float3 objectPosition = mul(xyz, MyModelViewMatrix).xyz;float3 lightDirection = mul(MyLightDirection, MyViewMatrix).xyz; result.ViewDirection = -objectPosition;result.LightDirection = (lightDirection - objectPosition);result.Normal = mul(normal, MyInverseTransposeModelViewMatrix).xyz;If I'm transforming the object position to camera coords, then I don't need to transform the view direction because the camera is at the origin relative to the transformed vertex, but I do need to transform the light position by the view matrix.  Finally, I need to transform the normal by the inverse transpose of the model view?I tried using PIX to debug the shader to see what the values were doing, but it seems to only allow me to debug pixels in assembler, not HLSL :(.  It would be useful to be able to see exactly what's going on inside the shader!;  Hi,RenderMonkeys row/col major is, by default, the opposite to Direct3D i believe. You can debug in HLSL, have a look at the D3DXCreateEffectFromFile() flags parameter and add the skip optimisation and profiling and add the debugging ones. I think you also need to create the device with the software vertex processing.It's been a while however so i could be wrong.   ;  Wasn't that dropped in 2008/2010? (I'm using 2010 at the moment).   ;  Wasn't what dropped?   ;  Shader debugging... didn't there used to be a menu option in VS 2005 for it?   ;  Oh, yeah it used to be in 2005, but you should be using Pix For Windows now (which comes with the SDK) for all your Direct3D debugging needs.   