Frage

In my first opengl 'voxel' project I'm using geometry shader to create cubes from gl_points and it works pretty well but I'm sure it can be done better. In the alpha color I'm passing info about which faces should be rendered ( to skip faces adjacent to other cubes) then vertices for visible faces are created using 'reference' cube definition. Every point is multiplied by 3 matrices. Instinct tells me that maybe whole face could be multiplied by them instead of every point but my math skills are poor so please advise.

#version 330 
layout (points) in;
layout (triangle_strip,max_vertices=24) out;

smooth out vec4 oColor;
in VertexData 
{
    vec4 colour;
    //vec3 normal;
} vertexData[];

uniform mat4 cameraToClipMatrix;
uniform mat4 worldToCameraMatrix;
uniform mat4 modelToWorldMatrix;

const vec4 cubeVerts[8] = vec4[8](
    vec4(-0.5 , -0.5, -0.5,1),  //LB   0
     vec4(-0.5, 0.5, -0.5,1), //L T   1
    vec4(0.5, -0.5, -0.5,1), //R B    2
    vec4( 0.5, 0.5, -0.5,1),  //R T   3
                        //back face
    vec4(-0.5, -0.5, 0.5,1), // LB  4
     vec4(-0.5, 0.5, 0.5,1), // LT  5
    vec4(0.5, -0.5, 0.5,1),  // RB  6
     vec4(0.5, 0.5, 0.5,1)  // RT  7
    );

const int  cubeIndices[24]  = int [24]
    (
      0,1,2,3, //front
      7,6,3,2, //right
      7,5,6,4,  //back or whatever
      4,0,6,2, //btm 
      1,0,5,4, //left
      3,1,7,5
    );      

void main()
{       
    vec4 temp;  
    int a = int(vertexData[0].colour[3]);
    //btm face
    if (a>31)
    {
        for (int i=12;i<16; i++)
        {
            int v = cubeIndices[i];
            temp = modelToWorldMatrix * (gl_in[0].gl_Position + cubeVerts[v]);
            temp = worldToCameraMatrix * temp;
            gl_Position = cameraToClipMatrix * temp;
            //oColor = vertexData[0].colour;
            //oColor[3]=1;
            oColor=vec4(1,1,1,1);       
            EmitVertex();
        }   
        a = a - 32;
        EndPrimitive(); 
    }
    //top face
    if (a >15 )
...
}

------- updated code:------

//one matrix to transform them all
mat4 mvp = cameraToClipMatrix * worldToCameraMatrix * modelToWorldMatrix;
//transform and store cube verts for future use 
for (int i=0;i<8; i++) 
{
    transVerts[i]=mvp * (gl_in[0].gl_Position + cubeVerts[i]);
}
//btm face
if (a>31)
{
    for (int i=12;i<16; i++)
    {
        int v = cubeIndices[i];
        gl_Position = transVerts[v];
        oColor = vertexData[0].colour*0.55;
        //oColor = vertexData[0].colour;
        EmitVertex();
    }   
    a = a - 32;
    EndPrimitive(); 
}
War es hilfreich?

Lösung

In OpenGL, you don't work with faces (or lines, for that matter), so you can't apply transformations to a face. You need to do it to the vertices that compose that face, as you're doing.

On possible optimization is that you don't need to separate out the matrix transformations, as you do. If you multiple them once in your application code, and pass them as a single uniform into your shader, that will save some time.

Another optimization would be to transform the eight cube vertices in a loop at the beginning, store them to a local array, and then reference their transformed positions in your if logic. Right now, if you render every face of the cube, you're transforming 24 vertices, each one three times.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top