Jump to content
  • Advertisement
Sign in to follow this  
andy55

Interesting color mystery...

This topic is 3029 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hey guys, quick question for any Direct3D experts here -- we just can't seem to crack this...

So, I have a pixel shader bound that uses IN.color and everything is peachy. However, if the vertex buffer that is bound only has coordinate data (ie. no color data), IN.color always comes in as black (0,0,0,0), mucking up the output. So the question is, what is Direct3D doing to come up with that black value? Is there an environmental setting that will cause it to default to white instead?

Per spec, the multi-tex pipeline is not used when a pixel shader is bound:

"A pixel shader completely replaces the pixel-blending functionality specified by the multi-texture blender including operations previously defined by the texture stage states."

http://msdn.microsoft.com/en-us/library/bb944006(VS.85).aspx#Texture_Stage_and_Sampler_States

So, since SetTextureStageState() becomes N/A once a pixel shader is bound, why the heck is D3D sending black rather than white? Unfortunately, we can't just remove the use of IN.color in our shader because sometimes the bound vertex buffer does have color data (and binding and unbinding different shaders would be problematic).

Thanks in advance!!

Andy

Share this post


Link to post
Share on other sites
Advertisement
Black seems to make sense to me if there's no vertex color being propagated to the input of the pixel shader.

Where do you think it should be getting the input color from?

Why do you think it should default to white?

Share this post


Link to post
Share on other sites
why the hell dont you just pass that value to the pixel shader as White
or do you mean the shaders vs is layed out like so
struct VS_INPUT
{
float3 Pos : POSITION;

float4 col: COLOUR;//or what ever it is
//stuff
}

and then you trying to use this for a vertex structure with out colour
if so you are getting data from bogus input.
the vertex structure needs to match the inputlay out of the shader.

Share this post


Link to post
Share on other sites
If the input vertices to the shader are fixed for administrative reasons, add an "extern BOOL flag" to your shader. Set it to true prior to rendering for vertices that have color; set it to false for vertices without color.

In the shader:

if( flag ) //... do your thing with the vertex color
else // ... set a default color, WHITE if you prefer, to be used otherwise

Share this post


Link to post
Share on other sites
Hi guys,

I appreciate the your ideas but keep in mind this is a pixel shader, not a vertex shader. If we did bind a vertex shader that overrode the output color to white, then we're unfortunately back in the problem of the vertex buffer subsystem of our code now has to be bind different vertex shaders for different vertex buffers that come along.

As for adding logic based on an external flag, this unfortunately decreases performance (i.e. shader pipeline execution time per fragment) and increases interdependence of internal components (since the subsystem dealing with vertex object now has to communicate and set that shader extern whenever drawing occurs). Also, Buckeye, I'm not sure what you mean by "administrative reasons". Perhaps you could explain that further?

So, any other thoughts as to why the default vertex color is black and/or how that can be overridden?

Thanks again,
Andy

Share this post


Link to post
Share on other sites
What does your vertex shader look like that feeds this pixel shader?

I'm gonna assume it's black because either:

A) Since your vertex buffer lacks a color component, as it's mapping your buffer to the shader semantics it's filling in the color portion with 0s which would look black.

B) Your vertex shader's color semantic is 0 because there is no incoming color data and/or you're not sending out any color to the pixel shader.

I don't think there's anything you can set to say "fill the blanks with white". Because blanks will always be black (0,0,0,0) You're going to have to either

A) Set your vertex buffer to have the color you want.

B) Create a vector shader variable which would contain color information. Before drawing an object, you simply update the shader variable with the new color information and read that in the fragment shader. This means you can keep your shaders, or use one pixel shader for IN.color from the vertex shader and one pixel shader for the diffuse color shader variable.

Share this post


Link to post
Share on other sites
So far you've just mentioned pixel shader input. The reason why IN.color for your pixel shader is black is - of course - because that's what the output from your vertex shader was. Depending on what you're doing with colour in your vertex shader, the question might really be: "why is the default vertex shader input colour black if I don't specify one?"

Now look at your SDK documentation, specifically under the topic "Registers - vs (pick a version)". The default for an input register that's not specified in your vertex data is {0, 0, 0, 1}. So double-check your VS input, make sure that it matches the spec (0, 0, 0, 1), then check what's happening to the input colour in your VS, and the question of why your PS is always getting black as it's input should be answered.

As for changing it - well, the spec stipulates a default of {0, 0, 0, 1} so you'd need to change the spec. Why not just add an extra vertex stream containing colour data of all white for cases where you're not otherwise using one?

Share this post


Link to post
Share on other sites
I'm not really sure what your vertex shader looks like, but there is certainly no way to change the default color of something that isn't specified. In fact, if the vertex shader doesn't define an output color and you pixel shader requires one, then you should be getting debug error output because your shaders don't match up.

Honestly, how hard would it be to do one of two things:

1. Make all you vertex data in the same format, including a vertex color which is defaulted to white if other sources don't provide it. Then your vertex/pixel shaders are the same for all cases.

2. Set the appropriate vertex/pixel shaders to fit with your input data. This is how 100% of rendering applications work - that's why it is possible to change shaders at runtime, because it is always changing!

I suspect that you are using the fixed function vertex processing in some cases, and if that is so, then you need to replace that functionality with a vertex shader to make everything operate in the same mode.

Share this post


Link to post
Share on other sites
Quote:
Buckeye, I'm not sure what you mean by "administrative reasons".

Nothing special, I'm afraid. You had previously posted:
Quote:
Unfortunately, we can't just remove the use of IN.color in our shader because sometimes the bound vertex buffer does have color data (and binding and unbinding different shaders would be problematic).

It appears that your choice for a solution isn't based on programming capability. I just called that an "administrative" reason. I.e., binding and unbinding different shaders can certainly be done - but someone's made a decision that it won't be done.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!