DOT3 Product problem

Started by
1 comment, last by Koobazaur 17 years, 1 month ago
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:

#define CVERTEXBM_FVF (D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE  | D3DFVF_TEX1)

class cVertexBM
{
 public:
 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)
	 ReleaseAll();

  HRESULT result;
  //load the mesh
  result = D3DXLoadMeshFromX(filename.c_str(), 
				   D3DPOOL_MANAGED | D3DXMESH_32BIT, 
				   (*D3D9Device), 
				   &AdjecencyInfo, 
				   &MaterialBuffer,
				   0,
				   (DWORD*)(&MaterialCount),
				   &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.MatD3D.Ambient = MaterialBufferAccess.MatD3D.Diffuse;
		 materials.push_back(MaterialBufferAccess.MatD3D);

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

			textures.push_back(tex);
			
			//get the filename of the normal

			//construct the normal filename and load it
			TextureFilename = ConstructNormalFilename(Filename);
			if(!TextureFilename.empty())
				{
				if(D3DXCreateTextureFromFile((*D3D9Device), TextureFilename.c_str(), &tex)!=D3D_OK)
					tex=0;
				normalmaps.push_back(tex);
				}		
			}
		 else //otherwise, add an "empty" texture
			textures.push_back(0);
	    }
	 //we are done; release the material buffer
	 MaterialBuffer->Release(); 
	}

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

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

//calculate normals
D3DXComputeNormals(mesh, 0);

//release adjecency
AdjecencyInfo->Release();

//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

 D3D9Device->SetRenderState( D3DRS_SHADEMODE, D3DSHADE_GOURAUD );







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)->SetMaterial(&materials);

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

		  mesh->DrawSubset(i);
	}







That's the code and it fails miserably... now, it will work fine if I do this instead:

//=================================================
	  //normal
	  (*D3D9Device)->SetTextureStageState(0,D3DTSS_COLORARG1,D3DTA_TEXTURE);
	  //light vector
	  (*D3D9Device)->SetTextureStageState(0,D3DTSS_COLORARG2,D3DTA_TFACTOR);
	  //dot3
	  (*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);

	   (*D3D9Device)->SetRenderState(D3DRS_TEXTUREFACTOR,Vertex[12].diffuse);
	   mesh->UnlockVertexBuffer();
//============================================






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]
Comrade, Listen! The Glorious Commonwealth's first Airship has been compromised! Who is the saboteur? Who can be saved? Uncover what the passengers are hiding and write the grisly conclusion of its final hours in an open-ended, player-driven adventure. Dziekujemy! -- Karaski: What Goes Up...
Advertisement
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.
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.

Thanks.
Comrade, Listen! The Glorious Commonwealth's first Airship has been compromised! Who is the saboteur? Who can be saved? Uncover what the passengers are hiding and write the grisly conclusion of its final hours in an open-ended, player-driven adventure. Dziekujemy! -- Karaski: What Goes Up...

This topic is closed to new replies.

Advertisement