Sign in to follow this  
m4gnus

normals getting displayed wrong

Recommended Posts

m4gnus    240
i didn't want to revive my old funky normals thread but i've got some new infos that may help to solve my problem. For those who haven't read my old thread: (I thought that!!)The problem is that my function for calculating the normals of my mesh doesn't work right. I first tested it with 2 cubes(both cubes in 1 Vertexbuffer) and the normals of the first cube were alright while the ones from the second cube weren't. For testing purpose i simply exported 2 seperated triangles lying on the x/z plane and all normals(for both triangles) were wrong. I tested if my code calculates the right normals and noticed that even in the vertex buffer the normals are correct(see screenshot below). But when i show the normals as colors with my pixelshader i get this: clicky but when i lock my buffer just before rendering and look at the memory inside the buffer everything looks fine:(the floats surrounded by the blue boxes are the normals) clicky and the vertex decl used is: clicky (also checked right before rendering with
	D3DVERTEXELEMENT9 decl[256];
	UINT numElements;
	HRESULT hr = vertexdecl->GetDeclaration( decl, &numElements);

) my rendering function looks like this:
void Draw(ngVertexBuffer *pvbuffer,ngIndexBuffer *pibuffer)
{
	ngEngine &engine=ngEngine::getInstance();
	
	int vertexsize=pvbuffer->getVertexsize();
	int triangleCount=pibuffer->getLength()/3;
	LPDIRECT3DVERTEXBUFFER9 vbuffer=pvbuffer->getD3DVBuffer();
	LPDIRECT3DINDEXBUFFER9 ibuffer=pibuffer->getD3DIBuffer();
	DWORD fvf=pvbuffer->getFVF(); //just switched 2 vertexdecls recently...
	DWORD vlength=pvbuffer->getLength();
	LPDIRECT3DVERTEXDECLARATION9 vertexdecl=pvbuffer->getVertexDecl();

	D3DVERTEXELEMENT9 decl[256];
	UINT numElements;
	HRESULT hr = vertexdecl->GetDeclaration( decl, &numElements);
	void *pOut;
	//vbuffer->Lock(0,0,&pOut,0);

	//engine.g_pD3DDevice->SetRenderState(D3DRS_FILLMODE,D3DFILL_SOLID);
	engine.g_pD3DDevice->SetVertexDeclaration(vertexdecl);
	//engine.g_pD3DDevice->SetFVF(fvf);
	engine.g_pD3DDevice->SetStreamSource(0,vbuffer,0,vertexsize);
	engine.g_pD3DDevice->SetIndices(ibuffer);
	engine.g_pD3DDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,0,0,pvbuffer->getLength(),0,triangleCount);
}




All that looks quite correct to me. So maybe the error is in the shader:
float3 lightVector;
float4x4 matView : View;
float4x4 matProjection : Projection;
float4x4 matWorld : World;
float4x4 matWorldViewProjection : WorldViewProjection;

struct VS_INPUT 
{
   float3 Position : POSITION0;
   float2 uv : TEXCOORD0;
   float3 Normal : NORMAL0;
};

struct VS_OUTPUT 
{
   float3 normal : TEXCOORD1;
   float2 uv : TEXCOORD0;
   float4 Position : POSITION0;
   
};

struct PS_INPUT 
{
   float3 normal : TEXCOORD1;
   float2 uv : TEXCOORD0;
   float4 Position : POSITION0;
   
};


VS_OUTPUT Position_Pass_0_Vertex_Shader_vs_main( VS_INPUT Input )
{
   VS_OUTPUT Output;
   float4 n=mul(float4(Input.Normal,1.0f), matWorld);
   //Output.normal = float3(n.x, n.y, n.z);
   Output.uv=Input.uv;
   Output.normal = Input.Normal;
   Output.Position = mul(float4(Input.Position,1.0f), matWorldViewProjection);
   return( Output );
   
}

float4 Position_Pass_0_Pixel_Shader_ps_main(PS_INPUT Input) : COLOR0
{   	
   //float3 light=normalize(float3(1.0f,1.0f,1.0f));
   //return float4(1.0f,0.0f,0.0f,1.0f)*dot(normalize(normal),lightVector);
   return float4(Input.normal,1.0f);
}

//--------------------------------------------------------------//
// Technique Section for Position
//--------------------------------------------------------------//
technique Position
{
   pass Pass_0
   {
      PixelShader = compile ps_2_0 Position_Pass_0_Pixel_Shader_ps_main();
      VertexShader = compile vs_2_0 Position_Pass_0_Vertex_Shader_vs_main();
   }

}





hopefully somebody spots the problem. I really have no clue how that is possible. regards, m4gnus [Edited by - m4gnus on April 23, 2006 3:57:20 AM]

Share this post


Link to post
Share on other sites
jollyjeffers    1570
Normals are defined between [-1,+1], but the colour your emitting is [0,1] - so you're effectively chopping off half of your normal [smile]

Values in normal-maps have similar problems. It's usual to encode them using:

float3 Encoded = (Normal + 1.0f) / 2.0f;

and decode using:

float3 Decoded = (Normal * 2.0f) - 1.0f;

Therefore a (0,0,1) normal becomes RGB(128,128,255) and the opposite (0,0,-1) normal becomes RGB(128,128,0)...

hth
Jack

EDIT: changed "/" to "*"..

[Edited by - jollyjeffers on April 23, 2006 10:22:13 AM]

Share this post


Link to post
Share on other sites
m4gnus    240
ok fixed that. Now it looks like this:
clicky
Sadly still wrong. The triangles should be all green.(theoretically, in fact the normal of the one triangle is (0,-1,0))

thx for reply

regards,
m4gnus

Share this post


Link to post
Share on other sites
ET3D    810
Your vertex declaration puts all components at offset 0, which is obviously wrong. When using FVF it was probably wrong because in an FVF the normal always comes before the UV coords in the structure.

What ends up happening is that the data you're reading as normals is some other data stored in the vertex.

Share this post


Link to post
Share on other sites
m4gnus    240
are these offsets the offsets from the vertex start to a specific element? i thought they had somehting to do with the streams.
i think i fixed that now. i changed Offset=0; to Offset=(unsigned char*)pointerToVertexElement-(unsigned char*)vertexStart;
everything is right one tri is green and the other one purple(because it's normal points downwards)

Thank you very much guys.

regards,
m4gnus

Share this post


Link to post
Share on other sites
matches81    474
Quote:
Original post by jollyjeffers
Values in normal-maps have similar problems. It's usual to encode them using:

float3 Encoded = (Normal + 1.0f) / 2.0f;

and decode using:

float3 Decoded = (Normal / 2.0f) - 1.0f;


Don´t want to be nit-picky or anything, but I think it should be

float3 Decoded = (Normal * 2.0f) - 1.0f;

just wanted to mention that.

Share this post


Link to post
Share on other sites
jollyjeffers    1570
Quote:
are these offsets the offsets from the vertex start to a specific element?
Yeah, a '0' offset is the start of each vertex..

Quote:
Original post by matches81
Quote:
Original post by jollyjeffers
Values in normal-maps have similar problems. It's usual to encode them using:

float3 Encoded = (Normal + 1.0f) / 2.0f;

and decode using:

float3 Decoded = (Normal / 2.0f) - 1.0f;


Don´t want to be nit-picky or anything, but I think it should be

float3 Decoded = (Normal * 2.0f) - 1.0f;

just wanted to mention that.
[embarrass] Looks like you got me there!

Thanks for pointing that out.

Jack

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this