OpenGL渲染到纹理会产生空纹理

时间:2018-05-20 17:27:03

标签: java opengl framebuffer render-to-texture shadow-mapping

我正在尝试渲染和orhto将我的场景深度值投影到纹理,以便在稍后的渲染圆圈中使用纹理来确定阴影中的片段。基本上是阴影贴图。

然而,我渲染的纹理最终都是空的。鉴于我只能在着色器中真正测试它,我只能限制生成的输出。但是,似乎纹理中的所有z值都是0.

以下是生成纹理的代码(宽度和高度为1024,pixelFormat为GL_DEPTH_COMPONENT):

this.id = glGenTextures();

glBindTexture(GL_TEXTURE_2D, id);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, width, height, 0, pixelFormat, GL_FLOAT, (ByteBuffer) null);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

return id;

这里我创建了FrameBuffer并附加了Texture:

// Create a FBO to render the depth
this.depthMapFBO = glGenFramebuffers();
// Create the depth map texture

this.depthMap = new Texture(SHADOW_MAP_WIDTH, SHADOW_MAP_HEIGHT, GL_DEPTH_COMPONENT);

// Attach the the depth map texture to the FBO
glBindFramebuffer(GL_FRAMEBUFFER, depthMapFBO);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, this.depthMap.getId(), 0);

// Set only depth
glDrawBuffer(GL_NONE);

if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
    throw new Exception("Could not create FrameBuffer" +glCheckFramebufferStatus(GL_FRAMEBUFFER));
}

// Unbind
glBindFramebuffer(GL_FRAMEBUFFER, 0);

在渲染场景之前,我调用此函数来渲染纹理的深度:

if(shaderMap.containsKey("shadow")){
    shaderprogram = shaderMap.get("shadow");
}
shaderprogram.bind();

Sun sun = resourceManager.getSun();

Matrix4f LightViewMatrix = transformation.getLightViewMatrix(sun);
Matrix4f modelLightViewMatrix = transformation.getModelViewMatrix(object, LightViewMatrix);
shaderprogram.setUniform("modelLightViewMatrix",modelLightViewMatrix);

glBindFramebuffer(GL_FRAMEBUFFER,this.shadowmap.getDepthMapFBO());
glViewport(0, 0, 1024, 1024);

glClear(GL_DEPTH_BUFFER_BIT);

glEnable(GL_TEXTURE_2D);

this.shadowmap.getDepthMapTexture().bind();

glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );

glBindVertexArray(object.getMesh().getVaoId());

glEnableVertexAttribArray(0);//Vertex positions
glEnableVertexAttribArray(1);//Color Positions
glEnableVertexAttribArray(2);//Normals

glDrawElements(GL_TRIANGLES, object.getMesh().getVertexcount(),GL_UNSIGNED_INT ,0);

glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
glDisableVertexAttribArray(2);

glBindVertexArray(0);
glBindTexture(GL_TEXTURE_2D,0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);

shaderprogram.unbind();

如果需要,我可以发布OrthogonalViewMatrix和LightViewMatrix的矩阵,但我测试了它们并用它们渲染我的场景,它给出了相机飞越地形并观察地图中心的预期效果。基本上你会想象如果相机是太阳那么场景就像。所以我不认为他们有任何问题。

这是我用正常投影进行的第二次渲染。基本上是正常的相机:

shaderprogram.createUniform("shadowMap");
glActiveTexture(GL_TEXTURE4);
this.shadowmap.getDepthMapTexture().bind();
shaderprogram.setUniform("shadowMap", 4);
glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );

glBindVertexArray(object.getMesh().getVaoId());

glEnableVertexAttribArray(0);//Vertex positions
glEnableVertexAttribArray(1);//Color Positions
glEnableVertexAttribArray(2);//Normals

glDrawElements(GL_TRIANGLES, object.getMesh().getVertexcount(),GL_UNSIGNED_INT ,0);

glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
glDisableVertexAttribArray(2);

glBindVertexArray(0);
glBindTexture(GL_TEXTURE_2D,0);
shaderprogram.unbind();

有些部分被遗漏了,但我认为这些是错误可能最重要的代码部分。

这是在阴影贴图的第一个渲染周期中使用的顶点和片段着色器:

#version 330

layout (location=0) in vec3 position;
layout (location=1) in vec2 texCoord;
layout (location=2) in vec3 vertexNormal;

uniform mat4 modelLightViewMatrix;
uniform mat4 orthoProjectionMatrix;

void main()
{
    gl_Position = orthoProjectionMatrix * modelLightViewMatrix * vec4(position, 1.0f);
}

我知道我没有使用texCoords和vertexNormal。 这里是片段着色器:

#version 330

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

它应该只保存Fragments Depth值。 这里是普通场景片段着色器的一部分:

float shadowfactor = 0;
vec3 projCoords = mlightviewVertexPos.xyz;
projCoords = projCoords * 0.5 + 0.5;

if (projCoords.z < texture(shadowMap,projCoords.xy).r){
    // Current fragment is not in shade
    shadowfactor = 1;
}else{
    shadowfactor = 0.5;
}

color = color * (vec4(1,1,1,1)* shadowfactor);

fragColor = color;

我输入orthoMatrix和LightViewMatrix来确定片段在太阳POV中的位置,并检查纹理部分的Z值。

问题在于,影子因子似乎是一种均匀的黑色纹理。我尝试将纹理(shadowMap,projCoords.xy).r直接分配给片段,以查看是否有任何差异,但它是完全相同的黑色,例如。 0

我还试图直接在地形上使用ShadowMap纹理来查看是否有任何东西,但我也只得到一个黑色纹理。

我知道这是一个很长的问题,但我在最近2天尝试调试它,但无法找到错误。我的猜测是我没有绑定纹理右边或者在渲染周期中使用了错误的FrameBuffer。

希望有人想帮忙,可以找到错误。

感谢您提前抽出时间, 亚历

0 个答案:

没有答案