OpenGL 3.3在两个GPU nVidia Optimus上使用阴影映射得到两个不同的结果 所以我正在做一个项目(在将来学习和创建一个游戏),在C++中,我选择了OpenGL 3.3。我一直在开发内置于处理器中的Intel HD 4000,因为它可以打开默认的新应用程序,一切都很顺利。但后来我试着在我的第二个GPU上打开它-nVidia GTX660,这是一个快得多的GPU,我期望它有更多的FPSE。但没有,不仅我有几十个bug(在示例中-如果我在片段着色器中使用vec3作为颜色,英特尔就可以了,但是如果我没有使用vec4,nVidia就完全疯狂了…)。当然,编译时没有任何错误,所以很难修复

OpenGL 3.3在两个GPU nVidia Optimus上使用阴影映射得到两个不同的结果 所以我正在做一个项目(在将来学习和创建一个游戏),在C++中,我选择了OpenGL 3.3。我一直在开发内置于处理器中的Intel HD 4000,因为它可以打开默认的新应用程序,一切都很顺利。但后来我试着在我的第二个GPU上打开它-nVidia GTX660,这是一个快得多的GPU,我期望它有更多的FPSE。但没有,不仅我有几十个bug(在示例中-如果我在片段着色器中使用vec3作为颜色,英特尔就可以了,但是如果我没有使用vec4,nVidia就完全疯狂了…)。当然,编译时没有任何错误,所以很难修复,opengl,nvidia,optimus,shadow-mapping,Opengl,Nvidia,Optimus,Shadow Mapping,但是现在,当我解决了大部分问题后,我遇到了一个我无法解决的问题(可能有一些肮脏的方法,但……这不是重点) 简而言之:我在两个GPU上都生成了有效的深度贴图,但在nVidia GPU上它不是灰度的,而是从红色到黑色的比例,这非常奇怪,因为同一台机器上的相同代码(几乎)应该运行相同的(同样的API!)。由于这一事实,我的碎片着色器可能没有赶上它,在nVidia上也没有检测到照亮的区域和完全黑暗的区域(至少在聚光灯下,平行光不起作用) 图片: 重要信息-请注意GTX660上的深度贴图是红黑比例,而不

但是现在,当我解决了大部分问题后,我遇到了一个我无法解决的问题(可能有一些肮脏的方法,但……这不是重点)

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

图片:

重要信息-请注意GTX660上的深度贴图是红黑比例,而不是英特尔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);
}
vec2uv中的
//标准纹理的坐标(模型)
在vec4阴影坐标中//平行光坐标(pos)
在vec4中,POVShadowCoord//聚光灯(手电筒)坐标(位置)
输出vec4颜色//输出颜色
均匀取样器2D MyTexture取样器//带有模型数据的标准纹理
均匀采样二维阴影图//平行光阴影图
均匀采样二维POVshadowMap//聚光灯(手电筒)的阴影贴图
void main(){
vec3 tex_data=texture2D(myTextureSampler,UV).rgb;
浮动偏差=0.005;
浮动能见度=0.7;
浮动减少=0.002;
int-early_-bailing=0;
if(纹理2d(阴影贴图,ShadowCoord.xy+vec2(0,0)/1850.0).z0){
for(int i=-2;i<2;i++){
对于(int j=-2;j<2;j++){
如果(i==0&&j==0)继续;
如果(i=-2&&j=-2)继续;
if(纹理2d(阴影贴图,阴影坐标xy+vec2(i,j)/850.0).z1 | | y<0 | | y>1){
能见度-=0.6;
}否则{
浮动最小能见度=能见度-0.6;
if(textureProj(POVshadowMap,POVShadowCoord.xyw).z<(POVShadowCoord.z-bias)/POVShadowCoord.w){
能见度=最低能见度;
}否则{
//手电筒效应
浮点数dx=0.5-x;
浮动dy=0.5-y;
能见度-=sqrt(dx*dx+dy*dy);
if(能见度<最小能见度)
能见度=最低能见度;
}
}
颜色=vec4(可见性*tex_数据,1);
}
第一部分是平行光-我在5个点中预先采样深度贴图,如果所有点都相同,我就不会再采样(早期bailing-很多性能优化!),或者如果一些点不同,我采样所有点并计算当前片段上阴影的强度

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

我不认为需要更多,但如果是,请写,我会张贴所需的代码


另外-对于阴影贴图,只有16位精度(GL_DEPTH_component 16),Intel HD4000比我的GTX660更快(在某种程度上更强大)-这非常奇怪。虽然我认为这是因为我没有画任何高多边形,只是画了很多非常低的多边形。我说的对吗?我在别处找到了答案。作为将来的参考-采样深度图使用红色通道(或.x值),如sample.r(/sample.x),而不是像我一样使用.b(/.z)。

我已经在另一台笔记本电脑上测试过它,这次使用的是ATI/AMD Radeon 4670,它在笔记本电脑中相当高端(现在相当中端?),shadow工作正常,虽然在切换绘制深度贴图时出现了另一个问题(但我想这很容易解决…)。我原以为使用一个API可以解决这样的平台问题,但我想没有/Quick Q,您是如何选择要与Optimus一起使用的GPU的?在我的例子中,如果我选择nvidia,它仍然使用intel,并且崩溃得很厉害。谢谢@LennartRolland我通过在exe文件上单击鼠标右键并从菜单中选择GPU来选择它。它必须在nVidia控制面板中启用(我认为是默认设置)。