定向光影映射错误 - opengl

时间:2015-10-27 19:44:05

标签: opengl glsl shadow

我需要在opengl 3.3和GLSL中使用阴影贴图(定向光)。问题是在de 3d模型和基元上没有正确显示阴影:

这是生成着色器源阴影矩阵的代码:

void shadow::calculateShadowMatrixFromLightPointOfView(vector3f lightPosition, vector3f lightDirection)
{
//this method, only bind the frame buffer:
//glBindFramebuffer(GL_FRAMEBUFFER, uiFramebuffer);
fboShadowMap.bindFramebuffer();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);


//this method only bind the shader
m_shader.bindShader();

float rangeX = globalData::windowWidth;
float rangeY = globalData::windowHeight;

m_ProjectionMatrix =  glm::ortho<float>(-rangeX,rangeX,-rangeY,rangeY, 0.05f,400.0);

m_currentLigthPosition = glm::lookAt(
glm::vec3(lightPosition.x,lightPosition.y,lightPosition.z),
glm::vec3(
lightDirection.x,
lightDirection.y,
lightDirection.z
),
glm::vec3(0,1,0)
);

glm::mat4 biasMatrix(
0.5, 0.0, 0.0, 0.0,
0.0, 0.5, 0.0, 0.0,
0.0, 0.0, 0.5, 0.0,
0.5, 0.5, 0.5, 1.0
);


mDepthBiasMVP = biasMatrix * m_ProjectionMatrix * m_currentLigthPosition;


}

这会创建帧缓冲区:

bool frameBuffer::createFrameBufferWithTexture(int a_iWidth, int a_iHeight )
{
if(uiFramebuffer != 0)return false;

glGenFramebuffers(1, &uiFramebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, uiFramebuffer);

tFramebufferTex.createEmptyTexture(a_iWidth, a_iHeight, GL_RGB);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);

glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tFramebufferTex.getTextureID(), 0);

iWidth = a_iWidth;
iHeight = a_iHeight;

return glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE;

}

a_iWidth和a_iHeight整数是1024。

这会创建纹理:

unsigned int CTexture::createTexture(int w,int h,bool isDepth)
{
glGenTextures(1,&uiTexture);
glBindTexture(GL_TEXTURE_2D,uiTexture);
glTexImage2D(GL_TEXTURE_2D,0,(!isDepth ? GL_RGBA8 : GL_DEPTH_COMPONENT),w,h,0,(isDepth ? GL_DEPTH_COMPONENT : GL_RGBA),GL_FLOAT,NULL);

glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);

int i;
i=glGetError();
if(i!=0)
{
cout << "Error happened while loading the texture: " << i << "\n";
}
glGenSamplers(1, &uiSampler);
return uiTexture;
}

isDepth变量,当我使用此函数构造de framebuffer时为true。

然后在我用于阴影的着色器中:

VERTEX SHADER:

#version 330 core                                                    

// Input vertex data, different for all executions of this shader.   
layout(location = 0) in vec3 inPosition;                             

// Values that stay constant for the whole mesh.                     
uniform mat4 depthMVP;                                               

void main(){                                                         
gl_Position = depthMVP*vec4(inPosition.xyz,1.0f);                
}       

FRAGMENT SHADER:

#version 330 core                                                   

// Output data                                                      
layout(location = 0) out float fragmentdepth;                       

void main(){                                                        
fragmentdepth = gl_FragCoord.z;                                 
}                                                                   

最后,为了在&#34; world&#34;中渲染阴影,我使用了这个着色器:

VERTEX SHADER:

#version 330                                                                

uniform mat4 projectionMatrix;                                              
uniform mat4 modelViewMatrix;                                               
uniform mat4 normalMatrix;                                                  
uniform mat4 modelMatrix;                                                   


uniform mat4 DepthBiasMVP;                                              
smooth out vec4 ShadowCoord;                                            


layout (location = 0) in vec3 inPosition;                                   
layout (location = 1) in vec2 inCoord;                                      
layout (location = 2) in vec3 inNormal;                                     

smooth out vec2 texCoord;                                                   
smooth out vec3 vNormal;                                                    
smooth out vec3 vEyeSpacePos;                                               
smooth out vec3 vWorldPos;                                                  

uniform float objOpacity;                                                   
smooth out float fObjOpacity;                                                                           
uniform vec3 objColor;                                                      
smooth out vec3 vObjColor;                                                  


void main()                                                                 
{                                                                           
vec4 vEyeSpacePosVertex = modelViewMatrix*vec4(inPosition, 1.0);        
gl_Position = projectionMatrix*vEyeSpacePosVertex;                      
texCoord = inCoord;                                                     
vec4 vRes = normalMatrix*vec4(inNormal, 0.0);                           
vNormal = vRes.xyz;                                                     
vEyeSpacePos = vEyeSpacePosVertex.xyz;                                  
vec4 vWorldPosVertex = modelMatrix*vec4(inPosition, 1.0);               
vWorldPos = vWorldPosVertex.xyz;                                        

ShadowCoord = DepthBiasMVP * vWorldPosVertex;                           


fObjOpacity = objOpacity;                                                   
vObjColor = objColor;                                                       

}   

FRAGMENT SHADER

#version 330                                                                

smooth in vec2 texCoord;                                                    
smooth in vec3 vNormal;                                                     
smooth in vec3 vEyeSpacePos;                                                
smooth in vec3 vWorldPos;                                                   

smooth in vec3 vObjColor;                                                   
smooth in float fObjOpacity;                                                
struct material 
{ 
float specularIntensity; 
float specularPower; 
}; 
uniform material m_material;                                                    

out vec4 outputColor;                                                       


uniform sampler2D gSampler;                                                 
vec4 totalLight = vec4(0.0,0.0,0.0,0.0);                                    
float visibility = 1.0f;                                                    


struct DirectionalLight                                                             
{                                                                                   
vec3 vColor;                                                                        
vec3 vPosition;                                                                     
vec3 vDirection;                                                                    
float fAmbientIntensity;                                                            
float fStrength;                                                                    
};                                                                                  


vec4 getDirectionalLightColor(DirectionalLight dirLight, vec3 vNormal)              
{                                                                                   
float fDiffuseIntensity = max(0.0, dot(normalize(vNormal), -dirLight.vDirection));  
return vec4(dirLight.vColor*(dirLight.fAmbientIntensity+fDiffuseIntensity)*dirLight.fStrength, 1.0);     
}

uniform DirectionalLight sunLight;  

uniform sampler2D shadowMap;                                                 
smooth in vec4 ShadowCoord;                                                  
vec2 poissonDisk[16] = vec2[]( 
vec2( -0.94201624, -0.39906216 ), 
vec2( 0.94558609, -0.76890725 ), 
vec2( -0.094184101, -0.92938870 ), 
vec2( 0.34495938, 0.29387760 ), 
vec2( -0.91588581, 0.45771432 ), 
vec2( -0.81544232, -0.87912464 ), 
vec2( -0.38277543, 0.27676845 ), 
vec2( 0.97484398, 0.75648379 ), 
vec2( 0.44323325, -0.97511554 ), 
vec2( 0.53742981, -0.47373420 ), 
vec2( -0.26496911, -0.41893023 ), 
vec2( 0.79197514, 0.19090188 ), 
vec2( -0.24188840, 0.99706507 ), 
vec2( -0.81409955, 0.91437590 ), 
vec2( 0.19984126, 0.78641367 ), 
vec2( 0.14383161, -0.14100790 ) 
);


float getVisibility(sampler2D shadowMap, vec4 vShadowCoord)     
{                                                               
float visibility = 1.0;                                     
float bias = 0.005;                                         

if(vShadowCoord.w > 0.0)
{
vec3 ShadowMapTexCoordProj = vShadowCoord.xyz / vShadowCoord.w;

if(ShadowMapTexCoordProj.x >= 0.0 && ShadowMapTexCoordProj.x < 1.0 &&
ShadowMapTexCoordProj.y >= 0.0 && ShadowMapTexCoordProj.y < 1.0 &&
ShadowMapTexCoordProj.z >= 0.0 && ShadowMapTexCoordProj.z < 1.0)
{                                                           
for (int i=0;i<4;i++)                                       
{                                                           
int index = i;
vec4 vShadowSmooth = vec4(ShadowMapTexCoordProj.x + poissonDisk[index].x/800.0, ShadowMapTexCoordProj.y + poissonDisk[index].y/600.0, (ShadowMapTexCoordProj.z-bias)/1.0, 1.0);
float fSub = texture(shadowMap, vShadowSmooth.st).r; 
visibility -= 0.1*(1.0-fSub);
}  
}
}    


return visibility;
}   

void main()                                                                 
{                                                                           
vec3 vNormalized = normalize(vNormal);                                  

totalLight += getDirectionalLightColor(sunLight, vNormal);                      


visibility =  getVisibility(shadowMap, ShadowCoord);         

vec4 vTexColor = texture2D(gSampler, texCoord);                         
vTexColor.a = fObjOpacity;                                              
vec4 vMixedColor = vTexColor*vec4(vObjColor,1.0);                       
outputColor = vec4(vMixedColor*totalLight*visibility);                  

}

当我看到场景时,我得到了这样的结果:

https://www.youtube.com/watch?v=6uS-f7qhWMI&feature=youtu.be

正如您在视频中看到的那样,对象不会以正确的方式影响阴影。所有物体都是黑暗的。

这是渲染场景的顺序:

glViewport(0, 0, 1024, 1024);

//this function are described above
m_shadows->calculateShadowMatrixFromLightPointOfView(
dirLight->getPosition(),
dirLight->getDirection()
);

//render objects

glViewport(0, 0, globalData::windowWidth, globalData::windowHeight);

glBindFramebuffer(GL_FRAMEBUFFER, 0);

//render objects

我不知道出了什么问题,我阅读了很多教程,但结果总是错误的。

谢谢你的帮助。

1 个答案:

答案 0 :(得分:-1)

我在de shadow函数的片段着色器中找到了解决方案:

if(fSub<vShadowSmooth.z){
          visibility -= 0.1*(1.0-fSub);

          }