Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/opengl/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ OpenGL阴影映射几乎可以正常工作_C++_Opengl_Glsl - Fatal编程技术网

C++ OpenGL阴影映射几乎可以正常工作

C++ OpenGL阴影映射几乎可以正常工作,c++,opengl,glsl,C++,Opengl,Glsl,我正在尝试根据教程将实时阴影贴图添加到我的类似Minecraft的克隆中: 首先发生了什么: 据我所知,阴影贴图渲染正确吗?问题似乎出在最后关卡 我创建深度纹理: glGenFramebuffers(1, &m_frameBufferId); glBindFramebuffer(GL_FRAMEBUFFER, m_frameBufferId); glGenTextures(1, &m_depthTexture); glBindTexture(GL_TEXTURE_2D, m_

我正在尝试根据教程将实时阴影贴图添加到我的类似Minecraft的克隆中:

首先发生了什么:

据我所知,阴影贴图渲染正确吗?问题似乎出在最后关卡

我创建深度纹理:

glGenFramebuffers(1, &m_frameBufferId);
glBindFramebuffer(GL_FRAMEBUFFER, m_frameBufferId);
glGenTextures(1, &m_depthTexture);
glBindTexture(GL_TEXTURE_2D, m_depthTexture);
glTexImage2D(GL_TEXTURE_2D, 0,GL_DEPTH_COMPONENT16, 1024, 1024, 0,GL_DEPTH_COMPONENT, GL_FLOAT, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE);

glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, m_depthTexture, 0);
glDrawBuffer(GL_NONE);
注意:我还尝试在着色器中使用GL_COMPARE_R_TO_纹理和sampler2DShadow。同样的结果

然后运行两个过程:

// ====================    Shadow    =====================
glBindFramebuffer(GL_FRAMEBUFFER, m_frameBufferId);
glViewport(0, 0, 1024, 1024);

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

ShadowShader->Bind();
VCSceneGraph::Instance->RenderGraph();


// ====================    Final    =======================
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glViewport(0, 0, 1280, 800);

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

VoxelShader->Bind();
VCSceneGraph::Instance->RenderGraph();
阴影着色器代码:

// ====================    Vert    =====================
#version 330 core\n

in vec4 vertexPosition_modelspace;
uniform mat4 depthMVP;

void main()
{
    gl_Position =  depthMVP * vertexPosition_modelspace;
}

// ====================    Frag    =====================
#version 330 core\n

out float fragmentdepth;

void main()
{
    fragmentdepth = gl_FragCoord.z;
}
// ====================    Vert    =====================
#version 330 core\n

in vec3 position;
in int normal;
in vec4 color;

out vec4 colorVarying;
out vec4 ShadowCoord;

uniform mat4 modelViewProjectionMatrix;
uniform mat4 DepthBiasMVP;

void main()
{
    gl_Position =  modelViewProjectionMatrix * vec4(position, 1);
    ShadowCoord = DepthBiasMVP * vec4(position, 1);
    colorVarying = color;
}

// ====================    Frag    =====================
#version 330 core\n

in vec4 colorVarying;
in vec4 ShadowCoord;

out vec4 color;

uniform sampler2D  shadowMap;

void main()
{
    float visibility = 1.0;

    if ( texture(shadowMap, ShadowCoord.xy).z  <  ShadowCoord.z)
    {
        visibility = 0.5;
    }

    color.xyz = colorVarying.xyz * visibility;
    color.w = colorVarying.w;
}
最终过程(体素着色器)代码:

//=====================================Vert=====================
#版本330核心\n
在vec3位置;
在int-normal中;
vec4色;
输出vec4颜色变化;
外4号暗影合作社;
均匀mat4模型视图投影矩阵;
均匀mat4深度偏差mVP;
void main()
{
gl_位置=modelViewProjectionMatrix*vec4(位置,1);
阴影坐标=深度偏差VP*vec4(位置,1);
颜色变化=颜色;
}
//========================================Frag=====================
#版本330核心\n
在vec4中,颜色变化;
在vec4阴影坐标中;
输出vec4颜色;
均匀采样二维阴影图;
void main()
{
浮动能见度=1.0;
if(纹理(阴影贴图,ShadowCoord.xy).z
我怀疑我的问题在于更新最后通行证制服的代码:

// Re-create the exact same MVP matrix that was used for the shadow pass
glm::mat4 depthProjectionMatrix = glm::ortho<float>( -30, 30, -30, 30, -100, 100);
glm::mat4 depthViewMatrix = glm::lookAt(glm::vec3(0.5f, 2, 2), glm::vec3(0,0,0), glm::vec3(0,1,0));
depthViewMatrix = glm::translate(depthViewMatrix, -15.0f, 30.0f, 0.0f);
glm::mat4 depthMVP = depthProjectionMatrix * depthViewMatrix;// * modelMatrix;

// Multiply it be the bias matrix
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
);

glm::mat4 depthBiasMVP = biasMatrix * depthMVP;

// Create Camera's MVP
VCCamera* currentCamera = VCSceneGraph::Instance->CurrentRenderingCamera;
glm::mat4 ProjectionMatrix = currentCamera->ProjectionMatrix;
glm::mat4 ViewMatrix = currentCamera->ViewMatrix;
glm::mat4 MVP = ProjectionMatrix * ViewMatrix;// * modelMatrix;

// Update uniforms
glUniformMatrix4fv(m_unifMVP, 1, GL_FALSE, &MVP[0][0]);
glUniformMatrix4fv(m_unifDepthMVP, 1, GL_FALSE, &depthBiasMVP[0][0]);
//重新创建与阴影过程使用的MVP矩阵完全相同的MVP矩阵
glm::mat4 depthProjectionMatrix=glm::ortho(-30,30,-30,30,-100,100);
glm::mat4 depthViewMatrix=glm::lookAt(glm::vec3(0.5f,2,2),glm::vec3(0,0,0),glm::vec3(0,1,0));
depthViewMatrix=glm::translate(depthViewMatrix,-15.0f,30.0f,0.0f);
glm::mat4 depthMVP=depthProjectionMatrix*depthViewMatrix;//*模型矩阵;
//将其乘以偏差矩阵
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
);
glm::mat4 depthBiasMVP=biasMatrix*depthMVP;
//创建相机的MVP
VCCamera*currentCamera=VCSceneGraph::Instance->CurrentRenderingCamera;
glm::mat4 ProjectionMatrix=currentCamera->ProjectionMatrix;
glm::mat4 ViewMatrix=currentCamera->ViewMatrix;
glm::mat4 MVP=ProjectionMatrix*ViewMatrix;//*模型矩阵;
//更新制服
glUniformMatrix4fv(m_unifMVP,1,GL_FALSE,&MVP[0][0]);
glUniformMatrix4fv(m_unidepthmvp,1,GL_FALSE和depthmiasmvp[0][0]);
编辑:

我修复了这个问题,使阴影纹理的分辨率与窗口相同。然而,我无法解释为什么这会修复它。如果有人想尝试一下,我会接受你的回答。预期输出如下:


我还应该注意到,完整的源代码可以在以下位置获得:。

我比较了你和我的阴影,我建议你使用
sampler2DShadow
而不是
sampler2D
。此采样器仅用于阴影,并且有一些用于阴影投影的函数(shadow2DProj等)。你可以这样使用它

in vec4 colorVarying;
varying vec4 ShadowCoord;

out vec4 color;

uniform sampler2DShadow shadowMap;

float offset_lookup(sampler2DShadow map, vec4 loc, vec2 offset) {
    //Texture size (1024 x 1024)
    vec2 texmapscale = vec2(1.0/1024.0, 1.0/1024.0);
    //Set bias as you need (it corrects shadow acne)
    float bias = 0.001;
    vec4 result = shadow2DProj(map, vec4(loc.xy + offset * texmapscale * loc.w, loc.z, loc.w));
    if (loc.z > result.z + bias) {
        return 0.5;
    } else {
        return 1.0;
    }
}

void main() {
    float shadowFactor;
    shadowFactor = offset_lookup(shadowMap, ShadowCoord, vec2(0, 0));
    color = colorVarying * shadowFactor;
}
最后一个参数偏移量是多少?你可以做一些阴影模糊。 3x3阴影模糊:

//3x3 blur
    for (y = -1.5; y <= 1.5; y += 1.0)
        for (x = -1.5; x <= 1.5; x += 1.0)
            sum += offset_lookup(shadowMap, ShadowCoord, vec2(x, y));
    //I am no sure why 16 (insted of 9) but I use this and it works :D
    float shadeFactor = sum / 16.0;
/3x3模糊

对于(y=-1.5;y谢谢你的帮助。我在乘以深度biasmVP后将ShadowCoord.xyz=ShadowCoord.xyz/ShadowCoord.w;添加到我的顶点着色器中,但没有效果。你希望得到什么结果?另外,你能在一些3D建模软件中提供场景、相机和光源位置/方向的屏幕截图,这样我就可以了想象一下什么结果应该被认为是“正确的”?从我在阴影贴图上看到的-不应该有任何阴影,因为你的对象几乎没有阴影投射-可能它甚至是凸的,在这个视图上很难看到。如果你将第二个视口设置为1024 x 1024,会发生什么?有趣的是,什么都不会发生。事实上,我设置的第二个V查看端口到似乎不相关。场景仍像以前一样渲染。奇怪…嗯,你能在曲面上应用照明或在其上渲染线框吗?并指示照明位置?根据当前的屏幕截图,很难确定几何体是什么样子。