2013-07-18 2 views
3

C++에서 프로젝트를 배우고 (나중에 게임을 만들고 생성하기 위해) 작업하고 있으며 렌더링을 위해 OpenGL 3.3을 선택했습니다. 인텔 HD 4000이 내 프로세서에 내장되어 있기 때문에 기본 새 응용 프로그램을 열었습니다. 그런데 제 2 GPU에서 열려고 시도했습니다. nVidia GTX660m은 훨씬 더 빠른 속도이며, 더 많은 FPS를 기대했습니다. 하지만 수십 개의 버그가 있었을뿐만 아니라 (예를 들어, 조각 쉐이더에서 vec3을 컬러로 썼다면 Intel도 괜찮 았지만, vec4를 껐다면 nVidia는 완전히 미쳐 버렸습니다 ...). 물론 컴파일시 오류가 없으므로 수정하기가 극도로 어렵습니다.OpenGL 3.3 두 개의 GPU에서 두 가지 결과 섀도 매핑을 사용하는 nVidia Optimus

하지만 이제는 대부분을 고쳐봤을 때, 제가 고칠 수없는 한 가지 문제로 어려움을 겪었습니다 (일부는있을 수 있습니다. 더러운 방법 그러나 ... 요점이 아니다). 짧은 방법으로

: 내가 모두 GPU 유효 깊이지도 생성하지만, 엔비디아 GPU에 해당하지 그레이 스케일, 가시 빨간색 - 투 - 블랙 동일한 시스템에서 동일한 코드 때문에, 매우 이상한 어떤 규모 (거의) 동일한 (동일한 API!)를 실행해야합니다. 그 사실로 인해 내 프래그먼트 쉐이더는 따라 잡을 수 없으며, nVidia는 조명 영역과 완전히 어둡습니다 (적어도 스포트 라이트, 방향성 등은 작동하지 않음)를 감지하지 못합니다.

갤러리 : 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)

중요 - GTX660m에주의 깊이지도 redToBlack 스케일, 인텔 GPU에 같이하지 그레이 스케일이다. 상단 빛은 방향성 빛에서 나온 것이고 하단 하나는 점 광원에서 나온 것입니다.

내 FragmentShader : #Version을

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

첫 번째 부분은 방향성 광원입니다 (330)의 핵심 - 모두가 동일 할 경우 5 점의 전 사전 샘플의 깊이지도는, 내가 더 샘플 해달라고 (초기 모르나요 - 많은 성능 최적화 !), 또는 일부가 다른 경우, 나는 모두 샘플을 만들고 현재 조각의 그림자 강도를 계산합니다.

두 번째 부분은 단순히 포인트 라이트 깊이 맵의 샘플입니다. 그런 다음 광선의 중심으로부터 거리를 확인하여 플래시 라이트 효과를 시뮬레이트합니다 (가운데가 강함).

나는 더 이상 필요한 것은 없다고 생각하지만 그렇지 않다면 필자에게 필 요한 코드를 게시 할 것입니다.

또한 섀도우 맵이 16 비트 정밀도 (GL_DEPTH_COMPONENT16) 인 Intel HD4000이 더 빠르며 GTX660m이 더 강력합니다. 이것은 매우 이상합니다. 비록 내가 그 어떤 고 폴리, 아주 많은 저 폴리 폴리을 그리지 않기 때문에 나는 생각한다. 나 맞아?

+0

이번에는 다른 노트북에서 테스트 해 보았습니다. 이번에는 ATI/AMD Radeon 4670을 노트북에서 테스트 해 보았습니다. (현재는 Mid-end입니까?) 그리고 그림자는 괜찮 았지만 괜찮습니다. 깊이 -지도 (하지만 그것은 꽤 easly 고정 수 있습니다 ...). 하나의 API를 사용하면 플랫폼과 관련된 문제를 해결할 수 있다고 생각했지만, 그렇지 않습니다. :/ – RippeR

답변

1

나는 다른 곳에서 답을 얻었습니다. 나중에 참조 용 샘플링 깊이 맵은 sample.r (/ sample.x)과 같이 .b (/ .z)와 같은 빨간색 채널 (또는 .x 값)을 사용합니다.

+0

Quick Q, 옵티머스에서 사용할 GPU를 어떻게 선택 했습니까? 제 경우 엔, nvidia를 선택하면 여전히 인텔을 사용하고 끔찍하게 충돌합니다. 감사! –

+0

@LennartRolland exe 파일을 마우스 오른쪽 버튼으로 클릭하고 메뉴에서 GPU를 선택하여 선택했습니다. 그것은 nVidia 제어판에서 활성화되어야합니다 (기본적으로 생각합니다). – RippeR

관련 문제