【问题标题】:Framebuffers can't store floating point numbers帧缓冲区不能存储浮点数
【发布时间】: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;
}

【问题讨论】:

    标签: java opengl lwjgl


    【解决方案1】:

    因为是3.3核心。 OpenGL 标准在可渲染格式的问题上有些自相矛盾,一些实现实际上支持 RGBxF 格式。 OpenGL 4.4 规范声明它们是可渲染的。

    如果真的需要,我认为可以将整数值映射到浮点数。 Ofc 你仍然有数量有限的值,但你可以实现负值和小数值,但范围有限

    【讨论】:

    • 将着色器版本切换到450,没有解决问题。
    • @stringflow 应该尝试gamedev.net/topic/… 或使用更通用的映射值解决方法。例如0..65535 会映射到什么? -1.0f ...1.0f ?短 int 值的 LSB 将等于 1/(2^17)(最低有效位值),增量为 -1.0f
    • 我已经尝试了每一种内部格式,但它不适用于任何一种。我真的只会使用官方的 opengl 功能,而不是围绕它编写一个 hack。此外,关于 HDR 或延迟着色之类的每个教程都建议使用浮点内部格式来绘制帧缓冲区,所以我真的没有看到围绕它编写 hack 的意义。这显然不是驱动程序问题,因为使用这种实现方法的其他程序运行得很好。
    • @stringflow 你只使用核心模式吗?据我了解,这是核心模式的问题,那里不支持那些格式。关于 hacks.. 否则,使用非 IEEE754 浮点格式的 stange GPU 不支持它。我看到大量生产代码(又名,真实的现有游戏或应用程序)使用各种数学“黑客”来为着色器提供更多数据,尤其是在渲染网格、动画或实例渲染时,只要它不使用一些转瞬即逝的平台取决于功能
    • @stringflow 例如Rasberry Pi 的 GPU 硬件不支持它,你只能绕过它或遵守它
    猜你喜欢
    • 1970-01-01
    • 2017-05-13
    • 1970-01-01
    • 1970-01-01
    • 2021-05-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多