Passing argument from Vertex to Pixel Shader

Started by
3 comments, last by Zaph-0 14 years, 4 months ago
Hi, I am trying to rendering a mesh with several different kinds of material with dx9. I can theoretically do that in 1 rendercall because all materials are encoded into the vertex information as a D3DDECLTYPE_UBYTE4 and can be handled in the vertex and pixel shader at runtime (animation, etc...). In the vertex and pixel shaders I have set it to be a BLENDINDICES type (don't know what else to use) and pass it from the vertex shader to the pixel shader where its being evaluated and then the appropriate texture with modifications being rendered. But the problem I am having is that the value I get for the BLENDINDICES is not always correct. If I set it to 100 and test for 100 I get something like noise or Z-fighting for the pixels. Some ok, some not. If I test it for >90 its sort of ok, but can't I pass exact 8bit values using D3DDECLTYPE_UBYTE4 ? It seems to be working in the vertex shader though only the pixel shader is giving strange results. Here is my PS Code:

struct PS_INPUT
{	float4 Position		: POSITION;
	float4 VertexData	: BLENDINDICES;
	float2 Texture		: TEXCOORD0;
};

struct PS_OUTPUT
{	float4 Color   : COLOR0;
};

PS_OUTPUT ps_main( in PS_INPUT In )
{	PS_OUTPUT Out;

	if(In.VertexData.g == 100)
	{	Out.Color = tex2D(Tex0, In.Texture) * float4(0,1,1,1);
	}
	else
	{	Out.Color = tex2D(Tex0, In.Texture);
	}

	return Out;
}



And here the picture thats demonstrates the problem. The light blue pixels are ok, the white pixels are not. image Thanks in advance for any help with this...
Advertisement
You realize the fragment shader is going to get interpolated values sent to it, right?

Or is it the case that in your mesh every triangle has 3 vertices with the exact same value for each vert?

If not, you might have to duplicate some verts in your mesh so that this holds
Hi,

yes in every triangle they all have the same values.
Is it possible the BLENDINDICES interpolator is done as less-than-float precision? Try sending it through as a TEXCOORD#

Does your GPU support int4 interpolators? That's likely a better solution

In general testing floats with == is a bad idea. The actual value might be 99.9999f or something. A gpu debugger may actually show this.


A more accurate test might be:

if( value >= 99.9f && value <= 100.1f )
{
Changing it to int4 changed nothing but changing the code to

	if((In.VertexData.g > 99.9) && (In.VertexData.g < 100.1))	{	Out.Color = tex2D(Tex0, In.Texture) * float4(0,1,1,1);		}	else	{	Out.Color = tex2D(Tex0, In.Texture);	}


seems to have done the trick as it works every time now.

I think thats a really lame solution because then I could have just used the color arguments from 0.0 to 1.0 that are supported everywhere instead of the less common ubyte4 where I can use values from 0 to 255.

I would never have thought that floats are that unprecise. I know that I can not make exact comparisons after I did some math with the floats but those where just set and passed along. Well, I guess my gpu is taking some shortcuts somewhere...

Maybe I'll just round the value. That seems to work as well.

Thanks for your help.

^_^

This topic is closed to new replies.

Advertisement