Actually this is a math question ... any egg head want to help a simpleton ?

Started by
13 comments, last by TSEDSE 15 years, 8 months ago
Hello, I cant seem to get this working as I require. Anyone tell me why ? (Really sorry if this is mega simple, I am learning and trying to get this working). The stuff below relates to my vs and ps in an fx file. The fx file has this at the top - float3 lightpos; // light position in world coordinates The vertex shader has this in it - float4 pos=float4(IN.pos.x, IN.pos.y, IN.pos.z, 1.0); OUT.pos=mul(pos, world_matrix);// world_matrix = rot, scale, trans of object float4 lp = float4(lightpos.x, lightpos.y, lightpos.z, 1); OUT.lightpos = lp; OUT.normal=mul(IN.normal, world_matrix); And the pixel shader does this - float3 l = normalize(IN.pos-IN.lightpos.xyz); float3 normal = normalize(IN.normal); float diff=saturate(dot(l, normal.xyz)); return diff; Now I am trying to get some clubs that are in the hands of my skinned creature to diffuse correctly. Now the qeird bit - his right club works perfectly with - float3 l = normalize(IN.pos-IN.lightpos.xyz); his left club works with this - float3 l = normalize(IN.lightpos.xyz-IN.pos); What do I need to change to get this to work for both at the same time ? Please help as I am knackered. Thanks, TSEDSE
Advertisement
I can't see anything wrong here.
You're shure that the normals are transfered in world space? If they are, where is the light source?

Please use the code tag to highlight code, otherwise reading it becomes painful.
Thanks for the reply. I pass in a translation for the creature and then the skinned mesh is output correctly at the correct lcoation/rotation/etc with perfect diffusion, etc using a different fx file. The code then tries to render the items which dont have skinning info which are part of the same animation, it uses the code above. The world_matrix appears to be correct because the items are placed correctly in his hands, etc and move with the animation. I am definately multiplying the IN.normal by the same world_matrix. Its weird because it works for each club independently (apart from the swapping of the params) as stated above ...

Any tests or ideas I can do to try and get a handle of what is happening here ?

Thanks again for your help. The rendering looks awesome at the moment apart from this ...

Sorry didnt answer one bit. The translation I am using is matrix.translation(0,0,0), the model is centered on 0,0,0 and the light is at x=200,y=200,z=0.
Are you trying to access the POSITION register in the pixel shader? If so, you can't. Pass your position in a TEXCOORDn register as well if you need to access it in the pixel shader.

If this isn't the case, then it sounds like maybe the normals on one side of your mesh are flipped.

Regards,
ViLiO
Richard 'ViLiO' Thomasv.net | Twitter | YouTube
I pass the normal in a texture register (float4 pos : TEXCOORD2;) so that should be cool. Is there an easy way I can check if the normals are inverted ?
Quote:Original post by TSEDSE
I pass the normal in a texture register (float4 pos : TEXCOORD2;) so that should be cool. Is there an easy way I can check if the normals are inverted ?
It was the line "float3 l = normalize(IN.pos-IN.lightpos.xyz);" I was referring to, if IN.pos is the POSITION register then that shouldn't even compile [smile]

As for checking if the normals are inverted, I think you already have proved they are, but you may want to render your normals as a line list or something (just for debug purposes) or just output half4(normal.xyz, 1.f); as the colour from the pixel shader and show a screenshot of what it looks like.

All the best,
ViLiO
Richard 'ViLiO' Thomasv.net | Twitter | YouTube
Actually thinking about this. I have tried using a different model (the club model loaded separately and checked for correctness rendering elsewhere) and when I apply the combined transformation from the skinning info one of the clubs is spot on and the other gets rendered inside out, so I can see the back of it instead of the front. How can a matrix do this ? This is the same model used twice so has any one got any ideas ... my head hurts.
Sorry, yes IN.pos is transferred in a tex reg.
Hi TSEDSE, I'm learning too and I'm not sure I'll be helpful, however I'll try :-)

It really looks like the normals on your clubs in object space (before any transforming) are not set properly. Or maybe they are, are you sure that the behaviour is not correct? For instance, if the light is between the clubs both the inner sides of both clubs would be lit; otherwise if the light is outside the arms you should see that the inner side of one club is lit, and the outer side of the other one is lit.

And what is exactly your world matrix? Does it include also some kind of projection? If it does then the fourth coordinate of pos after the mul(pos, world_matrix) may not be one. Just out of curiosity try to multiply also lp by the same matrix, and in the pixel shader try to do IN.pos-IN.lightpos instead of IN.pos-IN.lightpos.xyz.

And if there is a projection, I'm not sure you can do light computation in that space.

For me the following works, but for sure there is a better way to do it. For me, the player position is itself the light position (as in Quake when you pick up the quad damage :-).

struct VS_Input{	float4 position : POSITION;	float3 normal : NORMAL;};struct PS_Input{	float4 wvpPosition : POSITION;	float4 wvPositionTC : TEXCOORD1;	float3 wvNormal : TEXCOORD2;};struct PS_Output{	float4 color : COLOR0;};PS_Input VS(VS_Input vsIn){	PS_Input psIn;		psIn.wvpPosition = mul(vsIn.position, worldViewProjection);	psIn.wvPositionTC = mul(vsIn.position, worldView);	psIn.wvNormal = mul(vsIn.normal, worldView);		return psIn;}PS_Output PS(PS_Input psIn){	PS_Output psOut;		float3 n;	float3 obsDir = normalize(-psIn.wvPositionTC);		if (dot(psIn.wvNormal, obsDir) > 0)	{		n = normalize(psIn.wvNormal);	}	else	{		n = -normalize(psIn.wvNormal);	}		float3 light = normalize(float4(0.0f, 0.0f, 0.0f, 1.0f) - psIn.wvPositionTC);		psOut.color = float4(1.0f, 0.0f, 0.0f, 1.0f) * dot(light, n);		return psOut;}


Hope to have been helpful! Bye!

This topic is closed to new replies.

Advertisement