2

私の最初のopengl'voxel'プロジェクトでは、ジオメトリシェーダーを使用してgl_pointsからキューブを作成しています。これは非常にうまく機能しますが、もっとうまくできると確信しています。アルファカラーでは、どの面をレンダリングするか(他の立方体に隣接する面をスキップするため)に関する情報を渡します。次に、「参照」立方体定義を使用して、表示される面の頂点を作成します。すべての点に3つの行列が掛けられます。本能は、多分顔全体がすべての点ではなくそれらで乗算される可能性があると私に言いますが、私の数学のスキルは貧弱なので、アドバイスしてください。

#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 )
...
}

-------更新されたコード:------

//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(); 
}
4

1 に答える 1

2

OpenGLでは、面(または線)を操作しないため、面に変換を適用することはできません。あなたがしているように、あなたはその顔を構成する頂点にそれをする必要があります。

可能な最適化では、行列変換を分離する必要はありません。アプリケーションコードでそれらを1回多重化し、それらを単一のユニフォームとしてシェーダーに渡すと、時間を節約できます。

もう1つの最適化は、最初にループ内の8つの立方体頂点を変換し、それらをローカル配列に格納してから、変換された位置をifロジックで参照することです。現在、立方体のすべての面をレンダリングすると、24個の頂点がそれぞれ3回変換されます。

于 2013-01-28T17:56:10.417 に答える