OpenGL 3.3 两个 GPU 上的两个不同结果 nVidia Optimus 与阴影映射

Posted

技术标签:

【中文标题】OpenGL 3.3 两个 GPU 上的两个不同结果 nVidia Optimus 与阴影映射【英文标题】:OpenGL 3.3 Two different results on two GPUs nVidia Optimus with Shadow mapping 【发布时间】:2013-07-17 17:27:18 【问题描述】:

所以我正在使用 C++ 开发一个项目(既要学习又要在未来创建游戏),我选择了 OpenGL 3.3 进行渲染。我一直在研究我的处理器中内置的 Intel HD 4000,因为它会打开默认的新应用程序,一切都很顺利。但后来我尝试在我的第二个 GPU - nVidia GTX660m 上打开它,它的速度要快得多,而且我预计它会有更多的 FPS。但是,不,不仅我有几十个错误(例如 - 如果我在片段着色器中将 vec3 作为颜色输出,英特尔就可以了,但如果我没有输出 vec4,nVidia 就完全疯狂了......)。当然编译时没有任何错误,所以它很难修复......

但是现在,当我修复了大部分问题时,我正苦苦挣扎着一个我无法按照我想要的方式解决的问题(可能有一些肮脏的方式,但......这不是重点)。

简而言之:我在两个 GPU 上生成有效的深度图,但在 nVidia GPU 上它不是灰度图,而是从红到黑的比例 这非常奇怪,因为相同的代码机器(几乎)应该运行相同的(也是相同的 API!)。由于这个事实,我的片段着色器可能没有赶上它,并且在 nVidia 上没有检测到被照亮的区域并且它完全黑暗(至少在聚光灯下,定向光不起作用)。

图片:

重要 - 请注意 GTX660m 上的深度图是 redToBlack 比例,而不是像 Intel GPU 上那样的灰度。 上面一张来自定向光,下面一张当然来自点光。

我的片段着色器: #版本 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 个点中预采样深度图,如果所有点都相同,我不会采样更多(早期保释 - 很多性能优化!),或者如果有些不同,我会全部采样并计算阴影强度在当前片段上。

第二部分是简单地从点光深度图中采样,然后我检查到光线中心的距离以模拟手电筒效果(中心更强)。

我认为不需要更多,但如果需要,请写下来,我会发布所需的代码。

ALSO - 阴影贴图只有 16 位精度 (GL_DEPTH_COMPONENT16) 英特尔 HD4000 比我的 GTX660m 更快(它更强大) - 这很奇怪。虽然我认为这是因为我不画任何高多边形,只是很多非常低的多边形。我说的对吗?

【问题讨论】:

我已经在另一台笔记本电脑上测试过,这次使用的是 ATI/AMD Radeon 4670,它在笔记本电脑中相当高端(现在它相当中端?)并且影子工作正常,但还有一个问题在切换绘图时也到达了深度图(但我想它可以很容易地修复......)。我认为使用一个 API 可以解决此类平台问题,但我想不会。 :// 【参考方案1】:

我在别处得到了答案。供将来参考 - 采样深度图使用红色通道(或 .x 值),如 sample.r (/sample.x),而不是像我一样的 .b (/.z)。

【讨论】:

快速问,你是如何选择与 Optimus 一起使用的 GPU 的?就我而言,如果我选择 nvidia,它仍然使用 intel 并严重崩溃。谢谢! @LennartRolland 我通过在 exe 文件上单击鼠标右键并从那里的菜单中选择 GPU 来选择它。它必须在 nVidia 控制面板中启用(我认为默认情况下)。

以上是关于OpenGL 3.3 两个 GPU 上的两个不同结果 nVidia Optimus 与阴影映射的主要内容,如果未能解决你的问题,请参考以下文章