Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 5 of 5

Thread: strange problems with billboard shader (Geometry shader)

Hybrid View

  1. #1
    Junior Member Newbie
    Join Date
    Nov 2012
    Posts
    5

    strange problems with billboard shader (Geometry shader)

    Hi guys, I've been trying to fix this problem for a while now. And I think I'm a little crazier because of it, I've already posted this issue in the GameDev.net forums, but they couldn't help me.

    So basically certain things don't travel through the shader properly, for example, they get recognized in the geometry shader, but not in the vertex and visa-versa.

    Anyways codes are below, I've tried so many different variations on the shaders. Including layout locations and have gotten different results from different locations.

    Geometry Shader
    Code :
    #version 330
    #extension GL_ARB_separate_shader_objects : enable
     
     
     
    layout (points) in;
    layout (triangle_strip) out;
    layout (max_vertices = 4) out;
     
     
    uniform mat4 gVP;
    uniform vec3 gCameraPos;
     
     
     
    layout (location = 1) in float inScale[1];
    layout (location = 3) in vec4 inTexCoord[1];
    layout (location = 2) in vec4 inColor[1];
     
     
     
    layout (location = 3) out vec2 TexCoord;
    layout (location = 2) out vec4 Color;
     
     
     
    void main(void)
    {
    	vec3 Pos = gl_in[0].gl_Position.xyz;
     
    	vec3 toCamera = normalize(gCameraPos - Pos);
    	vec3 up = vec3(0.0, 1.0, 0.0);
    	vec3 right = cross(toCamera, up);
     
     
    	vec2 tcTL = inTexCoord[0].xy;
    	vec2 tcBR = vec2(inTexCoord[0].z,inTexCoord[0].w);
    	float Sc = 20.0;
    	vec4 col = inColor[0];
     
    	Pos -= (right * (Sc * 0.5));
    	Pos.y -= Sc * 0.5;
    	gl_Position = gVP * vec4(Pos, 1.0);
    	TexCoord = vec2(tcTL.x, tcTL.y);
    	Color = col;
    	EmitVertex();
     
    	Pos.y += Sc;
    	gl_Position = gVP * vec4(Pos, 1.0);
    	TexCoord = vec2(tcTL.x, tcBR.y);
    	Color = col;
    	EmitVertex();
     
    	Pos.y -= Sc;
    	Pos += right * Sc;
    	gl_Position = gVP * vec4(Pos, 1.0);
    	TexCoord = vec2(tcBR.x, tcTL.y);
    	Color = col;
    	EmitVertex();
     
    	Pos.y += Sc;
    	gl_Position = gVP * vec4(Pos, 1.0);
    	TexCoord = vec2(tcBR.x, tcBR.y);
    	Color = col;
    	EmitVertex();
     
    	EndPrimitive();
    }

    Vertex Shader
    Code :
    #version 330
    #extension GL_ARB_separate_shader_objects : enable
     
     
     
     
    in vec3 Position;
    layout (location = 3) in vec2 TexCoord;
    layout (location = 2) in vec4 Color;
     
     
     
    // vertex shader
     
    layout (location = 3) out vec2 TexCoordOut;
    layout (location = 2) out vec4 ColorOut;
     
     
     
    void main(void)
    {
        gl_Position = vec4(Position, 1.0);
    	TexCoordOut = TexCoord;
    	ColorOut = Color;
    }

    Fragment Shader
    Code :
    #version 330
    #extension GL_ARB_separate_shader_objects : enable
     
     
    uniform sampler2D TextureMap;
    uniform float Alpha;
     
    // fragment shader
    layout (location = 3) in vec2 TexCoordOut;
    flat layout (location = 2) in vec4 ColorOut;
     
     
    out vec4 outputF;
     
     
     
    void main(void)
    {
    	//vec4 tex = texture(TextureMap, TexCoordOut.xy);
    	//tex.a *= Alpha;
    	//tex *= ColorOut;
    	//if (tex.a <= 0.0)
    	//{
    	//	discard;
    	//}
    	//else
    	//{
    		vec4 Test = ColorOut;
     
    		//This test will show the correct result by colouring it the correct colour, then having the texture cut out the center
    		//I have gotten the correct result from the texture once, but not the colour at the same time :(
    		outputF = Test - texture(TextureMap, TexCoordOut.xy);
    	//}
    }

    Below here is c# code, the library I'm using is OpenTK. As far as I can tell from various tests is that the VBO data is infact correct.
    But I'm not sure about the VAO code. I've referenced the VBO construction further down.

    VAO code
    Code :
                    GL.GenVertexArrays(1, out VAOID);
                    GL.BindVertexArray(VAOID);
     
                    GL.EnableVertexAttribArray(0);
                    GL.BindBuffer(BufferTarget.ArrayBuffer, VertID);
                    GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, true, Vector3.SizeInBytes, 0);
                    GL.BindAttribLocation(BillboardShader, 0, "Position");
     
                    GL.EnableVertexAttribArray(1);
                    GL.BindBuffer(BufferTarget.ArrayBuffer, ScaleID);
                    GL.VertexAttribPointer(1, 1, VertexAttribPointerType.Float, false, sizeof(float), 0);
                    GL.BindAttribLocation(BillboardShader, 1, "inScale");
     
                    GL.EnableVertexAttribArray(3);
                    GL.BindBuffer(BufferTarget.ArrayBuffer, CoordID);
                    GL.VertexAttribPointer(3, 4, VertexAttribPointerType.Float, true, Vector4.SizeInBytes, 0);
                    GL.BindAttribLocation(BillboardShader, 3, "inTexCoord");
     
     
                    GL.EnableVertexAttribArray(2);
                    GL.BindBuffer(BufferTarget.ArrayBuffer, ColorID);
                    GL.VertexAttribPointer(2, 4, VertexAttribPointerType.Float, false, Vector4.SizeInBytes, 0);
                    GL.BindAttribLocation(BillboardShader, 2, "inColor");
     
     
                    GL.BindVertexArray(0);

    VBO Code
    Code :
    if (VertID == 0)
                {
                    GL.GenBuffers(1, out VertID);
                    GL.BindBuffer(BufferTarget.ArrayBuffer, VertID);
                }
                else
                {
                    GL.BindBuffer(BufferTarget.ArrayBuffer, VertID);
     
                    GL.BufferData(BufferTarget.ArrayBuffer,
                        new IntPtr(Vertices.Length * Vector3.SizeInBytes),
                        IntPtr.Zero, BufferUsageHint.DynamicDraw);
                }
     
                GL.BufferData<Vector3>(BufferTarget.ArrayBuffer,
                        new IntPtr(Vertices.Length * Vector3.SizeInBytes),
                        Vertices, BufferUsageHint.DynamicDraw);
     
                if (ScaleID == 0)
                {
                    GL.GenBuffers(1, out ScaleID);
                    GL.BindBuffer(BufferTarget.ArrayBuffer, ScaleID);
                }
                else
                {
                    GL.BindBuffer(BufferTarget.ArrayBuffer, ScaleID);
     
                    GL.BufferData(BufferTarget.ArrayBuffer,
                        new IntPtr(Scales.Length * sizeof(float)),
                        IntPtr.Zero, BufferUsageHint.DynamicDraw);
                }
     
                GL.BufferData<float>(BufferTarget.ArrayBuffer,
                        new IntPtr(Scales.Length * sizeof(float)),
                        Scales, BufferUsageHint.DynamicDraw);
     
                if (CoordID == 0)
                {
                    GL.GenBuffers(1, out CoordID);
                    GL.BindBuffer(BufferTarget.ArrayBuffer, CoordID);
                }
                else
                {
                    GL.BindBuffer(BufferTarget.ArrayBuffer, CoordID);
     
                    GL.BufferData(BufferTarget.ArrayBuffer,
                        new IntPtr(Coords.Length * Vector4.SizeInBytes),
                        IntPtr.Zero, BufferUsageHint.DynamicDraw);
                }
     
                GL.BufferData<Vector4>(BufferTarget.ArrayBuffer,
                        new IntPtr(Coords.Length * Vector4.SizeInBytes),
                        Coords, BufferUsageHint.DynamicDraw);
     
     
                if (ColorID == 0)
                {
                    GL.GenBuffers(1, out ColorID);
                    GL.BindBuffer(BufferTarget.ArrayBuffer, ColorID);
                }
                else
                {
                    GL.BindBuffer(BufferTarget.ArrayBuffer, ColorID);
     
                    GL.BufferData(BufferTarget.ArrayBuffer,
                        new IntPtr(Colors.Length * Vector4.SizeInBytes),
                        IntPtr.Zero, BufferUsageHint.DynamicDraw);
                }
     
                GL.BufferData<Vector4>(BufferTarget.ArrayBuffer,
                        new IntPtr(Colors.Length * Vector4.SizeInBytes),
                        Colors, BufferUsageHint.DynamicDraw);

    Here's the result:



    As you can see from the above image the colours are correct (the clouds seem to have the correct alpha, which is the fourth element of the colour). I've had to set the Scale to 20.0 because otherwise you don't see anything, which I believe means the Geometry shader thinks inScale is 0, even though it's somewhere between 20 and 100 according to the c# debugger...

    Thanks for any help, it's greatly appreciated

  2. #2
    Senior Member OpenGL Guru
    Join Date
    May 2009
    Posts
    4,948
    Your code is very confusing.

    First, you meticulously provide a layout(location) for every input and output... except for `Position`. Why? Is there something wrong with assigning it?

    Second, you then meticulously assign an attribute index to inputs... to the geometry shader. The geometry shader doesn't have attributes. So you're not doing anything productive there. You cannot pass attributes directly to the GS; the GS gets its inputs from the vertex shader.

    If you had linked your program together, you'd have gotten a linker error because of the third problem: `inScale` is never defined in the vertex shader. The VS never defines an output variable for location 1, so the GS gets undefined values in location 1. That's how it works. There's no magic passing of values from attributes directly to the GS. If the GS needs data, the VS must feed it data.

  3. #3
    Junior Member Newbie
    Join Date
    Nov 2012
    Posts
    5
    wow, that's a massive eye-opener, here I was thinking the geometry shader came first. I didn't assign 'Position' because it was the only one that consistently worked haha. Thanks I understand it a lot better now. I wonder why it didn't error though :/ maybe my drivers are a bit too friendly if you know what I mean.

    P.S. I Love you <3 . You're a life saver
    P.S.S I'm sorry about the confusing code


  4. #4
    Junior Member Newbie
    Join Date
    Nov 2012
    Posts
    5
    My original reply seems to have vanished. So now I'm posting in the non-quick-reply.

    Anyway what I said before was: Thanks heaps, I didn't realise the geometry shader was after the vertex shader. It's now working great

    And sorry about the confusing code.

  5. #5

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •