问题部分解决,留下上一篇文章&此处的代码供参考,新问题(在标题中标明)在底部的强文后
我正在尝试使用颜色选择来识别Android上的OpenGL中的对象。我的代码在大多数情况下工作正常,所有对象都分配了0.00f,0.00f,0.00f格式的唯一颜色(Alpha始终为0),并且单击对象时使用glreadpixels识别它们(大多数时候)并转换/比较价值。
仅在使用某些颜色值时才会出现此问题。例如,如果对象被赋予颜色0.0f,0.77f,1.0f(RGB),则它将不会稳固地着色。它将对象的部分颜色为0.0,0.76,1.0或0.0,0.78.1.0。我认为它可能是颜色混合,所以我将场景中的每个对象着色这种颜色,但同样的事情发生了,这也消除了我认为可能是另一个原因的任何光照问题(尽管我没有明确地实现光知识)。这个问题出现在几种颜色上,而不仅仅是陈述的颜色。
如何判断对象或渲染器是否完全按照说明对这些对象进行着色,而不是将颜色混合在哪一侧?
如果R:0.0f G:0.77f B1.0f的颜色传递给glUniform4v& glDrawArrays,它被绘制(并由glreadpixels读取)为R:0.0f G:0.78f B1.0f。这不是发生这种情况的唯一价值,这只是一个例子。
赞赏任何修复建议
答案 0 :(得分:1)
至少有两个方面可以帮助您获得完全预期的颜色:
默认情况下启用抖动颜色输出。基于我所看到的,如果你渲染到每个组件8位的目标,它通常似乎不会发挥作用(或者至少不是以可测量的方式)。但是当你渲染到较低的颜色深度时,它肯定非常引人注目,比如RGB565。
抖动导致的确切情况的细节似乎与供应商有关。
默认情况下,抖动启用。对于典型用途,这可能是件好事,因为你只关心视觉外观。抖动的整个想法显然是为了提高视觉质量。但是,如果您依赖于获取输出颜色的可控和可预测值(例如在拾取案例中必要的话),则应始终禁用抖动:
glDisable(GL_DITHER);
根据您的代码您已经意识到,精度是一个很大的问题。你显然不能指望完全返回与你最初为颜色指定的浮点值相同的浮点值。
主要的精度损失来自颜色值到颜色缓冲区中的标准化值的转换。对于8位/分量颜色深度,该值的精度为1.0 / 255.0。这意味着应该可以生成和比较精度为0.01的值。
精度损失的另一个来源是着色器处理。由于您为着色器代码中的精度指定了mediump
,这为您提供了至少大约10位的精度,这看起来也不应该是有害的。
一种可能性是您实际上没有获得具有8位颜色分量的配置。这也与视觉抖动效果一致。假如你有一个RGB565表面,你观察到的精度开始变得有意义了。
例如,对于RGB565,如果为绿色分量传入0.77,则在固定点转换期间将该值乘以63(2 ^ 6 - 1),得到48.51。现在,规范说:
将值(通过舍入到最接近)转换为具有m位的固定点值,其中m是分配给相应的R,G,B,A或深度缓冲区组件的位数。
48.51的最接近值是49.但是如果你在路上的任何地方丢失任何精度,它很容易变成48。
现在,当您将这些值转换回浮动状态并将其读回时,它们将除以63.0。如果帧缓冲区中的值为48,则结果为0.762,您将在代码0.76中舍入到该值。如果它是49,结果是0.777,其回合到0.78。
简而言之:
此外,对值使用0.01的倍数看起来不是理想的策略,因为它不与帧缓冲区中的表示对齐。我会使用2^b - 1
的倍数,其中b
是颜色分量中的位数。指定颜色时使用这些值,并在将读回的值与预期值进行比较时应用匹配的量化。