だから私はC ++で(将来的にゲームを学び、作成するために)プロジェクトに取り組んでおり、レンダリングのためにOpenGL 3.3を選択しました。デフォルトの新しいアプリを開き、すべてがうまくいったので、プロセッサーに組み込まれた Intel HD 4000 に取り組んできました。しかし、その後、2番目のGPUであるnVidia GTX660mで開こうとしましたが、これははるかに高速であり、より多くのFPSが期待されていました。しかし、いいえ、何十ものバグがあっただけではありません(たとえば、フラグメントシェーダーで色としてvec3を出力した場合、Intelは問題ありませんでしたが、vec4を出力しなかった場合、nVidiaは完全にクレイジーなスタイルになりました...)。もちろん、コンパイル時にエラーが発生するわけではないので、修正するのは非常に困難です...
しかし今、私はそれのほとんどを修正したとき、私が望むように修正できない1つの問題に苦労しています(いくつかの汚い方法があるかもしれませんが...それはポイントではありません)。
簡単に言えば、両方の GPU で有効な深度マップを生成しますが、nVidia GPU ではグレースケールではなく、バーの赤から黒へのスケールです。同じ API!)。そのため、私のフラグメント シェーダーはそれに追いつかない可能性が高く、nVidia では、照らされた領域と完全に暗い領域を検出しません (少なくともスポットライトでは、ディレクショナル ライトは機能しません)。
写真:
重要 - GTX660m の深度マップは、Intel GPU のようなグレースケールではなく、redToBlack スケールであることに注意してください。上はディレクショナル ライト、下はもちろんポイント ライトです。
マイ FragmentShader: #version 330 コア
in vec2 UV; //Coords for standard texture (model)
in vec4 ShadowCoord; //Coords for directional light (pos)
in vec4 POVShadowCoord; //Coords for spot light (flashlight) (pos)
out vec4 color; //Output color
uniform sampler2D myTextureSampler; //Standard texture with data for models
uniform sampler2D shadowMap; //Shadowmap for directional light
uniform sampler2D POVshadowMap; //Shadowmap for spot light (flashlight)
void main(){
vec3 tex_data = texture2D( myTextureSampler, UV ).rgb;
float bias = 0.005;
float visibility = 0.7;
float decrease = 0.002;
int early_bailing = 0;
if ( texture2D( shadowMap, ShadowCoord.xy + vec2(0,0)/1850.0 ).z < ShadowCoord.z-bias ) {
visibility -= decrease; early_bailing++;
}
if ( texture2D( shadowMap, ShadowCoord.xy + vec2(-2,-2)/1850.0 ).z < ShadowCoord.z-bias ) {
visibility -= decrease; early_bailing++;
}
if ( texture2D( shadowMap, ShadowCoord.xy + vec2(-2, 2)/1850.0 ).z < ShadowCoord.z-bias ) {
visibility -= decrease; early_bailing++;
}
if ( texture2D( shadowMap, ShadowCoord.xy + vec2( 2,-2)/1850.0 ).z < ShadowCoord.z-bias ) {
visibility -= decrease; early_bailing++;
}
if ( texture2D( shadowMap, ShadowCoord.xy + vec2( 2, 2)/1850.0 ).z < ShadowCoord.z-bias ) {
visibility -= decrease; early_bailing++;
}
if(early_bailing < 5) {
if(early_bailing > 0) {
for (int i=-2; i < 2; i++) {
for(int j = -2; j < 2; j++) {
if(i == 0 && j == 0) continue;
if(i == -2 && j == -2) continue;
if ( texture2D( shadowMap, ShadowCoord.xy + vec2(i,j)/850.0 ).z < ShadowCoord.z-bias )
visibility -= decrease;
}
}
}
} else {
visibility -= 14 * decrease;
}
float x = POVShadowCoord.x/POVShadowCoord.w;
float y = POVShadowCoord.y/POVShadowCoord.w;
bias = 0.0004;
if(x < 0 || x > 1 || y < 0 || y > 1) {
visibility -= 0.6;
} else {
float min_visibility = visibility - 0.6;
if ( textureProj( POVshadowMap, POVShadowCoord.xyw).z < (POVShadowCoord.z - bias)/POVShadowCoord.w) {
visibility = min_visibility;
} else {
//Flashlight effect
float dx = 0.5 - x;
float dy = 0.5 - y;
visibility -= sqrt(dx*dx + dy*dy);
if(visibility < min_visibility)
visibility = min_visibility;
}
}
color = vec4(visibility * tex_data, 1);
}
最初の部分はディレクショナル ライト用です - 5 つのポイントで深度マップを事前にサンプリングします。すべてが同じである場合は、それ以上サンプリングしません (早期ベイリング - パフォーマンスの最適化が大幅に向上します!)。または、一部が異なる場合は、すべてをサンプリングし、現在のフラグメントの影の強度を計算します。 .
2 番目の部分は、ポイント ライトの深度マップから単純にサンプリングしたものです。次に、レイの中心からの距離をチェックして、懐中電灯の効果 (中心が強い) をシミュレートします。
これ以上何も必要ないと思いますが、必要な場合は書いてください。必要なコードを投稿します。
また、シャドウマップの精度は 16 ビットのみ (GL_DEPTH_COMPONENT16) です。Intel HD4000 は私の GTX660m よりも高速です (これはより強力です)。これは非常に奇妙です。ハイポリを描いていないからだと思いますが、非常にローポリが多いだけです。私は正しいですか?