我需要在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
我不知道出了什么问题,我阅读了很多教程,但结果总是错误的。
谢谢你的帮助。
答案 0 :(得分:-1)
我在de shadow函数的片段着色器中找到了解决方案:
if(fSub<vShadowSmooth.z){
visibility -= 0.1*(1.0-fSub);
}