Sign in to follow this  

DOT3 Product problem

Recommended Posts

Koobazaur    1264
EDIT: fixed my original problem but still not quite there yet: I am trying to do bump mapping using a normal map and DOT3 product but it's looking a bit off. It seems like the highlights are more prominent if the light is to the left or top of the texture; even if the light is too far you just see black shape with the white top/left highlights. Any idea why? The way I do it is by calculating the Vector to Light and storing it in each vertexe's diffuse value. I then use the DOT3 operator between the texture (normal map) and the Diffuse value. It doesn't work. However, if I use TextureFactor instead of diffuse, it works fine. Also, I know for a fact my VectorToLight values and my normal maps are calculated and stored correctly. EDIT: If I turn lighting off, the highlights are correct..? Here's my Vertex definition:

class cVertexBM
 float x, y, z;			//coordinates of the vertex
 float nx, ny, nz;		//normal vector of the vertex
 DWORD diffuse;			//diffuse color
 float u, v;			//texture coordinates of the vertex

Creating my mesh:
// Loads level from an X file
bool cLevel::LoadFromX(string filename, IDirect3DDevice9 ** D3D9Device)
 ID3DXBuffer * MaterialBuffer =0;			//Material Buffer
 ID3DXBuffer * AdjecencyInfo =0;			//Adjecency Info
 D3DXMATERIAL * MaterialBufferAccess =0;	//Pointer to access material buffer
 IDirect3DTexture9 * tex = 0;				//temporary texture used when loading from file
 string TextureFilename;					//file name of a texture to load

 //clear the mesh if it already exists
 if(mesh != 0)

  HRESULT result;
  //load the mesh
  result = D3DXLoadMeshFromX(filename.c_str(), 
				   &mesh );
  if( result != D3D_OK)
		mesh = 0;
		return 0;

 //now, if we have material buffer and the material count is greater than 0
 if(MaterialCount != 0 && MaterialBuffer != 0)
     //first, gain access to the buffer
	 MaterialBufferAccess = (D3DXMATERIAL*)MaterialBuffer->GetBufferPointer();

	 //for every single materia...
	 for(int i = 0; i < MaterialCount; i++)
		 //add material to the list
		 MaterialBufferAccess[i].MatD3D.Ambient = MaterialBufferAccess[i].MatD3D.Diffuse;

		 //get the file name of the texture
		 TextureFilename = MaterialBufferAccess[i].pTextureFilename;
		 //if the texture is not undefined
		 if( !(TextureFilename.empty()) )
			//load and add the texture			
			if(D3DXCreateTextureFromFile((*D3D9Device), TextureFilename.c_str(), &tex)!=D3D_OK)

			//get the filename of the normal

			//construct the normal filename and load it
			TextureFilename = ConstructNormalFilename(Filename);
				if(D3DXCreateTextureFromFile((*D3D9Device), TextureFilename.c_str(), &tex)!=D3D_OK)
		 else //otherwise, add an "empty" texture
	 //we are done; release the material buffer

//convert the mesh to our format
ID3DXMesh * TempMesh = 0;
mesh->CloneMeshFVF(D3DXMESH_MANAGED | D3DXMESH_32BIT, CVERTEXBM_FVF, (*D3D9Device), &TempMesh);
mesh = TempMesh;

mesh->OptimizeInplace(D3DXMESHOPT_ATTRSORT | D3DXMESHOPT_COMPACT | D3DXMESHOPT_VERTEXCACHE, (DWORD*)AdjecencyInfo->GetBufferPointer(), 0,0,0);

//calculate normals
D3DXComputeNormals(mesh, 0);

//release adjecency

//calculate collision data
if(RetreiveCollisionData() == 0)
	return 0;

 return 1;

My Light:
// Creates omnidirection light
void CreateLight()
 //set all the values of a point light
 Light.Type				= D3DLIGHT_POINT;
 //Light.Type				= D3DLIGHT_DIRECTIONAL;
 Light.Diffuse			= D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f)*1.0f;
 Light.Ambient			= D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f)*0.0f;
 Light.Specular			= D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f)*0.0f;
 Light.Position			= D3D_Vector3(0.0f, 0.0f, -3.0f);
 //Light.Direction		= D3D_Vector3(1.0f, -0.5f, 1.0f);
 Light.Range			= 1000.0f;
 Light.Attenuation0		= 0;
 Light.Attenuation1		= 0.01;	
 Light.Attenuation2		= 0;

 //set the light
 D3D9Device->SetLight(0, &Light);
 //enable the light
 D3D9Device->LightEnable(0, true);

My Render States:
 //set default render states
 D3D9Device->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);    //counter-clockwise culling
 D3D9Device->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);  //fill solids
 D3D9Device->SetRenderState(D3DRS_NORMALIZENORMALS, true);   //renormalize all normals just in case
 D3D9Device->SetRenderState(D3DRS_LIGHTING, true);			 //enable lighting
 D3D9Device->SetRenderState(D3DRS_SPECULARENABLE, true);     //enable specular lighting


My Rendering:
  //set proper FVF
 (*D3D9Device)->SetFVF( CVERTEXBM_FVF );

 //set correct texture coordinates
 (*D3D9Device)->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, 0 );
 (*D3D9Device)->SetTextureStageState( 1, D3DTSS_TEXCOORDINDEX, 0 );

 //set first stage operations
 (*D3D9Device)->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_DOTPRODUCT3 ); // Perform a Dot3 operation...
 (*D3D9Device)->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );    // between the N (of N.L) which is stored in a normal map texture...
 (*D3D9Device)->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );    // with the L (of N.L) which is stored in the vertex's diffuse color.

 //set second stage operations

 (*D3D9Device)->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_MODULATE ); // Modulate...
 (*D3D9Device)->SetTextureStageState( 1, D3DTSS_COLORARG1, D3DTA_TEXTURE ); // the texture for this stage with...
 (*D3D9Device)->SetTextureStageState( 1, D3DTSS_COLORARG2, D3DTA_CURRENT ); // the current argument passed down from stage 0

 for(int i = 0; i < MaterialCount; i++)

	  (*D3D9Device)->SetTexture(0, normalmaps[i]);
	  (*D3D9Device)->SetTexture(1, 0);						
 	  //(*D3D9Device)->SetTexture(1, textures[i]);						


That's the code and it fails miserably... now, it will work fine if I do this instead:
	  //light vector
	  (*D3D9Device)->SetTextureStageState(0,D3DTSS_COLOROP, D3DTOP_DOTPRODUCT3);
	  //set the TFactor to our diffuse of the 12th vertex (just randomly to test it)
	  D3DXVECTOR3 LightVector;

	  mesh->LockVertexBuffer(D3DLOCK_DISCARD, (VOID**)&Vertex);


So, if I let the rendered take the Diffuse value itself, it screws up, but if I set it manually through the Texture Factor and use that instead, it works... The crappy thing is, I used this method in a program where it works perfectly fine; here it screws up and I have no idea what is the differen :/ Any idea? [Edited by - Koobazaur on March 16, 2007 2:33:17 PM]

Share this post

Link to post
Share on other sites
SimmerD    1210
When you turn on fixed function lighting, your diffuse color will be overwritten with the diffuse lighting result. That's what the lighting is for. If you turn on specular enable, like you have, you will find specular also overwritten.

Share this post

Link to post
Share on other sites
Koobazaur    1264
I see. I was working with a sample and was under the impression the light stayed enable through the whole program; now, double checking, I see it actually wasn't.


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