Sign in to follow this  

Shader about the fixed pipeline

This topic is 3410 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

Hi, there is some code like this: ///////////////////////////////////////////// //pDevice is a IDirect3DDevice9 pointer //pEffect is a ID3DXEffect pointer //hTechnique is a vaild technique handle ///////////////////////////////////////////// pEffect->SetTechnique( hTechnique ); pDevice->SetFVF( D3DFVF_XYZRHW | D3DFVF_TEX1 ); pDevice->DrawPrimitive(...); The used technique only contains a pixel shader, which accept a float2 UV and returns a float4 COLOR. ///////////////////////////////////////////// technique GaussBlur5x5 { pass P0 { PixelShader = compile ps_2_0 GaussBlur5x5_func(); MinFilter[0] = Point; AddressU[0] = Clamp; AddressV[0] = Clamp; } } So which vertex shader does the pipeline use to process vertices? And if I want to replace the SetFVF() function, what should I do? Thanks!

Share this post


Link to post
Share on other sites
If you don't specify a vertex shader in an effect technique, then the application of the technique does not change the vertex shader already set on the device. Usually, you will want to set all shaders for a technique, because the i/o structure between the shader stages generally varies depending on the usage of the technique.

As for replacing SetFVF, you should create a IDirect3D9VertexDeclaration9 object containing your vertex element descriptors, and use it by calling Device::SetVertexDeclaration. While SetFVF and this method are interchangeable at the most basic level, you will get an enormous amount of flexibility (arbitrary order and offsets of elements, ability to use multiple input streams) when you use vertex declarations instead of FVF codes.

Share this post


Link to post
Share on other sites
Evil things.

In all seriousness, you can expect undefined behavior if you use pixel shaders without vertex shaders.

In most cases I've seen, the default behavior is for the device to pass at least some vertex data through the pipeline. However, you cannot trust that this will happen - nor will you actually know what data you have available - so don't use pixel shaders without vertex shaders if you want to write robust code.

Mismatching vertex formats, missing and/or malfunctioning shaders and data structure mismatches can create all kinds of nice bugs, including access violations in both hardware and software; these, in turn, cause blue screens if you're lucky, and random behavior such as potential loss of data if you're unlucky. Professional programmers tend not to trust luck on these things.

Note that the omission of the vertex shader from the effect technique is perfectly legal, if you have set a vertex shader (output of which matches the technique's PS input) at least once in the host application.

Share this post


Link to post
Share on other sites
Oh, if I use a technique which just contains a pixel shader but still use
SetFVF() function, the default vertex shader will be implicitly used.
And if I use the same technique but do NOT use SetFVF(), undefined behavior may be happen, am I right?

Thanks again.

Share this post


Link to post
Share on other sites
The problem here is that "default vertex shader" is likely non-existent or, if it does exist, you don't know exactly what it outputs.

A basic vertex shader is not very difficult to write, so I heavily recommend that you do just that [smile]

The default fixed-function T/L processing does very little other than multiplies the incoming position and normal by the world*view*projection matrix, optionally calculates basic diffuse and specular lighting, optionally transforms or generates texture coordinates, and passes the data to the rasterizer. These are very trivial operations to emulate in a vertex shader.


struct PS_IN //pixel shader input
{
float4 pos : POSITION; //rasterizer needs position
float4 diffuse : COLOR;
float2 texcoord : TEXCOORD;
//add or remove stuff as needed
};

struct VS_IN //vertex shader input; should match vertex format
{
float4 pos : POSITION;
float3 normal : NORMAL;
float2 texcoord : TEXCOORD;
//add or remove stuff as needed
};

//constants; set these from the host program using ID3DXBaseEffect::Set* calls
float4x4 wvp; // world*view*projection matrix
float3 lightdir; // light direction

PS_IN BasicVS (VS_IN input) //vertex shader
{
PS_IN ret; //allocate structure to send to pixel shader
ret.pos = mul(input.pos, wvp); //transform position to projection space
ret.color = saturate (dot(normalize(mul(input.normal, (float3x3)wvp)), lightdir)); //calculate basic diffuse lighting
ret.texcoord = input.texcoord; //pass the incoming texcoord directly to ps
//add or remove stuff as needed
return ret;
}

//...pixel shader omitted...

//...techniques omitted...




You must use either SetFVF or SetVertexDeclaration. The hardware does not attempt to (and cannot) guess what the data layout of your incoming vertices is.

If you are using the ID3DXMesh interfaces, they call SetFVF or SetVertexDeclaration automatically behind the scenes when you call DrawSubset.

[Edited by - Nik02 on August 15, 2008 4:02:10 AM]

Share this post


Link to post
Share on other sites
I understand. Thanks very much! And I have another question.

How to declare a vertex declaration for the combination like this:
[ D3DFVF_XYZRHW | D3DFVF_TEX2 ] but without [ D3DFVF_TEX1 ]

////////////////////////////////////////////////////////////
D3DVERTEXELEMENT9 FVF[] =
{
{ 0, 0, D3DDECLTYPE_FLOAT4,D3DDECLMETHOD_DEFAULT,D3DDECLUSAGE_POSITION, 0 },//POS
{ 0, 16,D3DDECLTYPE_FLOAT2,D3DDECLMETHOD_DEFAULT,D3DDECLUSAGE_TEXCOORD, [0or1]? },
D3DDECL_END()
};
////////////////////////////////////////////////////////////

Note: I do not use D3DDECLUSAGE_POSITION[T] because I want to use shader to do the conversion myself.

Share this post


Link to post
Share on other sites
Quote:
Original post by wswqwps
Oh, if I use a technique which just contains a pixel shader but still use
SetFVF() function, the default vertex shader will be implicitly used.
And if I use the same technique but do NOT use SetFVF(), undefined behavior may be happen, am I right?

Your usage looks fine to me, but I think it'd be safer and clearer to use "FVF = ..." within the technique, instead of setting it in the code.

Share this post


Link to post
Share on other sites

This topic is 3410 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.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this