2

シャドウマッピングについて混乱しています。これが私が理解したことです(以下の手順は機能していません:))

利益を得る方法(コードについて混乱しないでください。Javaで書いているからです):

1.パラメータを使用して空のdepthTexture(私のものは1024x1024)を作成します

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE)

glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, width, height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, GL_NULL)

2. FBOを作成し、そのテクスチャをそれに添付します

glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, depthTexture, 0)

3.照明カメラの新しい投影とビューマトリックスを設定します

シーンが良く見えるので、メインカメラと同じものを別の座標で使用しました(試してみたので、問題はありません...と思います)。

4.新しい小さなシェーダーを作成してFBOのgl_Positionを決定し、メインシェーダーを派手なもので変更します(バイアス行列* lightCamera行列*頂点、sampler2Dshadowなど)

5.もちろん、すべてを統一して何かをします。

そして今、レンダーループ

1.もちろん、すべてを統一し、(もう一度)何かをします。

2. FBOをバインドし、小さなシェーダーをバインドglViewport(0, 0, 1024, 1024)します、、 colorMaskをfalseにバインドし、深度バッファーをクリアしますglCullFace(GL_FRONT)、、glBindTexture(GL_TEXTURE_2D, 0)

3.頂点位置属性のみを使用してすべてを完全に無料でレンダリングします

4. FBOのバインドを解除し、プログラムをメインシェーダー(派手なものを含むもの)に再バインドしglViewport、colorMaskを有効にします。glCullFace(GL_BACK)

5.sampler2DShadow 「バインドしたり、均一にしたり、触れたりしないので、メインシェーダーがどうなるか」を考えずに、通常どおりにシーンをレンダリングします。

6.数え切れないほどのグリッチ、バグ、ピクセル乱交を見る

実際、サンプラーにdepthTextureを均一にしようとしましたが、黒い画面しかありません。また、FBOをレンダリングしなくても、レンダリングすると同じ画像が表示されます。

誰かが説明できますか、私は何が欠けていますか?

シェーダーがディフューズテクスチャをディフューズテクスチャとdepthTextureの2回使用しているように感じますが、そのdepthTextureを与える方法がわかりません。

4

1 に答える 1

4

読みやすいリンクは次のとおりです。 http://www.opengl-tutorial.org/intermediate-tutorials/tutorial-16-shadow-mapping/

そしてここ: http://www.paulsprojects.net/tutorials/smt/smt.html (2番目のリンクは古い固定関数openglを使用していますが)

一般に:

  1. 1 深度テクスチャを作成する
  2. このテクスチャを FBO にアタッチします
  3. FBO をバインドし、適切なビューポートを設定します
  4. ライト位置からシーンをレンダリングし、深度値のみをテクスチャに保存します
  5. FBO のバインドを解除し、最終シーンのビューポートとカメラ位置をセットアップします
  6. シャドウ テスト (sampler2DShadow) を使用してシーンを通常どおりレンダリングする

深度マップを常に (レンダー ループで) レンダリングすることも、ライトの位置が変化した場合にのみレンダリングすることもできます。

シーンを通常 2 回レンダリングしている理由がわかりません... Z-prepass などを使用していますか? 私が思う基本バージョンを試してみてください。

シャドウ マップを使用した古いコード:

void RenderShadowMap() {
    currDepth->Bind();
    glClear(GL_DEPTH_BUFFER_BIT);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gLightCam.SetProjectionMatrix();
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    gLightCam.SetViewMatrix();

    glColorMask(false, false, false, false);
    glUseProgram(0);   // draw without any shaders... just default depth
    glEnable(GL_POLYGON_OFFSET_FILL);
    glPolygonOffset(offFactor, offUnits);
    SimpleScene(false); // floor does not cast shadow so do not render it
    glDisable(GL_POLYGON_OFFSET_FILL);
    glColorMask(true, true, true, true);
}

レンダリング シーン:

// compose shadow matrix:
MATRIX4X4 bias(0.5f, 0.0f, 0.0f, 0.0f, 
               0.0f, 0.5f, 0.0f, 0.0f,
               0.0f, 0.0f, 0.5f, 0.0f,
               0.5f, 0.5f, 0.5f, 1.0f);
MATRIX4X4 *invCam = gSphericalCam.GetInvViewMatrix();
MATRIX4X4 smMat = (*gLightCam.GetViewProjMatrix()) * (*invCam);

gShaderProgramManager->GetProgram("shadow")->Use();
gShaderProgramManager->GetProgram("shadow")->SetMatrix("shadowMat", &smMat);
gShaderProgramManager->GetProgram("shadow")->SetBool("useShadow", currCam != &gLightCam && useShadow);
gShaderProgramManager->GetProgram("shadow")->SetFloat("shadowMapSize", (float)currDepth->GetWidth());
glActiveTexture(GL_TEXTURE0);
glEnable(GL_TEXTURE_2D);
glColor3f(1.0f, 1.0f, 1.0f);
gTextureManager->Bind("default");
glActiveTexture(GL_TEXTURE1);
currDepth->BindDepthAsTexture();
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL);

SimpleScene();
于 2013-01-09T17:44:00.400 に答える