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는 조명 영역과 완전히 어둡습니다 (적어도 스포트 라이트, 방향성 등은 작동하지 않음)를 감지하지 못합니다.
갤러리 :
중요 - 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이 더 강력합니다. 이것은 매우 이상합니다. 비록 내가 그 어떤 고 폴리, 아주 많은 저 폴리 폴리을 그리지 않기 때문에 나는 생각한다. 나 맞아?
이번에는 다른 노트북에서 테스트 해 보았습니다. 이번에는 ATI/AMD Radeon 4670을 노트북에서 테스트 해 보았습니다. (현재는 Mid-end입니까?) 그리고 그림자는 괜찮 았지만 괜찮습니다. 깊이 -지도 (하지만 그것은 꽤 easly 고정 수 있습니다 ...). 하나의 API를 사용하면 플랫폼과 관련된 문제를 해결할 수 있다고 생각했지만, 그렇지 않습니다. :/ – RippeR