在GLSL和C ++中使用来自2D PNG的3D查找表

问题描述 投票:0回答:1

我正在尝试为我的颜色分级着色器加载代表颜色查找表的PNG。

这里是Neutral LUT png表示形式:

<< img src =“ https://image.soinside.com/eyJ1cmwiOiAiaHR0cHM6Ly9pLmltZ3VyLmNvbS92MkpKelZKLnBuZyJ9” alt =“ img”>

我不确定如何正确地将其作为3d纹理加载,然后将其传递到我的着色器中。显然,正在发生颜色转换,但是我最终得到一个嘈杂的彩虹混乱,而不是中性图像。例如:“

这是我创建纹理的方式

    glGenTextures(1, &lut_texture);
    glBindTexture(GL_TEXTURE_3D, lut_texture);
    glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
    glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB8, 32, 32, 32, 0, GL_RGB,
        GL_UNSIGNED_BYTE, &lut_image[0]);

这是我将其传递给着色器的方法:

    glUseProgram(colorGradingProgram);
    glUniform1f(glGetUniformLocation(colorGradingProgram, "tex0"), 0);
    glUniform1f(glGetUniformLocation(colorGradingProgram, "lut"), 1);
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, colorBuffers[0]); 
    glActiveTexture(GL_TEXTURE1);
    glBindTexture(GL_TEXTURE_3D, lut_texture); 
    drawQuad();
    glBindTexture(GL_TEXTURE_3D, 0); 
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, 0); 
    glUseProgram(0);

这里是碎片着色器(使用GLSL 1.x):

uniform sampler2D tex0;
uniform sampler3D lut;

void main(void)
{
  vec4 colorIn = texture2D(tex0, gl_TexCoord[0].st);

  vec4 colorOut;    
  colorOut.rgb = texture3D(lut, colorIn.rgb).rgb;   

  gl_FragColor = colorOut;  
}

我最不清楚的是为致电指定的尺寸

glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB8, 32, 32, 32, 0, GL_RGB,
        GL_UNSIGNED_BYTE, &lut_image[0]);

根据我在这里使用的值,我的结果差异很大。我能得到的最接近中性图像的东西是使用(2,2,2)作为宽度,高度,深度,但这在直觉上不会引起我共鸣,也不是完全中性。我不明白自己在做什么或应该如何实现(将2d纹理转换为3d体积)

opengl colors glsl shader lookup-tables
1个回答
0
投票

根据我从上面的评论得出的有根据的猜测,您需要

  1. 分别上传每个纹理层。
  2. 指定GL_RGBA格式。

以下代码应该这样做(免责声明-未经测试):

glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB8, 32, 32, 32, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
glPixelStorei(GL_UNPACK_ROW_LENGTH, 1024);
for(int z = 0; z < 32; ++z) {
    glPixelStorei(GL_UNPACK_SKIP_PIXELS, 32*z);
    glTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, z, 32, 32, 1, GL_RGBA, GL_UNSIGNED_BYTE, &lut_image[0]);
}
© www.soinside.com 2019 - 2024. All rights reserved.