Sign in to follow this  
beuschl

DirectX: Problem with Geometry Shader

Recommended Posts

Hi Today was the first time I used the geometry shader and I have the following problem. I want to calculate the normal, tangent and binormal dynamical in the geometry shader (like it is described in the http://wiki.gamedev.net/index.php/D3DBook:%28Lighting%29_Per-Pixel_Lighting online-book) But when I want to compiel the shader I get the following two errors (without getting a line number were the error is) and I don't know what to do error X4580: emitting a system-interpreted value which is not written in every execution path of the shader error X4575: Reading uninitialized value Here is my test shader code:
cbuffer cbChangesEveryFrame
{
	matrix World;
	matrix WVPMatrix;			// WorldViewProjection Matrix
	float3 view_position;
};

struct PS_INPUT
{
float4 Pos : SV_POSITION;		// Position tranformed with WorldViewProjection Matrix
float4 WorldPos : POSITION;		// Position in World Space
float3 ViewDir : TEXCOORD0;
float3 LightDir : TEXCOORD1;
float2 Tex : TEXCOORD2;			// Texture coordinates
float3x3 TBNMatrix : TEXCOORD3;

};

// VERTEX SHADER

PS_INPUT VS(float4 Pos : POSITION, float2 Tex :TEXCOORD)
{
	PS_INPUT psInput;
	psInput.Pos = mul( Pos, WVPMatrix );
	psInput.WorldPos = mul(Pos, World);

	psInput.ViewDir = mul(view_position, (float3x3)World) - psInput.WorldPos;
	psInput.LightDir = g_vLightPositions -  psInput.WorldPos;
	psInput.Tex = Tex;

	return psInput;
}

// GEOMETRY SHADER

 [maxvertexcount(3)]
 void GS( triangle PS_INPUT input[3], inout TriangleStream<PS_INPUT> TriStream)
 {    
	 PS_INPUT output;
	 float3 A = input[1].WorldPos - input[0].WorldPos;
     float3 B = input[2].WorldPos - input[0].WorldPos;
 
     float2 P = input[1].Tex - input[0].Tex;
     float2 Q = input[2].Tex - input[0].Tex;
 
     float fraction = 1.0f / ( P.x * Q.y - Q.x * P.y );
 
     float3 normal = normalize( cross( A, B ) );
 
     float3 tangent = float3
     (
         (Q.y * A.x - P.y * B.x) * fraction,
         (Q.y * A.y - P.y * B.y) * fraction,
         (Q.y * A.z - P.y * B.z) * fraction
     );
 
     float3 bitangent = float3
     (
         (P.x * B.x - Q.x * A.x) * fraction,
         (P.x * B.y - Q.x * A.y) * fraction,
         (P.x * B.z - Q.x * A.z) * fraction
     );

     float NdotT = dot( normal, tangent );
     float NdotB = dot( normal, bitangent );
     float TdotB = dot( tangent, bitangent );
 

     tangent    = tangent - NdotT * normal;
     bitangent  = bitangent - NdotB * normal - TdotB * tangent;
 
	output.TBNMatrix[0] = tangent;
     output.TBNMatrix[1] = bitangent;
     output.TBNMatrix[2] = normal;
	 
	  TriStream.Append( output );
	 
	 TriStream.RestartStrip(); 
 }


Like I said I have zero experience with geometry shader and the DirectX Documentation doesn't answered all my questions ;)

Share this post


Link to post
Share on other sites
It looks like you should update to a newer version of the DirectX SDK. The March 2009 and soon to be released August 2009 SDK's are providing me different errors and line numbers for real issues with your shader.

What questions do you have about the geometry shader that aren't being answered by the docs?

Share this post


Link to post
Share on other sites
Mhm I have the March 2009 SDK and I use the Nvidia FX Composer 2.52... to compile the shader.

My question is: I fill my PS_INPUT structure in the vertex shader with some values (for example ViewDir)
Now I pass the structure to the geometry shader to calculate the TBN Matrix and then I output one finishes vertex to the pixel shader with
TriStream.Append( output );

Is that rigth so far? My question is if the values in the PS_INPUT structure (ViewDir, LightDir) are still stored when it comes to the pixel shader although the geometry shader do nothing with them?

Share this post


Link to post
Share on other sites
I don't know what nvidia composer is using to compile the shader. It may contain a version of the dx compiler which isn't up to date. Use fxc.exe from the March SDK to see what you get.

The input structure to the geometry shader should contain only the data that will be coming from the vertex shader. So, in this case it should not contain the TBN matrix yet. There should be a separate structure that you will pass from the geometry shader to the pixel shader that contains this extra data. You will have to do a copy on any members that you want to be passed through to the pixel shader. Streaming data between stages works the same for any two stages in a row in the pipeline. Whatever data you output from the first stage will be available to the second, provided that you use the same structure to both send and receive the streamed data.

The other issue with your shader is that you need to be doing 3 Appends(), one for each vertex in the triangle. You won't need the RestartStrip() here. Your output stream is a TriangleStream, so you always need to append data in at least groups of 3 in order to make a triangle for the pixel shader. Each vertex should have the same positional data as the corresponding incoming triangle array used as input to the gs. Each vertex will contain the same TBN matrix that you calculate in the gs.

Share this post


Link to post
Share on other sites

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