[dx9] Output vertex color with pixel shader

Started by
4 comments, last by NightCreature83 13 years, 5 months ago
I have a mesh with this vertex data (examined mesh->DrawSubset() with PIX):
type:       usage:FLOAT3      POSITIONFLOAT3      NORMALD3DCOLOR    COLOR


and from dxsdk docs about D3DCOLOR type:
Quote:
4-D packed unsigned bytes mapped to 0 to 1 range. Input is in D3DCOLOR format (ARGB) expanded to (R, G, B, A).


so its 32 bit color value?

and in my shader i must set it as float4 for it to work:
float4x4 WorldViewProjection;struct VertexData{	float3 Position : POSITION;	float3 Normal   : NORMAL;	float4 Color    : COLOR;};struct VertexOutput{	float4 Position : POSITION;	float4 Color     : TEXCOORD0;};struct PixelOutput{	float4 Color : COLOR0;};void VS(in VertexData IN, out VertexOutput OUT){	OUT.Position = mul(float4(IN.Position.xyz, 1.0f), WorldViewProjection);	OUT.Color    = IN.Color;}void PS(in VertexOutput IN, out PixelOutput OUT){	OUT.Color = IN.Color;}technique Tech{	pass p0	{		VertexShader = compile vs_3_0 VS();		PixelShader  = compile ps_3_0 PS();	}}

but its 4 x 32 bit???
Is there some conversation behind scene that i am not aware of?

EDIT: i have another question on same shader:

if i set:
row_major float4x4 WorldViewProjection;//like D3DXMATRIX//column_major float4x4 WorldViewProjection;


row-major packing matrices has 5 instruction slots used
and column-major has 6 instruction slots used

but in dxsdk they say that column-major is efficient then row-major.
Advertisement
Your D3DCOLOR stores RGBA in a single 32 bit integer. In a 0 to 255 range for each color component unless I'm mistaken.
So some conversion goes on to convert this into a 0 to 1 floating point range.
I can't answer your second question.
If i assume it correctly default packing for (constant reg.) matrices are
column-major?
But aren't column-major just transpose of row-major?
Then i am confused as how does transforming vertices works with both ways?:
OUT.Position = mul(float4(IN.Position.xyz, 1.0f), WorldViewProjection);

I thought that for row-major it should be:
OUT.Position = mul(WorldViewProjection, float4(IN.Position.xyz, 1.0f));

Quote:Original post by brega
If i assume it correctly default packing for (constant reg.) matrices are
column-major?
But aren't column-major just transpose of row-major?
Then i am confused as how does transforming vertices works with both ways?:
OUT.Position = mul(float4(IN.Position.xyz, 1.0f), WorldViewProjection);

I thought that for row-major it should be:
OUT.Position = mul(WorldViewProjection, float4(IN.Position.xyz, 1.0f));


Matrix math tells us that the result of a MxN matrix times a NxK matrix gives us a MxK matrix as a result.

So in your two exaples that would give:
1x4 * 4x4 = 1x4 for the first case
4x4 * 4x1 = 4x1 for the second case

Both of which are considered to be one dimensional vectors, or just vectors. A warning here though don't mix the modes as that will lead to unexpected results as rotation and translation aren't applied in the manner you expect them to be in.

You do need to flip the order of multiplication though as matrix multilpy is not commutative, eg. x*y != y*x.

[Edited by - NightCreature83 on November 1, 2010 8:30:23 AM]

Worked on titles: CMR:DiRT2, DiRT 3, DiRT: Showdown, GRID 2, theHunter, theHunter: Primal, Mad Max, Watch Dogs: Legion

Thanks for reply.

I have switched to "pure" HLSL:
D3DXCompileShaderFromFile(...)dev->CreateVertexShader(...)dev->CreatePixelShader(...)...

and use pragma directive:
#pragma pack_matrix(row_major)//as D3DXMATRIX...void VS(...){    OUT.Position = mul(float4(IN.Position.xyz, 1.0f), WorldViewProjection);    // for column-major (default)    // but this works for both using "effect framework"    //OUT.Position = mul(WorldViewProjection, float4(IN.Position.xyz, 1.0f));}

and now shader work as expected.

One more question: any particular reason why is that coulmn-major (matrices packing) are set as default for HLSL shaders?
Quote:Original post by brega
Thanks for reply.

I have switched to "pure" HLSL:
D3DXCompileShaderFromFile(...)dev->CreateVertexShader(...)dev->CreatePixelShader(...)...

and use pragma directive:
#pragma pack_matrix(row_major)//as D3DXMATRIX...void VS(...){    OUT.Position = mul(float4(IN.Position.xyz, 1.0f), WorldViewProjection);    // for column-major (default)    // but this works for both using "effect framework"    //OUT.Position = mul(WorldViewProjection, float4(IN.Position.xyz, 1.0f));}

and now shader work as expected.

One more question: any particular reason why is that coulmn-major (matrices packing) are set as default for HLSL shaders?


The reason for this will probably be that they had to pick one and since most maths that deals with matrices is written in column major order that's the one they went with.

Worked on titles: CMR:DiRT2, DiRT 3, DiRT: Showdown, GRID 2, theHunter, theHunter: Primal, Mad Max, Watch Dogs: Legion

This topic is closed to new replies.

Advertisement