Hi GameDev.

Im currently having a problem with my geometry shader in which i want to billboard my particles to face the camera. Currently the bill boarding seems to work from most angles, however when i go to close to the particles they warp, and when at a certain position in which i look at the particles the bill board effect stops entirely until i have moved again.

Pictures to show, because my explanation skills are atrocious:

http://s720.photobucket.com/user/jbshadow1993/media/HELP.png.html

http://s720.photobucket.com/user/jbshadow1993/media/HELP2-1.png.html

In my eyes the calculation of the vectors for bill boarding is correct. However im skeptical about the need to multiply the new position of each vertex by the world matrix, as that had already been done in the vertex shader and been assigned to each new vertex generated.

Here is both vertex shader and geometry shader, hopefully its something stupid that i have missed or not understood correctly.

Any help is greatly appreciated.

cbuffer cbNeverChanges : register( b0 ) { matrix g_view; }; cbuffer cbChangeOnResize : register( b1 ) { matrix g_proj; }; //Camera position to work out billboarding cbuffer cbCameraPos : register( b2 ) { float4 g_camPos; }; struct VS_Input { float4 pos : POSITION; float2 tex0 : TEXCOORD0; float4x4 InstWorld : WORLD; float Size : SIZE; uint InstID : SV_InstanceID; }; struct GS_Input { float4 posL : POSITION1; float4 posH : POSITION2; float2 tex0 : TEXCOORD0; float4x4 InstWorld : WORLD; float Size : SIZE; }; struct GS_Output { float4 Pos : SV_POSITION; float2 TexCoords : TEXCOORD0; }; GS_Input VS( VS_Input vertex ) { GS_Input vsOut = ( GS_Input )0; //Transform the vertex position vsOut.posL = mul( vertex.pos, vertex.InstWorld ); vsOut.posH = mul( vsOut.posL, g_view ); vsOut.posH = mul( vsOut.posH, g_proj ); //Assign size so that it can be used in the gs vsOut.Size = vertex.Size; vsOut.InstWorld = vertex.InstWorld; vsOut.tex0 = vertex.tex0; return vsOut; } [maxvertexcount(4)] void GS(point GS_Input input[1], inout TriangleStream<GS_Output> outputStream) { //calculate the look at vector float3 lookVec = (float3)g_camPos - (float3)input[0].posL; lookVec = normalize(lookVec); //assign the up vec float3 upVec = float3(0.0f, 1.0f, 0.0f); //Calculate the right vector float3 rightVec = normalize(cross(upVec, lookVec)); // To use so that the particle will rotate around its centre float halfSize = input[0].Size / 2.0f; //Get the up vector of the quad float3 quadUpVec = normalize(cross(lookVec, rightVec)); //Times it by half the size to build quad from around the center quadUpVec = quadUpVec * halfSize; rightVec = rightVec * halfSize; // Create the positions of the quad float3 position[4]; //Top Left position[0] = (float3)input[0].posL - rightVec + quadUpVec; //Top Right position[1] = (float3)input[0].posL + rightVec + quadUpVec; //Bottom Left position[2] = (float3)input[0].posL - rightVec - quadUpVec; //Bottom Right position[3] = (float3)input[0].posL + rightVec - quadUpVec; float2 texcoords[4]; texcoords[0] = float2(1.0f, 0.0f); texcoords[1] = float2(1.0f, 1.0f); texcoords[2] = float2(0.0f, 0.0f); texcoords[3] = float2(0.0f, 1.0f); GS_Output newVertex; for(int k = 0; k < 4; k++) { //Assign position newVertex.Pos = mul(float4(position[k], 1.0f), input[0].InstWorld); newVertex.Pos = mul(newVertex.Pos, g_view); newVertex.Pos = mul(newVertex.Pos, g_proj); newVertex.TexCoords = texcoords[k]; outputStream.Append(newVertex); } }

Thanks

TaintedGear