   Too much ambient/diffuse?
  Hey guys,The above picture is a print screen of my application.The cube (red) in front was created using the default mesh that came with the SDK, the second cube (green) in the background is made up from vertices using an vertex buffer and index buffer.If you look at the cubes you can see that the red cube's faces are distinguishable, while the green cube's faces are not.I am using 1 directional light only in the screen, and directional light doesn't have a physical position, hence I don't think it is the placement of the directional light that is the problem.Can you guys see why the green cube isn't lit up more like the red, that is the faces are distinguishable. To me it seems either the ambient or the diffuse property of the green cube is overpowering everything?Some code for my application is here.// --------------- MAIN APPLICATION ENTRY ----------------- //// Code omitted...IDirect3DDevice9 *D3DDevice = NULL;Direct3DUtility *direct3DUtility = NULL;struct CustomVertex{FLOAT x, y, z;DWORD color;};#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE)//--- Function Prototypes ---//void cleanUp();void getInput();void initStars();void renderGame();void setupGame();void updateGame();int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd ){direct3DUtility = new Direct3DUtility;// Code omitted...direct3DUtility->init3D( hInstance, baseWindow->getHandle(), &D3DDevice );direct3DUtility->initState( &D3DDevice );direct3DUtility->initDirLight( &D3DDevice );MSG msg;ZeroMemory( &msg, sizeof( MSG ));while( msg.message != WM_QUIT ){if( PeekMessage( &msg, 0, 0, 0, PM_REMOVE )){TranslateMessage( &msg );DispatchMessage( &msg );}else{updateGame();renderGame();Yield();}}UnregisterClass( baseWindow->getClassName(), hInstance );return 0;}void getInput(){// Code omitted...}void setupGame(){// Code omitted...initStars();}void renderGame(){D3DDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB( 0, 0, 0 ), 1.0f, 0 );D3DDevice->Clear( 0, NULL, D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB( 0, 0, 0 ), 1.0f, 0);getInput();D3DDevice->BeginScene();direct3DUtility->setMaterialColor( direct3DUtility->getColorWhite(), 0.8f, 0.8f );D3DDevice->SetMaterial( &( direct3DUtility->getMaterial() ));D3DDevice->SetFVF( D3DFVF_CUSTOMVERTEX );D3DDevice->SetStreamSource( 0, VBStars, 0, sizeof( CustomVertex ));D3DDevice->DrawPrimitive( D3DPT_POINTLIST, 0, STAR_SIZE );direct3DUtility->setMaterialColor( direct3DUtility->getColorGreen(), 0.2f, 0.4f );D3DDevice->SetMaterial( &( direct3DUtility->getMaterial() ));D3DDevice->SetFVF( D3DFVF_CUSTOMVERTEX );D3DDevice->SetStreamSource( 0, VBCrates, 0, sizeof( CustomVertex ));D3DDevice->SetIndices( IBCrates );D3DDevice->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 0, 0, 8, 0, 12 );/*Base code you can work with.*/D3DXMATRIX matTranslate;D3DXMatrixTranslation( &matTranslate, spaceship[ 1 ]->getPosition()->getX(), spaceship[ 1 ]->getPosition()->getY(), spaceship[ 1 ]->getPosition()->getZ());D3DDevice->SetTransform (D3DTS_WORLD, &matTranslate);direct3DUtility->setMaterialColor( direct3DUtility->getColorRed(), 0.2f, 0.4f );D3DDevice->SetMaterial( &( direct3DUtility->getMaterial() )); spaceship[ 1 ]->getMesh()->DrawSubset( 0 );D3DDevice->EndScene();D3DDevice->Present( NULL, NULL, NULL, NULL );}void updateGame(){// Code omitted...}void initStars(){// Code omitted...CustomVertex customVertexCrate[] ={// Back of cube{ -3.0f, -3.0f, 5.0f, D3DCOLOR_XRGB( 255, 255, 255 )},{ -3.0f, -1.0f, 5.0f, D3DCOLOR_XRGB( 255, 255, 255 )},{ -1.0f, -1.0f, 5.0f, D3DCOLOR_XRGB( 255, 255, 255 )},{ -1.0f, -3.0f, 5.0f, D3DCOLOR_XRGB( 255, 255, 255 )},// Front of cube{ -3.0f, -3.0f, 3.0f, D3DCOLOR_XRGB( 255, 255, 255 )},{ -3.0f, -1.0f, 3.0f, D3DCOLOR_XRGB( 255, 255, 255 )},{ -1.0f, -1.0f, 3.0f, D3DCOLOR_XRGB( 255, 255, 255 )},{ -1.0f, -3.0f, 3.0f, D3DCOLOR_XRGB( 255, 255, 255 )},};void* verticesCrate;D3DDevice->CreateVertexBuffer( sizeof( CustomVertex ) * CRATE_SIZE, 0, D3DFVF_CUSTOMVERTEX, D3DPOOL_MANAGED, &VBCrates, NULL );VBCrates->Lock( 0, 0, ( void** ) &verticesCrate, 0 );memcpy( verticesCrate, customVertexCrate, sizeof( customVertexCrate ));VBCrates->Unlock();short indices[] ={0, 1, 2, // front face0, 2, 3,6, 5, 4, // back face4, 7, 6,2, 6, 7, // right side face3, 2, 7,4, 5, 1, // left side face0, 4, 1,2, 1, 6, // top face1, 5, 6,0, 7, 4, // bottom face0, 3, 7,};void* indexData = NULL;D3DDevice->CreateIndexBuffer( sizeof( short ) * 36, 0, D3DFMT_INDEX16, D3DPOOL_MANAGED, &IBCrates, NULL );IBCrates->Lock( 0, 0, ( void** ) &indexData, 0 );memcpy( indexData, indices, sizeof( indices ));IBCrates->Unlock();}void cleanUp(){// Code omitted...}// ------------ Direct3DUtility.h HEADER FILE -------------- //// Code omitted....class Direct3DUtility{public:~Direct3DUtility();Direct3DUtility();// Code omitted...void initDirLight( IDirect3DDevice9 **D3DDevice );void setMaterialColor( D3DXCOLOR color, float ambient, float diffuse );D3DXCOLOR getColorWhite();D3DXCOLOR getColorRed();D3DXCOLOR getColorGreen();D3DMATERIAL9 getMaterial();private:D3DXCOLOR COLOR_WHITE;D3DXCOLOR COLOR_RED;D3DXCOLOR COLOR_GREEN;D3DXVECTOR3 dir;D3DMATERIAL9 material;};#endif// ------------ Direct3DUtility.cpp IMPLEMENTATION FILE ---------- //#include "Direct3DUtility.h"Direct3DUtility::~Direct3DUtility() { }Direct3DUtility::Direct3DUtility(){COLOR_WHITE = D3DCOLOR_XRGB( 255, 255, 255 );COLOR_RED = D3DCOLOR_XRGB( 255, 0, 0 );COLOR_GREEN = D3DCOLOR_XRGB( 0, 255, 0 );dir = D3DXVECTOR3( 0.0f, -5.0f, 7.0f );ZeroMemory( &material, sizeof( D3DMATERIAL9 ));}void Direct3DUtility::initDirLight( IDirect3DDevice9 **D3DDevice ){D3DLIGHT9 dirLight;ZeroMemory( &dirLight, sizeof( dirLight ) );dirLight.Type = D3DLIGHT_DIRECTIONAL;dirLight.Direction = dir;dirLight.Ambient = COLOR_WHITE * 1.0f;dirLight.Diffuse = COLOR_WHITE * 1.0f;dirLight.Specular = COLOR_WHITE * 0.0f;( *D3DDevice )->SetLight( 0, &dirLight );( *D3DDevice )->LightEnable( 0, true );}void Direct3DUtility::setMaterialColor( D3DXCOLOR color, float amb, float diff ){material.Ambient = color * amb;material.Diffuse = color * diff;material.Emissive = color * 0.0f;material.Power = 0.0f;}D3DMATERIAL9 Direct3DUtility::getMaterial(){return material;}D3DXCOLOR Direct3DUtility::getColorWhite(){return COLOR_WHITE;}D3DXCOLOR Direct3DUtility::getColorRed(){return COLOR_RED;}D3DXCOLOR Direct3DUtility::getColorGreen(){return COLOR_GREEN;}I have left out unnecessary code so that the post isn't long... but if there is anything unclear in the code let me know and I will clarify.The function that is being call to the set the material properties is the same for the stars in the background, for the red cube and for the green cube, hence I am kinda out of ideas why the red one would render properly while the green one won't.Appreciate any help you guys can offer :)   
  Doesn't look like you've defined any normals for your custom vertex format, so your cube won't react to the light correctly.   ;  Well you do have: dirLight.Ambient = COLOR_WHITE * 1.0f;That's 100% ambient lighting, which should make everything look "flat".   ;Quote:Original post by HodgmanWell you do have: dirLight.Ambient = COLOR_WHITE * 1.0f;That's 100% ambient lighting, which should make everything look "flat".I've tried playing around with this value, and regardless of the value, the green cube always look flat.Yep, I haven't defined any normals for the custom vertex format. Is it needed?I will go and research this area and see if I can dig up more info.That very well could be the problem :)   ;  The vertex normals d of the vertices that make up a face define the direction of that face. This is used in lighting calculations to determine how much light is reflected off the surface back into the camera's "eye" resulting in the different shading on the different sides of the cube.   ;  I have read up on vertex normals (I actually came across this before but had just forgotten) and the way the examples have shown and demonstrated is just by hard coding the values into the FVF structure like sostruct CUSTOMVERTEX {FLOAT X, Y, Z; D3DVECTOR NORMAL;};#define CUSTOMFVF (D3DFVF_XYZ | D3DFVF_NORMAL)CUSTOMVERTEX vertices[] ={{ -3.0f, -3.0f, 3.0f,  0.0f, 0.0f, 1.0f, },    // side 1    { 3.0f, -3.0f, 3.0f,  0.0f, 0.0f, 1.0f, },    { -3.0f, 3.0f, 3.0f,  0.0f, 0.0f, 1.0f, },    { 3.0f, 3.0f, 3.0f,  0.0f, 0.0f, 1.0f, },    { -3.0f, -3.0f, -3.0f,  0.0f, 0.0f, -1.0f, },    // side 2    { -3.0f, 3.0f, -3.0f,  0.0f, 0.0f, -1.0f, },    { 3.0f, -3.0f, -3.0f,  0.0f, 0.0f, -1.0f, },    { 3.0f, 3.0f, -3.0f,  0.0f, 0.0f, -1.0f, },// etc...}So here the last 3 float value are the vertex normal, but in my case it is likely that the cube will be rotating every frame.There is no DirectX function that will work this out for me? The tutorials I've read say I have to work this out myself unfortunately.[Edited by - tenpoundbear on April 6, 2010 10:53:18 AM];  You need to apply the world matrix (Though only the rotation portion) for the cube, to the vertex normals before you use them for calculations.Since you're using the fixed-function pipeline I would assume DirectX will do this for you as part of its hardware transform and lighting so long as you set a suitable world matrix for it.   ;  Hey guys,I am going to tackle calculating the normals for the faces of the cube rotating in a later version.Just wanted to say thanks for the vertex normal tip :)  cube is rendered with different shades of green now, instead of being flat.   