我从 OpenGL 开始,我想创建一个色调映射 - 算法。
我知道我的第一步是获取 HDR 图像的最大/最小亮度值。
我在 FBO 的纹理中有图像,但我不知道如何开始。
我认为最好的方法是将tex坐标传递给片段着色器,然后遍历所有像素并生成更小的纹理。
但是,在我拥有 1x1 纹理之前,我不知道如何手动进行下采样;我应该有很多FBO吗?我在哪里创建每个新纹理?
我搜索了很多信息,但我仍然没有清楚的几乎任何东西。
我会很感激一些帮助来定位自己并开始。
编辑 1. 这是我的着色器,以及我如何将纹理坐标传递给顶点着色器:
为了传递纹理坐标和顶点位置,我使用 VBO 绘制了一个四边形:
void drawQuad(Shaders* shad){
// coords: vertex (3) + texture (2)
std::vector<GLfloat> quadVerts = {
-1, 1, 0, 0, 0,
-1, -1, 0, 0, 1,
1, 1, 0, 1, 0,
1, -1, 0, 1, 1};
GLuint quadVbo;
glGenBuffers(1, &quadVbo);
glBindBuffer(GL_ARRAY_BUFFER, quadVbo);
glBufferData(GL_ARRAY_BUFFER, 4 * 5 * sizeof(GLfloat), &quadVerts[0], GL_STATIC_DRAW);
// Shader attributes
GLuint vVertex = shad->getLocation("vVertex");
GLuint vUV = shad->getLocation("vUV");
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 3 * sizeof(GLfloat), NULL);
// Set attribs
glEnableVertexAttribArray(vVertex);
glVertexAttribPointer(vVertex, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 5, 0);
glEnableVertexAttribArray(vUV);
glVertexAttribPointer(vUV, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 5, (void*)(3 * sizeof(GLfloat)));
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); // Draw
glBindBuffer(GL_ARRAY_BUFFER, 0);
glDisableVertexAttribArray(vVertex);
glDisableVertexAttribArray(vUV);
}
顶点着色器:
#version 420
in vec2 vUV;
in vec4 vVertex;
smooth out vec2 vTexCoord;
uniform mat4 MVP;
void main()
{
vTexCoord = vec2(vUV.x * 1024,vUV.y * 512);
gl_Position = MVP * vVertex;
}
和片段着色器:
#version 420
smooth in vec2 vTexCoord;
layout(binding=0) uniform sampler2D texHDR; // Tex image unit binding
layout(location=0) out vec4 color; //Frag data output location
vec4[4] col;
void main(void)
{
for(int i=0;i<=1;++i){
for(int j=0;j<=1;++j){
col[(2*i+j)] = texelFetch(texHDR, ivec2(2*vTexCoord.x+i,2*vTexCoord.y+j),0);
}
}
color = (col[0]+col[1]+col[2]+col[3])/4;
}
在这个测试代码中,我有一个大小为 1024*512 的纹理。我的想法是使用此着色器和绑定在其中的具有图像 ( ) 的纹理来渲染附加到GL_ATTACHMENT_0
FBO ( ) 中的纹理。我的目标是让我的 FBO 纹理中的图像将其大小减少两倍。layout(location=0)
GL_TEXTURE_0
layout(binding=0)
texHDR