Wednesday, June 1, 2011

DirectX: No lights, no colors

Whenever you find yourself writing a serious 3D application, with things like physics, skeletal animations, custom collision and interaction structures, predefined camera paths and / or spatial subdivision structures, you'll soon encounter the need for debugging geometry.

In the middle of all that eye candy shader goodness, you want your debugging geometry to be simple and clean. In our 3D framework, we allow the application to add simple debugging shapes (lines, boxes, spheres, etc) to the render queue, with a single argument specifying the desired color. Internally, the engine switches from shaders to fixed function pipeline for rendering those debugging primitives. Oh, and to make sure the debugging geometry is rendered in a monotonous color, lighting is disabled. Simple, right?

Wrong. All debugging geometry turned out bright white. No matter what color we specified. No warnings, no errors, no nothing, just plain white.

Turns out that in DirectX Fixed Function Pipeline, to use material colors, you have to enable lighting. Which wouldn't be so bad if someone had done a decent job documenting it.

Diffuse color is generated when lighting is enabled, that is, D3DRS_LIGHTING is set to TRUE

It's there alright, right on the page about Fixed Function Vertex Processing (DirectX9), but even if you stumble upon that page (as opposed to the dedicated pages about material and lighting, where you are very likely to end up from a google/bing/msdn search), on first glance it looks like that's just documenting IDirect3DDevice9::ProcessVertices, a call you are very likely not to be using. Like, ever.

The solution is to simply enable lighting, disable all fixed pipeline lights and set the ambient light to bright white. That, or simply use a dedicated shader.

No comments:

Post a Comment