【发布时间】:2016-12-12 15:56:30
【问题描述】:
我尝试实现延迟着色,但 gbuffer 无法存储任何浮点数。来自照明的边缘非常粗糙,因为即使我传入了正确的内部格式和数据类型,帧缓冲区也无法存储法线的负分量。
Example picture of the rough edges
纹理生成:
public TextureResource(int width, int height, int filter, int internalFormat, int format, boolean clamp, int dataType, ByteBuffer data) {
id = glGenTextures();
glBindTexture(GL_TEXTURE_2D, id);
glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, width, height, 0, format, dataType, data);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);
if(clamp) {
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_BASE_LEVEL, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
glBindTexture(GL_TEXTURE_2D, 0);
}
帧缓冲生成:
this.width = width;
this.height = height;
this.attachments = attachments;
boolean hasDepth = false;
IntBuffer drawBuffers = Util.createIntBuffer(attachments.length);
assert(attachments.length <= MAX_ATTACHMENTS);
framebuffer = glGenFramebuffers();
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
for(int i = 0; i < attachments.length; i++) {
if(attachments[i].getAttachmentType() == GL_DEPTH_ATTACHMENT) {
drawBuffers.put(GL_NONE);
hasDepth = true;
} else {
drawBuffers.put(attachments[i].getAttachmentType());
}
if(attachments[i].getAttachmentType() == GL_NONE) {
continue;
}
attachments[i].createTexture(width, height);
glFramebufferTexture2D(GL_FRAMEBUFFER, attachments[i].getAttachmentType(), GL_TEXTURE_2D, attachments[i].getTexture().getId(), 0);
}
if(!hasDepth) {
renderbuffer = glGenRenderbuffers();
glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, width, height);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, renderbuffer);
}
drawBuffers.flip();
glDrawBuffers(drawBuffers);
if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
System.err.println("Framebuffer creation failed!");
System.exit(1);
}
GBuffer:
super(width, height, new FramebufferAttachment(GL_COLOR_ATTACHMENT1, GL_NEAREST, GL_RGB32F, GL_RGB, false, GL_FLOAT),
new FramebufferAttachment(GL_COLOR_ATTACHMENT0, GL_NEAREST, GL_RGB32F, GL_RGB, false, GL_FLOAT),
new FramebufferAttachment(GL_COLOR_ATTACHMENT2, GL_NEAREST, GL_RGB, GL_RGB, false, GL_UNSIGNED_BYTE));
几何通道片段着色器:
#version 330 core
in vec3 worldPos0;
in vec2 texCoord0;
in vec3 normal0;
layout (location = 0) out vec3 gWorldPos;
layout (location = 1) out vec3 gNormal;
layout (location = 2) out vec3 gColor;
uniform sampler2D diffuse;
void main() {
gWorldPos = worldPos0;
gNormal = normalize(normal0);
gColor = texture(diffuse, texCoord0).xyz;
}
【问题讨论】: