Jump to content
  • Advertisement
Sign in to follow this  

DirectX: Problem with Geometry Shader

This topic is 3257 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 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;



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;


 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 );

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
Sign in to follow this  

  • Advertisement

Important Information

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

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!