質問

So i'm working on a project (to both learn and create a game in the future) in C++ and for rendering i've chose OpenGL 3.3. I've been working on Intel HD 4000 built in my processor as it opens default new apps and everything went sweet. But then i've tried to open it on my 2nd GPU - nVidia GTX660m which is much much faster one, and i've expected much more FPSes on it. But nope, not only i had dozens of dozens bugs (in example - Intel went ok if i've put out vec3 as color in fragment shader, but nVidia went full-on crazy style if i didnt put out vec4...). Of course not any errors at compile so its extremly hard to fix...

But now, when i've fixed most of it, im stuggling with one problem that i cannot fix as i would like (there could be some dirty ways but... that's not the point).

In short way: i generate on both GPU valid depth maps, but on nVidia GPU its not grey-scale, bur red-to-black scale Which is extremely odd, since same code on same machine (almost) should run the same (also same API!). Due to that fact my fragment shader propably doesnt catch-up with it, and on nVidia does not detect lit areas and its completly dark (at least in spotlight, directional light doesnt work).

Pics: Image when using Intel HD4000 (which comes from my i5 ivy-bridge cpu) Image when using nVidia GTX660m when running app from RMB menu. No soft shadows for "buildings" (big blocks) nor the flashlight effect (spot light)

IMPORTANT - Notice depth maps on GTX660m are redToBlack scale, not grey-scale like on Intel GPU. Top one is from directional light and bottom one is from point light of course.

My FragmentShader: #version 330 core

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);
}

First part is for directional light - i pre-sample depthmap in 5 points, if all are same i dont sample more (early bailing - much performance optimization!), or if some differs, i sample all and calculate intensity of shadow on current fragment.

Second part is simply sample from point light depth map, and then i check distance from center of the ray to simulate flashlight effect (stronger in the center).

I dont think anything more is needed but if is, please write and i'll post needed code.

ALSO - with shadowmaps only 16bits precision (GL_DEPTH_COMPONENT16) Intel HD4000 is faster then my GTX660m (which in way more powerfull) - this is very weird. Though i think its becouse i dont draw any high-poly, just many very-low-poly. Am I correct?

役に立ちましたか?

解決

I've got answer elsewhere. For future reference - sampling depth map uses Red channel (or .x value) like sample.r (/ sample.x), not .b (/ .z) like i had.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top