2017-10-24 3 views
2

안드로이드 Native OpenGL C++ 응용 프로그램에서 방향 지시등을 사용하여 그림자 맵을 구현했지만 그림자가 올바르게 렌더링되었지만 첨부 된 이미지와 같이 결과가 나타나는 버그가 있습니다 :OpenGL 그림자 맵이 객체 위에 그림자가 있습니다.

모델을 통해 이상한 삼각 그림자가 같이

enter image description here

, 다음과 같은 구현 :

:

먼저 깊이 버퍼 및 다음과 같은 깊이 맵을 생성

glTexImage2D의 내부 형식이 GL_Float에서 작동하지 않으므로 GL_UNSIGNED_SHORT를 사용했습니다.

나는 라이트 뷰에서 장면을 렌더링한다. 먼저 라이트 벡터는 (50,100,50)이고 나는 직접적인 빛의 방향에 대해 충돌이있다. 그것은 빛이나 빛으로부터의 방향이지만 그 값은 그림자를 만든다. 장면은 다른 조명 구성 요소로 잘 렌더링됩니다. 코드는 다음과 같습니다

if (sun->castShadow) { 
     double delta = GetCurrentTime() - firstFrame; 
     glBindFramebuffer(GL_FRAMEBUFFER, depthMapFBO); 
     glViewport(0, 0, SHADOW_WIDTH, SHADOW_HEIGHT); 
     glClear(GL_DEPTH_BUFFER_BIT); 
     glm::vec3 pos = player->getPosition(); 
     glm::vec3 tar = pos + (-sun->direction); 
     glm::mat4 lightSpaceProjection = glm::ortho(-10.0f, 10.0f, -10.0f, 10.0f, -20.0f, 500.0f); 
     glm::mat4 lightSpaceView = glm::lookAt(pos, tar, glm::vec3(0, 1, 0)); 
     lightSpaceMatrix = lightSpaceProjection * lightSpaceView; 
     shaders.setDepthLightSpaceUniform(lightSpaceMatrix); 
     terrain->renderDepth(delta); 
     for (item_it it = engineItems.begin(); it != engineItems.end(); ++it) { 
      if (it->get()->castShadow) 
       it->get()->renderDepth(delta); 
     } 
     glBindFramebuffer(GL_FRAMEBUFFER, 0); 
    } 

마침내 일반적으로 장면을 렌더링 :

shaders.setLightsUniforms(directlights, pointlights, spotlights); 
shaders.setViewUniforms(camera); 
double first = GetCurrentTime() - firstFrame; 
terrain->render(first); 
for (item_it it = engineItems.begin(); it != engineItems.end(); ++it) { 
    it->get()->render(first); 
} 

직접 조명 계산의 조각 쉐이더 부분은 다음과 같습니다 다른 버그가

vec3 calcDirectLight(DirectLight light,vec3 norm,vec3 tLightPos,vec3 diffColor,vec3 specColor){ 
    vec3 lightDir ; 
    if(Has_normal_map==1) 
     lightDir= normalize(tLightPos-tFragPos); 
    else 
     lightDir = normalize(light.direction - tFragPos); 

    float diff = max(dot(lightDir,norm), 0.0); 
    vec3 diffuse = light.color * diff * diffColor; 

    vec3 viewDir = normalize(tViewPos - tFragPos);  
    vec3 halfwayDir = normalize(lightDir + viewDir); 
    float spec = pow(max(dot(norm, halfwayDir), 0.0), 32.0); 
    vec3 specular = shininess * spec *specColor* light.color; 
    vec3 result; 
    if(light.castShadow==1){ 
     vec3 projCoords = FragPosLightSpace.xyz/FragPosLightSpace.w; 
     projCoords = projCoords * 0.5 + 0.5; 
     float shadow = 1.0; 
     for (int i=0;i<4;i++){ 
      shadow -= 0.2*(1.0-texture(shadowMap, projCoords.xy + poissonDisk[i]/700.0).r); 
     } 
     if(projCoords.z > 1.0) 
      shadow = 0.0; 
     result =light.intensity* shadow * (diffuse + specular); 
    } 
    else 
     result =light.intensity* (diffuse + specular); 
    return result; 
} 

하지만,이 주요 하나입니다

답변

3

나는 여기에 문제가 있다고 생각합니다 :

if(Has_normal_map==1) 
    lightDir= normalize(tLightPos-tFragPos); 
else 
    lightDir = normalize(light.direction - tFragPos); 

나는 방향성 등을 사용하고 있습니다. 방향성 빛의 방향을 계산하기 위해 는 간단하다 : 또한

lightDir = light.direction 

, 당신이 있는지 여부 Has_normal_map 여부에 따라 빛의 방향을 계산하는 개의 다른 공식을 사용하는 이유는 understant하지 않습니다. 나는 빛의 방향이 법선 맵에 의존하지 않는다고 믿는다. 나는 당신의 버그를 해결하기를 바랍니다.

+0

감사합니다. –

관련 문제