这是从每通道32位浮点数到每通道颜色标准化的“无符号字节”的转换,以便为其他事物节省一些pci-express带宽。有时会出现颜色条纹,看起来不自然。
我该如何避免这种情况?特别是在球体的边缘。
浮色通道:
无符号字节通道:
此处,蓝色球体上的黄色边缘和红色球体上的蓝色边缘不应存在。
我使用的规范化(来自opencl内核):
// multiplying with r doesnt help as picture color gets too bright and reddish.
float r=rsqrt(pixel0.x*pixel0.x+pixel0.y*pixel0.y+pixel0.z*pixel0.z+0.001f);
unsigned char rgb0=(unsigned char)(pixel0.x*255.0);
unsigned char rgb1=(unsigned char)(pixel0.y*255.0);
unsigned char rgb2=(unsigned char)(pixel0.z*255.0);
rgba_byte[i*4+0]=rgb0>255?255:rgb0;
rgba_byte[i*4+1]=rgb1>255?255:rgb1;
rgba_byte[i*4+2]=rgb2>255?255:rgb2;
rgba_byte[i*4+3]=255;
绑定到缓冲区:
GL11.glEnableClientState(GL11.GL_COLOR_ARRAY);
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, id);
GL11.glColorPointer(4, GL11.GL_UNSIGNED_BYTE, 4, 0);
在java环境中使用lwjgl(glfw context)。
正如Andon M.所说的那样,我在施法前被夹住了(我无法看到我什么时候睡得很沉)并且它解决了。
顺便说一下,色彩质量不是很好,但使用较小的色彩缓冲可以提高性能。
答案 0 :(得分:3)
您的原始数据集包含标准化[ 0.0 , 1.0 ]范围之外的浮点值,后面乘以 255.0 并进行投射到unsigned char
产生溢出。您遇到的假色彩出现在场景中一个或多个颜色分量特别明亮的区域。
在您编写rgb0>255?255:rgb0
时,您似乎知道会出现这种溢出,但该逻辑不起作用,因为当unsigned char
溢出时,它会绕回 0 而不是数字大于 255 。
对此的最小解决方案是将浮点颜色限制在[ 0.0 , 1.0 ]范围内 在转换为定点 0.8 (8位无符号标准化)颜色之前,以避免溢出。
但是,如果这是一个经常出现的问题,那么最好将HDR实现到LDR后期处理。您将识别场景的某个区域(或全部)中最亮的像素,然后将所有颜色标准化为该范围。你开始实现这个(使用r = sqrt (...)
),但它只使用当前像素的大小来标准化颜色。