如何在C ++中为GLSL创建1D lut [英] How to make a 1D lut in C++ for GLSL

查看:520
本文介绍了如何在C ++中为GLSL创建1D lut的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我开始理解如何实现一个片段着色器来做一个LUT,但我很难找到任何好的资源,告诉你如何使C ++中的1D LUT,然后纹理它。

I'm beginning to understand how to implement a fragment shader to do a 1D LUT but I am struggling to find any good resources that tell you how to make the 1D LUT in C++ and then texture it.

所以对于一个简单的例子给出下面的1D如下:

So for a simple example given the following 1D lut below:

我要创建一个包含以下数据的数组吗?

Would I make an array with the following data?

int colorLUT[255] = {255,
                     254,
                     253,
                     ...,
                     ...,
                     ...,
                     3,
                     2,
                     1,
                     0};

unsigned char

如果这是如何创建LUT,那么如何将它转换为纹理呢?我应该使用 glTexImage1D 吗?还是有更好的方法来做到这一点?

If this is how to create the LUT, then how would I convert it to a texture? Should I use glTexImage1D? Or is there a better method to do this? I'm really at a lose here, any advice would be helpful

我很抱歉这么短,但我没有看到任何教程如何实际做并链接LUT,GLSL上的每个教程只告诉你关于他们总是忽略链接部分的着色器。

I'm sorry to be so brief but I haven't seen any tutorials about how to actually make and link the LUT, every tutorial on GLSL only tells you about the shaders they always neglect the linking part.

我的最终目标是我想知道如何使用如下所示的不同1D LUT,并将它们全部应用于图像。

My end goal is I would like to know how to take different 1D LUTs as seen below and apply them all to images.

推荐答案

是的,您可以使用1D纹理作为查找表。

Yes, you can use 1D textures as lookup tables.

您可以将数据加载到1D纹理 glTexImage1D()。使用 GL_R8 作为内部纹理格式,并将数据传递给时指定 GL_UNSIGNED_BYTE glTexImage1D(),是你的最佳选择,如果8位的精度足够的价值。你的调用看起来像这样, lutData GLubyte 数据的指针/数组, lutSize 您的LUT大小:

You can load the data into a 1D texture with glTexImage1D(). Using GL_R8 as the internal texture format, and specifying the data as GL_UNSIGNED_BYTE when passing it to glTexImage1D(), is your best choice if 8 bits of precision are enough for the value. Your call will look like this, with lutData being a pointer/array to GLubyte data, and lutSize the size of your LUT:

glTexImage1D(GL_TEXTURE_1D, 0, GL_R8, lutSize, 0, GL_RED, GL_UNSIGNED_BYTE, lutData);

如果您需要比8位更高的精度,可以使用 GL_R16 GL_R32F

If you need higher precision than 8 bits, you can use formats like GL_R16 or GL_R32F.

确保您也正确设置了纹理参数,例如对于查找表中的值之间的线性采样:

Make sure that you also set the texture parameters correctly, e.g. for linear sampling between values in the lookup table:

glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

然后将纹理绑定到 sampler1D 在着色器中统一,并使用常规纹理采样函数来检索新值。请记住,纹理坐标在0.0到1.0的范围内,因此您需要将原始值的范围映射到[0.0,1.0],然后将其传递到纹理采样函数。您从纹理采样函数接收到的新值也将在[0.0,1.0]的范围内。

You then bind the texture to a sampler1D uniform in your shader, and use the regular texture sampling functions to retrieve the new value. Remember that texture coordinates are in the range 0.0 to 1.0, so you need to map the range of your original values to [0.0, 1.0] before you pass it into the texture sampling function. The new value you receive from the texture sampling function will also be in the range [0.0, 1.0].

请注意,只要您的查找是一个相对简单的函数,它可能更有效地计算在着色器中的函数。但是如果LUT可以包含完全任意的映射,使用1D纹理是一个很好的方法。

Note that as long as your lookup is a relatively simple function, it might be more efficient to calculate the function in the shader. But if the LUT can contain completely arbitrary mappings, using a 1D texture is a good way to go.

在没有1D纹理的OpenGL变体中,您可以使用高度设置为1的2D纹理。

In OpenGL variations that do not have 1D textures, like OpenGL ES, you can use a 2D texture with height set to 1 instead.

如果您需要大于支持的最大纹理大小的查找表,您还可以查看缓冲纹理,如Andon在他的评论中所建议的。

If you need lookup tables that are larger than the maximum supported texture size, you can also look into buffer textures, as suggested by Andon in his comment.

这篇关于如何在C ++中为GLSL创建1D lut的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆