ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

c – 剪裁到0-1范围的纹理值?

2019-07-25 06:08:12  阅读:233  来源: 互联网

标签:c opengl textures


简单的问题:

OpenGL默认情况下是否将纹理值剪辑到0-1范围内?如果它确实有一种方法来禁用它?

详细问题:

我有一个纹理,在创建时,我将一些默认值.

我创建RGBA值大小为16×16的纹理,如下所示:

//Generate the texture and get its ID
GLuint texID;
glGenTextures(1, &texID);

//Bind the texture
glBindTexture(GL_TEXTURE_2D, texID);

//Define the size of the texture
int width = 16;
int height = 16;
int numberOfElementsPerTexel = 4;
int size = width * height * numberOfElementsPerTexel;

//Create an empty array of texel data
float data[size];
std::fill_n(data, size, 0.0f);

//Add the empty data to the texture
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, GL_RGBA, GL_FLOAT, data);

为了测试这在我创建和填充纹理后正常工作,我检查内容如下:

//Bind the texture
glBindTexture(GL_TEXTURE_2D, texID);

//Get the data from the texture
float texData[size];
glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_FLOAT, texData);
{
    for(int i = 0; i < size; i++)
    {
        printf("Value at %d: %f\n", i, texData[i]);
    }
}

所以这给出了0的负载,正如我所期望的那样,然后在调用glTexImage2D之前作为另一个测试我修改了数据数组中的一个值:

data[0] = 1.0f;

正如预期的那样,在第一个要打印的数字中增加了1.0. 0到1之间的任何数字都按预期打印出来但是大于1或小于0的任何数字都会截断到该范围?

这听起来可能是因为纹理存储颜色值,因此剪切到RGBA值的范围.是这种情况还是我做错了什么?

如果是这种情况有没有办法禁用它?我想在纹理中存储任意数据而不是颜色值它只是我希望提高性能,因为纹理/纹理查找结构在GPU中高度优化

解决方法:

Does OpenGL clip texture values to the range 0-1 by default?

有时 – 取决于您访问纹理的方式和纹理的内部格式.

And if it does is there a way to disable this?

不是真的,但你可以改变内部格式来获得你想要的东西.

GL Spec 4.6,第2.3.5节定点数据转换:

When generic vertex attributes and pixel color or depth components are
repre- sented as integers, they are often (but not always) considered
to be normalized. Normalized integer values are treated specially when
being converted to and from floating-point values, and are usually
referred to as normalized fixed-point. Such values are always either
signed or unsigned.

The conversion from a floating-point value f to the corresponding
unsigned nor- malized fixed-point value c is defined by first clamping
f to the range [0, 1]
, then

以下调用是欺骗性的,因为纹理格式给出了GL_FLOAT(只是说你给它的数据是32位浮点).内部格式为GL_RGBA.我相信大多数实现最终都使用GL_RGBA8来存储它,即每个通道8位,如无符号字符r,g,b,a(尽管规范不要求这样).根据GL规范的上一部分,输入数据值将被钳制,然后转换为固定点. 0.0f及以下变为0且1.0f及以上变为255.

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, GL_RGBA, GL_FLOAT, data);

当您在着色器中使用此类纹理进行读取和写入时,也会发生相同的情况.整数值透明地缩放到[0,1]范围.在您的情况下,使用glGetTexImage GL_FLOAT也可以将整数值缩放回[0,1],但传入的数据已经被钳制.如果您使用GL_UNSIGNED_BYTE和无符号字符/ GLubyte数组读取,则应该看到0到25​​5.访问纹理时,使用与内部格式相同的格式访问它可能更快.然后就不需要转换了.

glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_FLOAT, texData);

简而言之,是的,0到1范围之外的任何东西都会被钳制(例如,使用FBO写入典型的RGB / A纹理).如果您不需要精度但仍希望数字大于1,则可以预先缩放值.

如果您需要更高的精度,可以使用GL_RGBA32F,如下所示.在这种情况下,不需要转换 – 您的输入与纹理存储相同,并且不会发生夹紧.缺点是它将占用数据的4倍,这意味着访问时传输的数量是4倍.当然,这不仅仅是更常规的精度,因为您获得了浮点格式的指数表示.

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, width, height, GL_RGBA, GL_FLOAT, data);

标签:c,opengl,textures
来源: https://codeday.me/bug/20190725/1530016.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有