OpenGL,使用不带剪切值的浮点颜色渲染到纹理

4uqofj5v  于 2022-09-26  发布在  其他
关注(0)|答案(1)|浏览(188)

我真的不知道我正在尝试做的事情的英文名字是什么,如果你知道的话,请告诉我。

以便运行一些基于物理的照明计算。我需要使用一个OpenGL着色器将浮点数据写入纹理,然后在另一个OpenGL着色器中再次读取该数据,但我想存储的数据可能小于0或大于1。

为此,我设置了渲染缓冲区以渲染到此纹理,如下所示(这是C++):

//Set up the light map we will use for lighting calculation
glGenFramebuffers(1, &light_Framebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, light_Framebuffer);
glBlendFunc(GL_SRC_ALPHA, GL_DST_ALPHA);//Needed for light blending (true additive)

glGenTextures(1, &light_texture);
glBindTexture(GL_TEXTURE_2D, light_texture);
//Initialize empty, and at the size of the internal screen
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_FLOAT, 0);

//No interpolation, I want pixelation
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

//Now the light framebuffer renders to the texture we will use to calculate dynamic lighting
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, light_texture, 0);
GLenum DrawBuffers[1] = { GL_COLOR_ATTACHMENT0 };
glDrawBuffers(1, DrawBuffers);//Color attachment 0 as before

请注意,我使用的是类型GL_FLOAT,而不是GL_UNSIGNED_BYTE,根据this的讨论,浮点类型的纹理不应该在0和1之间进行剪裁。

现在,为了测试这是否正确,我只需在创建此纹理的片段着色器中将颜色设置在此范围之外的某个位置:


# version 400 core

void main()
{
    gl_FragColor =  vec4(2.0,-2.0,2.0,2.0);
}

渲染到该纹理后,我将该纹理发送给程序,该程序应像使用任何其他纹理一样使用该纹理:

glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, light_texture );//This is the texture I rendered too
glUniform1i(surf_lightTex_ID , 1);//This is the ID in the main display program

同样,为了检查这是否起作用,我将片段着色器替换为测试颜色是否已保存的着色器。


# version 400 core

uniform sampler2D lightSampler;

void main()
{
    color = vec4(0,0,0,1);
    if (texture(lightSampler,fragment_pos_uv).r>1.0)
        color.r=1;
    if (texture(lightSampler,fragment_pos_uv).g<0.0)
        color.g=1;
}

如果一切正常,一切都应该变成黄色,但不用说,这只会给我一个黑屏。因此,我尝试了以下方法:


# version 400 core

uniform sampler2D lightSampler;

void main()
{
    color = vec4(0,0,0,1);
    if (texture(lightSampler,fragment_pos_uv).r==1.0)
        color.r=1;
    if (texture(lightSampler,fragment_pos_uv).g==0.0)
        color.g=1;
}

然后我就得到了

绿色的部分在测试场景中处于阴影中,不要管它们;要点是light_texture的所有通道都被修剪到0到1之间,这是它们不应该做的。我不确定数据是否被正确保存并且仅在读取时被剪裁,或者数据在保存时是否被剪裁为0到1。

所以,我的问题是,有没有某种方法可以读取和写入OpenGL纹理,以便存储的数据可以大于1或小于0。

此外,通过在每个通道使用32位整数,并在保存之前应用Sigmoid函数并在读取数据后应用Sigmoid函数的反转,No无法修复该问题,这将破坏Alpha混合。

2j4z5cfb

2j4z5cfb1#

  • typeFormat*参数glTexImage2D仅指定源图像数据的格式,但不影响纹理的内部格式。您必须使用特定的内部格式。例如:GL_RGBA32F
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);

相关问题