Thread: Light woes or bad normals?

  1. #1
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607

    Light woes or bad normals?

    This has got me stumped. Every time I attempt to light a sphere using Direct3D's default gouraud shading I get this result. Now even if light hits the surface unevenly, the interpolation should correct it to look much better than this.

    Is this the best I can get with default lighting? And if so - can I just create a lightmap that interpolates from black to white and blend it with the planet texture - in essence light map the planet?

    I've used:

    D3DXCreateSphere();
    Mesh->CloneMeshFVF();
    D3DXComputeNormals();

    I've also tried simply using the normalized sphere vertex as the normal for the vertex and I get the same results. The normal for any point on a sphere is this:

    Normal(PointOnSphere-CenterOfSphere);

    So it should work.

    Any help is appreciated.

  2. #2
    The Right Honourable psychopath's Avatar
    Join Date
    Mar 2004
    Location
    Where circles begin.
    Posts
    1,071
    I'm not sure about D3D, but Iv'e gotten similar results doing the same thing under OGL (however mine wasn't quite that bad, as the sphere had a higher tesselation, and the sphere was much smaller).

    I'd say either lightmap it, or use a shader.

    -psychopath
    M.Eng Computer Engineering Candidate
    B.Sc Computer Science

    Robotics and graphics enthusiast.

  3. #3
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    Ok, I tried to lightmap it. Seems my GeForce 3 64MB card won't do it. Now I know this is wrong because my retail games get away with it.

    So how do you light map w/o using shaders? Every time I try to use the fixed function pipeline or more than one sampler - I get no results. It's as if only sampler 0 is supported on my display driver.

    This is a render state that has the light map in the alpha component of the texture. Doesn't work.

    Code:
    // Set the base texture operation and args.
      
    
      // Set the color operation.
      Device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
    
      // Set argument 1 to the color operation.
      Device->SetTextureStageState(0, D3DTSS_COLORARG1,
           D3DTA_TEXTURE | D3DTA_ALPHAREPLICATE);
    And this is the other method. Again, doesn't work.

    Code:
    // This example assumes that d3dDevice is a valid pointer to an
    // IDirect3DDevice9 interface and that lptexLightMap is a valid
    // pointer to a texture that contains RGB light map data.
    
    // Set the light map texture as the first texture.
    Device->SetTexture(0, Texture);
    
    Device->SetTextureStageState( 0,D3DTSS_COLOROP, D3DTOP_MODULATE );
    
    Device->SetTextureStageState( 0,D3DTSS_COLORARG1, D3DTA_TEXTURE );
    
    Device->SetTextureStageState( 0,D3DTSS_COLORARG2, D3DTA_DIFFUSE );
    Code:
    // This example assumes that d3dDevice is a valid pointer to an
    // IDirect3DDevice9 interface.
    // lptexBaseTexture is a valid pointer to a texture.
    // lptexDiffuseLightMap is a valid pointer to a texture that contains 
    // RGB diffuse light map data.
    
    // Set the base texture.
    Device->SetTexture(0,Texture);
    
    // Set the base texture operation and args.
    Device->SetTextureStageState(0,D3DTSS_COLOROP,
           D3DTOP_MODULATE );
    
    Device->SetTextureStageState(0,D3DTSS_COLORARG1, D3DTA_TEXTURE );
    
    Device->SetTextureStageState(0,D3DTSS_COLORARG2, D3DTA_DIFFUSE );
    
    // Set the diffuse light map.
    Device->SetTexture(1,LightMap );
    
    // Set the blend stage.
    Device->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MODULATE );
    
    Device->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE );
    
    Device->SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT );

    Last two right out of the SDK with my variables added. Still nothing.

    Help, please.
    Last edited by VirtualAce; 10-09-2005 at 04:07 PM.

  4. #4
    The Right Honourable psychopath's Avatar
    Join Date
    Mar 2004
    Location
    Where circles begin.
    Posts
    1,071
    Odd. Are you generating the lightmap at runtime? If so, you could try saving the lightmap data into a texture, and then loading that texture into your second texture unit. That would see if the data is being passed properly. After that, I don't really know, because it's probably D3D specific.

    -psychopath
    M.Eng Computer Engineering Candidate
    B.Sc Computer Science

    Robotics and graphics enthusiast.

  5. #5
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    Ok here is the result, the texture map and the associated light map. All I want to do is multiply the RGBs of the texture by the RGBs of the light map, thus dimming the texels of the texture in the black areas of the light map and brightening them in the light areas of the light map. I realize this light map might not work as is, but I need to get some type of result so I can modify the light map.

    This is a simple light map - I just need to simulate the sun shining on the planet - specular highlights don't matter because a planet is not a shiny plastic ball - it's made of rock and specular highlights make it look like something from Toy Story.

    As you can see when I turn lighting off in the engine, I get nothing at all - just ambient light. You cannot see any variations in brightness on any portion of the planet. Not what I want.

    Perhaps I'm approaching light mapping incorrectly.

  6. #6
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    Here is the Earth lightmap

  7. #7
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    Here is the earth texture

  8. #8

    Join Date
    May 2005
    Posts
    1,042
    I've gotten this working in OpenGL, which is frustrating because you're doing the equivalent but with DirectX, so I don't know if I can help.


    Perhaps try applying the lightmap when it's fully dark; I personally can't tell whether or not it's affecting the final render in any region.

    For the first screenshot, how many light sources are contributing to the scene.

    For the D3DXComputeNormals function how come you don't pass in a mesh pointer? I msdn'd it to see the parameters and stipulations and it at least seems to require a mesh pointer, and optionally the adjacency indices. It also states 'The input mesh must have the D3DFVF_NORMAL flag specified in its flexible vertex format (FVF).'

    http://msdn.microsoft.com/library/de...utenormals.asp

    good luck
    I'm not immature, I'm refined in the opposite direction.

  9. #9
    The Right Honourable psychopath's Avatar
    Join Date
    Mar 2004
    Location
    Where circles begin.
    Posts
    1,071
    Perhaps the texture coords are incorrect for the second texture unit? Just a thought. And as BobMcGee said, maybe it just the ambient light throwing it off.

    Heres the lightmapping in OGL...I'm using OGL multitexture functions, and a default light.
    M.Eng Computer Engineering Candidate
    B.Sc Computer Science

    Robotics and graphics enthusiast.

  10. #10
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    I didn't post the actual function parameter lists. Everything is succeeding except for the end result. Even ramping the RGBs on the light map does not yield the correct results.

    The second texture unit's coords are the same as the the first - because of the spherical mapping.

    I finally got it working: Texture coords were incorrect. I placed code in the constructor of the vertex to copy the vertex for u and v to lu and lv, however when I spherical mapped the u and v, I was not setting the lu and lv. So the texture coords when I created the sphere was what the light map was getting. Doh!!!!!!!!!!!!!!!

    So far it looks...um......quite good.

    Thanks.
    Last edited by VirtualAce; 10-10-2005 at 12:22 PM.

  11. #11
    Registered User
    Join Date
    Apr 2002
    Posts
    1,571
    Make sure both textures are loaded correctly. You know your detail map is loaded correctly since you can plainly see it. Try using the lightmap texture as a detail map and seeing if it looks correct. Then it should be a matter of

    Set Detail Map
    SelectArg1 : TEXTURE
    Set Light Map
    Modulate : TEXTURE, CURRENT

    You said something about the lightmap being in the alpha channel? I don't know what that's all about but you would need to handle that differently if that's the case. Otherwise the above method should work. Make sure you turn of the alpha stages if you aren't using them.
    "...the results are undefined, and we all know what "undefined" means: it means it works during development, it works during testing, and it blows up in your most important customers' faces." --Scott Meyers

  12. #12
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    Okay got everything working, now I just have to mess with the textures and the artwork to get my planets to look right.

    This is the first shot of one of my planets rendered using no detail texture, a diffuse light map, and a bump map. You can see some large artifacts but at least the bump mapping is working correctly.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. cant get display with this computer I built. Bad board?
    By eats only heads in forum Tech Board
    Replies: 19
    Last Post: 11-28-2002, 12:27 PM
  2. UNICODE and GET_STATE
    By Registered in forum C++ Programming
    Replies: 1
    Last Post: 07-15-2002, 03:23 PM
  3. Bad File number?
    By Unregistered in forum Linux Programming
    Replies: 4
    Last Post: 05-31-2002, 08:55 AM
  4. good news and bad news
    By Garfield in forum A Brief History of Cprogramming.com
    Replies: 25
    Last Post: 10-27-2001, 07:31 AM
  5. Bad code or bad compiler?
    By musayume in forum C Programming
    Replies: 3
    Last Post: 10-22-2001, 09:08 PM