openGL バージョン 3.3 で全方向/点照明を作成しようとしています。私はインターネットとこのサイトを検索しましたが、これまでのところこれを達成できませんでした. 私の理解から、私はすることになっています
深度コンポーネントを使用してフレーム バッファを生成する
キューブマップを生成し、それを上記のフレームバッファにバインドします
列挙型 GL_TEXTURE_CUBE_MAP_* によって参照されるように、キューブマップの個々の部分に描画します
シーンを通常どおりに描画し、フラグメントの深度値をキューブマップの深度値と比較します
今、キューブマップのルックアップが簡単になるため、フラグメントの深さを保存するよりも、ライトからフラグメントまでの距離を使用する方が良いと読みました(個々のテクスチャをチェックする必要がないことについての何か?)
私の現在の問題は、出てくる光が実際には球であり、影を生成しないことです。もう 1 つの問題は、フレーム バッファーが完全でないと文句を言うことですが、テクスチャにレンダリングする場合、フレーム バッファーはレンダー バッファーを必要としないという印象を受けました。
フレームバッファとキューブ マップの初期化は次のとおりです。
framebuffer = 0;
glGenFramebuffers(1, &framebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
glGenTextures(1, &shadowTexture);
glBindTexture(GL_TEXTURE_CUBE_MAP, shadowTexture);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);GL_COMPARE_R_TO_TEXTURE);
for(int i = 0; i < 6; i++){
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i , 0,GL_DEPTH_COMPONENT16, 800, 800, 0,GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
}
glDrawBuffer(GL_NONE);
シャドウ頂点シェーダー
void main(){
gl_Position = depthMVP * M* vec4(position,1);
pos =(M * vec4(position,1)).xyz;
}
シャドウ フラグメント シェーダー
void main(){
fragmentDepth = distance(lightPos, pos);
}
Vertex Shader (無関係な部分を切り取ったもの)
uniform mat4 depthMVP;
void main() {
PositionWorldSpace = (M * vec4(position,1.0)).xyz;
gl_Position = MVP * vec4(position, 1.0 );
ShadowCoord = depthMVP * M* vec4(position, 1.0);
}
Fragment Shader (無関係なコードカット)
uniform samplerCube shadowMap;
void main(){
float bias = 0.005;
float visibility = 1;
if(texture(shadowMap, ShadowCoord.xyz).x < distance(lightPos, PositionWorldSpace)-bias)
visibility = 0.1
}
おそらく考えているように、depthMVP とは何ですか? 深度射影行列は現在、各方向の範囲が [-10, 10] の正射影です。これらは次のように定義されています。
glm::mat4 depthMVP = depthProjectionMatrix* ??? *i->getModelMatrix();
ここでの問題は、??? が何なのかわからないということです。価値があるはずです。以前はカメラマトリックスでしたが、それが本来あるべきものかどうかはわかりません。次に、キューブマップの側面に対して描画コードが次のように実行されます。
for(int loop = 0; loop < 6; loop++){
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_CUBE_MAP_POSITIVE_X+loop, shadowTexture,0);
glClear( GL_DEPTH_BUFFER_BIT);
for(auto i: models){
glUniformMatrix4fv(modelPos, 1, GL_FALSE, glm::value_ptr(i->getModelMatrix()));
glm::mat4 depthMVP = depthProjectionMatrix*???*i->getModelMatrix();
glUniformMatrix4fv(glGetUniformLocation(shadowProgram, "depthMVP"),1, GL_FALSE, glm::value_ptr(depthMVP));
glBindVertexArray(i->vao);
glDrawElements(GL_TRIANGLES, i->triangles, GL_UNSIGNED_INT,0);
}
}
最後に、シーンが正常に描画されます (詳細は省きます)。キューブマップへの描画を呼び出す前に、フレームバッファーを以前に生成したものに設定し、ビューポートを 800 x 800 に変更します。通常の描画を行う前に、フレームバッファーを 0 に戻し、ビューポートを 800 x 600 にリセットします。この件に関するヘルプは大歓迎です。
更新 1
いくつかの微調整とバグ修正の後、これが得られる結果です。depthMVP が機能しないというエラーを修正しました。ここで描画しているのは、キューブマップに格納されている距離です。 http://imgur.com/JekOMvf
基本的に何が起こるかは、両側に同じ片側投影を描画することです。両側に同じビュー マトリックスを使用するため、これは理にかなっていますが、どのような種類のビュー マトリックスを使用すればよいかわかりません。中心に位置し、立方体マップ側の方向を見るlookAt()行列であるはずだと思います。ただし、発生する問題は、これらの複数のプロジェクションをメインの描画呼び出しでどのように使用することになっているのかということです。
更新 2
先に進んでこれらのマトリックスを作成しましたが、それらがどれほど有効かはわかりません (DX キューブマップの Web サイトから取得したため、Z 座標を反転させました)。
case 1://Negative X
sideViews[i] = glm::lookAt(glm::vec3(0), glm::vec3(-1,0,0),glm::vec3(0,-1,0));
break;
case 3://Negative Y
sideViews[i] = glm::lookAt(glm::vec3(0), glm::vec3(0,-1,0),glm::vec3(0,0,-1));
break;
case 5://Negative Z
sideViews[i] = glm::lookAt(glm::vec3(0), glm::vec3(0,0,-1),glm::vec3(0,-1,0));
break;
case 0://Positive X
sideViews[i] = glm::lookAt(glm::vec3(0), glm::vec3(1,0,0),glm::vec3(0,-1,0));
break;
case 2://Positive Y
sideViews[i] = glm::lookAt(glm::vec3(0), glm::vec3(0,1,0),glm::vec3(0,0,1));
break;
case 4://Positive Z
sideViews[i] = glm::lookAt(glm::vec3(0), glm::vec3(0,0,1),glm::vec3(0,-1,0));
break;
これらは6つの個別の行列であるため、depthMVPビュー部分を何によって翻訳することになっているのかという問題がまだ残っています。これは、同じ frag シェーダ (つまり、実際に影をレンダリングする) を使用した現在の外観のスクリーンショット ですhttp://i.imgur.com/HsOSG5v.png問題。これを生成するために使用したビュー マトリックスは、カメラの位置の逆変換にすぎません (lookAt() 関数が行うように)。
アップデート 3
現在のコード: Shadow Vertex
void main(){
gl_Position = depthMVP * vec4(position,1);
pos =(M * vec4(position,1)).xyz;
}
影の欠片
void main(){
fragmentDepth = distance(lightPos, pos);
}
主頂点
void main(){
PositionWorldSpace = (M*vec4(position, 1)).xyz;
ShadowCoord = vec4(PositionWorldSpace - lightPos, 1);
}
メインフラグ
void main(){
float texDist = texture(shadowMap, ShadowCoord.xyz/ShadowCoord.w).x;
float dist = distance(lightPos, PositionWorldSpace);
if(texDist < distance(lightPos, PositionWorldSpace)
visibility = 0.1;
outColor = vec3(texDist);//This is to visualize the depth maps
}
使用されている透視マトリックス
glm::mat4 depthProjectionMatrix = glm::perspective(90.f, 1.f, 1.f, 50.f);
現在、すべてが機能しています。テクスチャが格納するデータ (つまり、距離) は、奇妙な方法で格納されているようです。すべての値が 0 から 1 の間であるため、正規化されているように見えます。また、ビューアの周りに投影のない 1x1x1 の領域がありますが、これは視錐台によるものであり、簡単に修正できると思います (カメラを中央に 0.5 オフセットします)。