質問

ARB_geometry_shader4 によれば、シーンをジオメトリシェーダーを備えたキューブマップの6つの面と、フレームバッファーオブジェクトにアタッチされたキューブマップ。この方法を使用してシャドウマップを作成します。ただし、解決できない競合があるようです:

  1. GL_DEPTH_COMPONENTを内部タイプとして持つテクスチャのみをGL_DEPTH_ATTACHMENT_EXTにアタッチできます。
  2. 深度テクスチャは1Dまたは2Dのみです。
  3. キューブマップを添付する場合、他のすべてのテクスチャもキューブマップでなければなりません。

つまり、キューブマップにレンダリングする場合、深度テストを使用できないようです。または、ここに何が欠けていますか?

編集:新しいNvidiaドライバー(180.48)はデプスキューブマップをサポートしているようです。

役に立ちましたか?

解決

OK、他のいくつかの質問に答えるには:

もちろん、顔ごとに1つずつ、6つのFBOを使用できます。または、1つのFBOを使用して、描画する前に各面をアタッチします。どちらの場合でも、キューブマップの面は他の2Dテクスチャと同様に扱われ、通常の2DテクスチャまたはRenderbufferと一緒に使用できます。そして、おそらくすべての可能な方法に大きな違いはありません(ハードウェアがサポートしている場合)。

ただし、すべてを1つのステップで描画することも可能です。これがどのように行われるかについて興味があったので、いくつかの研究を行いました。

単一のアタッチメントポイントにアタッチされたキューブマップのすべての面でFBOを作成するには、次のコードを使用しました(Dで記述):

// depth cube map
glGenTextures(1, &tDepthCubeMap);
glBindTexture(GL_TEXTURE_CUBE_MAP, tDepthCubeMap);
glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
for (uint face = 0; face < 6; face++) {
    glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, 0, GL_DEPTH_COMPONENT24,
        width, height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, null);
}

// color cube map
glGenTextures(1, &tColorCubeMap);
glBindTexture(GL_TEXTURE_CUBE_MAP, tColorCubeMap);
glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
for (uint face = 0; face < 6; face++) {
    glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, 0, GL_RGBA,
        width, height, 0, GL_RGBA, GL_FLOAT, null);
}

// framebuffer object
glGenFramebuffersEXT(1, &fbo);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
glFramebufferTextureARB(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, tDepthCubeMap, 0);
glFramebufferTextureARB(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, tColorCubeMap, 0);

glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);

if (!isValidFBO()) {
    glDeleteFramebuffersEXT(1, &fbo);
    fbo = 0;
}
  • デプスマップのみが必要な場合は、 glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT); glDrawBuffer(GL_NONE); に変更してから、検証する(そして描画する前に)必要がある)
  • MINおよびMAGフィルターは有効な値に設定する必要があります(デフォルトはGL_NEAREST_MIPMAP_LINEARです)
  • すべてのテクスチャの幅と高さは同じでなければなりません

キューブマップの面にレンダリングするには、ジオメトリシェーダーが必要です。次のシェーダーはいくつかの回転を逃しますが、それが何をするのかは明らかです。 gl_Layerを使用して、プリミティブを正しい面に向けます(0 = + X、1 = -X、...)。

#version 120
#extension GL_EXT_geometry_shader4 : enable

void main(void) {
    int i, layer;
    for (layer = 0; layer < 6; layer++) {
        gl_Layer = layer;
        for (i = 0; i < 3; i++) {
            gl_Position = gl_PositionIn[i];
            EmitVertex();
        }
        EndPrimitive();
    }
}
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top