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 8 of 8

Thread: Converting a vertex program to GLSL

Hybrid View

  1. #1
    Junior Member Newbie
    Join Date
    Nov 2013
    Posts
    4

    Converting a vertex program to GLSL

    I've been at this for quite some time, and lately, I've been having trouble finding other available OpenGL users out there to add their two cents, if possible. I have this vertex program that was originally written using GL_NV_vertex_program and I'm trying to port it to GLSL. What I have managed to do was to convert it to GL_ARB_vertex_program successfully, but the GLSL version doesn't work properly (getting garbage all over the screen).

    I've isolated the problem to a bad translation to GLSL. The offending instructions? I don't know what they are yet, but I have the feeling it involves the instructions that have the more complex and less obvious swizzling methods. Since I didn't write this code myself, there's only so much that I can decipher from an obvious level. This code was actually an old submission to an old version of the NVSDK from early 2001.

    Before I go further, I'll show you the ARB version, and my GLSL version, so you can see what I'm talking about. I hate to just dump some code on you guys, but I'm starting to get desperate.

    ARB (works):
    Code :
    !!ARBvp1.0
     
    # Ported from !!VP1.0 to !!ARBvp1.0 
    # by blueshogun96
     
    ATTRIB iPos = vertex.position;
    ATTRIB iCol = vertex.color;
    ATTRIB iTex = vertex.texcoord;
    ATTRIB iNor = vertex.normal;
     
    PARAM mvp[4] = {state.matrix.mvp};
    PARAM itmv[4] = {state.matrix.modelview.invtrans};
     
    #PARAM c0 = program.local[0];
    #PARAM c1 = program.local[1];
    #PARAM c2 = program.local[2];
    #PARAM c3 = program.local[3];
    #PARAM c4 = program.local[4];
    #PARAM c5 = program.local[5];
    #PARAM c6 = program.local[6];
     
    PARAM c8 = program.local[8];
    PARAM c9 = program.local[9];
    PARAM c10 = program.local[10];
    PARAM c11 = program.local[11];
    PARAM c12 = program.local[12];
    PARAM c13 = program.local[13];
    PARAM c14 = program.local[14];
    PARAM c15 = program.local[15];
    PARAM c16 = program.local[16];
    PARAM c17 = program.local[17];
     
    OUTPUT oPos = result.position;
    OUTPUT oCol = result.color;
    OUTPUT oTex = result.texcoord;
    #OUTPUT oNor = result.normal;
     
    TEMP R0;
    TEMP R1;
    TEMP R2;
    TEMP R3;
    TEMP R4;
    TEMP R5;
    TEMP R6;
     
    # R0 = (y coordinate of vertex * k) + (w * t)
    MAD R0.x, iPos.y, c16.x, c16.z;
     
    # R1 = cos(R0), R0 = any floating point number
    MUL R0.x, c11.w, R0.x; 
    EXP R0.y, R0.x; 
    SLT R2.x, R0.y, c11; 
    SGE R2.yz, R0.y, c11; 
    DP3 R2.y, R2, c14.zwzw;   
    ADD R5.xyz, -R0.y, c10; 
    MUL R5, R5, R5;
    MAD R0, c12.xyxy, R5, c12.zwzw; 
    MAD R0, R0, R5, c13.xyxy;      
    MAD R0, R0, R5, c13.zwzw;      
    MAD R0, R0, R5, c14.xyxy;      
    MAD R0, R0, R5, c14.zwzw;      
    DP3 R1.x, R0, -R2; 
     
    # R2 = R1 * c[10] + 1.0
    MAD R2.x, R1.x, c10.w, c10.z;
     
    # R3 = perturbed vertex
    # R4 = perturbed normal
    MOV R2.yw, c16;
    MUL R3, iPos, R2.xyxw;
    MUL R4, iNor, R2.yxyw;
     
    # Transform vertices into clip space via modelview-projection matrix
    DP4 oPos.x, R3, mvp[0];
    DP4 oPos.y, R3, mvp[1];
    DP4 oPos.z, R3, mvp[2];
    DP4 oPos.w, R3, mvp[3];
     
    # Transform normals via inverse transpose modelview matrix & normalize
    # R5 = transformed normal
    DP3 R5.x, R4, itmv[0];
    DP3 R5.y, R4, itmv[1];
    DP3 R5.z, R4, itmv[2];
    DP3 R5.w, R5, R5;
    RSQ R5.w, R5.w;
    MUL R5, R5, R5.w;
     
    # Get unit length eye vector to vertex....this is how we texture map
    # R6 = vector
    ADD R6, c8, iPos;
    DP3 R6.w, R6, R6;
    RSQ R6.w, R6.w;
    MUL R6, R6, R6.w;
     
    # Multiply by 0.5 for texture wrapping
    MUL R6, R6, c10.y;
     
    # Texture coord is dot product of normal and vector from eye to vertex
    DP3 oTex.x, R5, R6;
     
    # Pass color through
    MOV oCol, iCol;
     
    END

    GLSL (doesn't work, lots of garbage):
    Code :
    /* General purpose vectors */
    vec4 R0, R1, R2, R3, R4, R5, R6;
     
    /* Constants */
    uniform vec4 c8;
    //uniform vec4 c9;
    uniform vec4 c10;
    uniform vec4 c11;
    uniform vec4 c12;
    uniform vec4 c13;
    uniform vec4 c14;
    //uniform vec4 c15;
    uniform vec4 c16;
    //uniform vec4 c17;
     
    /* Matrices */
    mat4 mvp = gl_ModelViewProjectionMatrix;
    mat3 itmm = gl_NormalMatrix; //transpose(gl_ModelViewInverseMatrix);
     
    void main()
    {
        R0.x = ( gl_Vertex.y * c16.x ) + c16.z;
     
        R0.x *= c11.w;
        R0.y = exp( R0.x );
        R2.x = ( R0.y < c11.y ) ? 1.0 : 0.0;
        R2.y = R2.z = ( R0.y >= c11.y ) ? 1.0 : 0.0;
        R2.y = dot( R2, c14.zwzw );
        R5/*.xyz*/ = -R0.y + c10;
        R5 = R5 * R5;
        R0 = ( c12.xyxy * R5 ) + c12.zwzw;
        R0 = ( R0 * R5 ) + c13.xyxy;
        R0 = ( R0 * R5 ) + c13.zwzw;
        R0 = ( R0 * R5 ) + c14.xyxy;
        R0 = ( R0 * R5 ) + c14.zwzw;
        R1.x = dot( R0, -R2 );
     
        R2.x = ( R1.x * c10.w ) + c10.z;
     
        R2.yw = c16.yw;
        R3 = gl_Vertex * R2.xyxw;
        R4.xyz = gl_Normal * R2.yxy;
     
        gl_Position = R3 * mvp;
     
        R5.xyz = R4.xyz * itmm;
    //    R5 = R4 * itm;
        /*R5.w = dot( R5, R5 );
        R5.w = inversesqrt( R5.w );
        R5 = R5 * R5.w;*/
        R5 = normalize(R5);
     
        /*R6 = c8 + v_pos;
        R6.w = dot( R6, R6 );
        R6.w = inversesqrt( R6.w );
        R6 = R6 * R6.w;*/
        R6 = normalize( c8 + gl_Vertex );
     
        R6 = R6 * c10.y;
     
        gl_TexCoord[0].s = dot( R5, R6 );
     
        gl_FrontColor = gl_Color;
    }


    My theory is that there are 4 instructions that I did not translate properly.

    1. SLT R2.x, R0.y, c11;
    2. SGE R2.yz, R0.y, c11;
    3. ADD R5.xyz, -R0.y, c10;
    4. MOV R2.yw, c16;

    This is where I'm kinda confused. I understand what these instructions do, but I do not understand how the swizzling effects the output of each operation.

    1 & 2: I understand that x and then yz are the values being written to, but is the value in R0.y being compared to c11.y or the first component, c11.x? Or all of them?
    3. This is legal in GL_NV/ARB_vertex_program, but not in GLSL, so I don't understand how ARB handles this either. Is R0.y being subtracted from each component in c10, and input into R5.xyz?
    4. This also confuses me. So, am I moving c16.xy only into R2.yw? Or am I moving c16.yw only?

    Right now, I'm going through the ARB_vertex_program documentation trying to get a better understanding of how the swizzling works because I think I've been misunderstanding it the whole time. The official documentation isn't very straight forward IMO either. Any ideas? Thanks.

    Shogun

  2. #2
    Senior Member OpenGL Pro
    Join Date
    Jan 2012
    Location
    Australia
    Posts
    1,097
    You might have more success if you just try to program from the comments rather than trying to code each statement

    for example
    Code :
    // R0 = (y coordinate of vertex * k) + (w * t)
    float R0 = Position.y * C16.x + C16.z;
    // R1 = cos(R0), R0 = any floating point number
    float R1 = cos(R0);

  3. #3
    Junior Member Newbie
    Join Date
    Nov 2013
    Posts
    4
    Wow, I didn't realize anyone had responded to this thread. Thanks, but I tried that, and it broke everything.

    At this point, I *almost* got it working. The vertices still appear warped (as if the perspective was wrong) and I don't know why that is. My new shader looks like this:

    Code :
    /* Vertex attributes */
    attribute vec4 v_pos;
    attribute vec4 v_normal;
    varying float v_tex;
     
    /* Texture sampler */
    uniform sampler1D texture;
     
    /* General purpose vectors */
    vec4 R0, R1, R2, R3, R4, R5, R6;
     
    /* Constants */
    uniform vec4 c8;
    uniform vec4 c9;
    uniform vec4 c10;
    uniform vec4 c11;
    uniform vec4 c12;
    uniform vec4 c13;
    uniform vec4 c14;
    uniform vec4 c15;
    uniform vec4 c16;
    uniform vec4 c17;
     
    /* Matrices */
    mat4 mvp = gl_ModelViewProjectionMatrix;
    mat3 itmm = gl_NormalMatrix;
     
     
    void main()
    {
        R0 = R1 = R2 = R3 = R4 = R5 = R6 = vec4( 0, 0, 0, 1 );
        R0.x = ( v_pos.y * c16.x ) + c16.z;
     
        R0.x *= c11.w;
        R0.y = exp( R0.x );
        R2.x = ( R0.y < c11.y ) ? 1.0 : 0.0;
        R2.y = ( R0.y >= c11.y ) ? 1.0 : 0.0;
        R2.z = ( R0.y >= c11.y ) ? 1.0 : 0.0;
        R2.y = dot( R2, c14.zwzw );
        R5 = -R0.y + c10;
        R5 = R5 * R5;
        R0 = ( c12.xyxy * R5 ) + c12.zwzw;
        R0 = ( R0 * R5 ) + c13.xyxy;
        R0 = ( R0 * R5 ) + c13.zwzw;
        R0 = ( R0 * R5 ) + c14.xyxy;
        R0 = ( R0 * R5 ) + c14.zwzw;
        R1.x = dot( R0.xyz, -R2.xyz );
        //R1.x = cos(R0.x);
     
        R2.x = ( R1.x * c10.w ) + c10.z;
     
        R2.yw = c16.yw;
        R3 = v_pos * R2.xyxw;
        R4.xyz = v_normal.xyz * R2.yxy;
     
        gl_Position = R3 * mvp;
     
        R5.xyz = R4.xyz * itmm;
        R5.xyz = normalize(R5.xyz);
        R6.xyz = normalize( c8.xyz + v_pos.xyz );
        R6 = R6 * c10.y;
     
        v_tex = dot( R5.xyz, R6.xyz );
     
        gl_FrontColor = gl_Color;
    }

    I REALLY want to post a screenshot of this, but the forum won't let me (why is that?) and I think that would give you all a better idea of what is going on. I think it has something to do with the W coordinate and I don't fully understand much of the math/operations that are going on here. At this point, I'm ready to just pay someone to get it working because I have to get this fixed by January 18th (no pressure).

    Any more ideas?

    Shogun.

  4. #4
    Senior Member OpenGL Pro
    Join Date
    Jan 2012
    Location
    Australia
    Posts
    1,097
    I don't fully understand much of the math/operations that are going on here

    Can't help you much here


    Why do you initialize the the R-registers with vec4(0,0,0,1) and not vec4(0,0,0,0)?

    you can't post links until you have made a few normal post just to get down on spamming. You can post the link but just remove the http and change "." to "_dot_" - most people understand this here.

  5. #5
    Junior Member Newbie
    Join Date
    Nov 2013
    Posts
    4
    Quote Originally Posted by tonyo_au View Post

    Can't help you much here


    Why do you initialize the the R-registers with vec4(0,0,0,1) and not vec4(0,0,0,0)?

    you can't post links until you have made a few normal post just to get down on spamming. You can post the link but just remove the http and change "." to "_dot_" - most people understand this here.
    I can't remember exactly why I did that. There was some breakage that I *think* I fixed, but once again, I can't remember. Changing it back didn't really do anything.

    Anyway, I'll link a few pictures so you can all see what is going on visually.

    Good:
    i44.tinypic.com/5dqskn.png

    Bad:
    i42.tinypic.com/2jfhwgp.png
    i44.tinypic.com/5dqskn.png

    I'm quite sure it has something to do with the 2nd chunk of code. Still not sure if I converted it correctly, but I'll keep going over the ARB_vertex_program documentation in case I missed some detail. Thanks.

    Shogun.

  6. #6
    Senior Member OpenGL Pro
    Join Date
    Jan 2012
    Location
    Australia
    Posts
    1,097
    I see a couple of things that look odd
    Code :
    void main()
    {
        R0 = R1 = R2 = R3 = R4 = R5 = R6 = vec4( 0, 0, 0, 1 );
        R0.x = ( v_pos.y * c16.x ) + c16.z;
     
        R0.x *= c11.w;
        R0.y = exp( R0.x );
        R2.x = ( R0.y < c11.y ) ? 1.0 : 0.0;
        R2.y = ( R0.y >= c11.y ) ? 1.0 : 0.0;
        R2.z = ( R0.y >= c11.y ) ? 1.0 : 0.0;
        R2.y = dot( R2, c14.zwzw );
        R5 = -R0.y + c10;                                 // R5.xyz = 
        R5 = R5 * R5;
        R0 = ( c12.xyxy * R5 ) + c12.zwzw;
        R0 = ( R0 * R5 ) + c13.xyxy;
        R0 = ( R0 * R5 ) + c13.zwzw;
        R0 = ( R0 * R5 ) + c14.xyxy;
        R0 = ( R0 * R5 ) + c14.zwzw;
        R1.x = dot( R0.xyz, -R2.xyz );
        //R1.x = cos(R0.x);
     
        R2.x = ( R1.x * c10.w ) + c10.z;
     
        R2.yw = c16.yw;
        R3 = v_pos * R2.xyxw;
        R4.xyz = v_normal.xyz * R2.yxy;
     
        gl_Position = R3 * mvp;                           // looks odd usually mvp * R3
     
        R5.xyz = R4.xyz * itmm;
        R5.xyz = normalize(R5.xyz);
        R6.xyz = normalize( c8.xyz + v_pos.xyz );
        R6 = R6 * c10.y;
     
        v_tex = dot( R5.xyz, R6.xyz );

Posting Permissions

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