OpenGL ES 2.0的纯色和放大器;颜色值precision问题纯色、放大器、颜色、问题

2023-09-04 03:00:58 作者:戒烟戒酒戒爱情

问题部分解决,剩下previous邮电放大器; code在这里,以供参考,新的问题(标题中所述)后,在底部的强文

我想使用的颜色采摘辨别物体在OpenGL Android上。我的code正常工作,在大多数情况下,所有的对象都分配了唯一的颜色在0.00f,0.00f,0.00f的格式(字母始终为0),并在它们被发现的物体点击(在大多数情况下,当),使用glreadpixels和变换/比较值

I am trying to use colour picking to identify objects in OpenGL on Android. My code works fine for the most part, all objects are assigned unique colours in a 0.00f, 0.00f, 0.00f format (Alpha is always 0), and when clicking on the objects they are identified (Most of the time) using glreadpixels and converting/comparing the values.

仅在使用的某种的颜色值时,将出现问题。例如,如果一个对象是给定的颜色0.0,0.77f,1.0F(RGB),也不会着色牢固。它会着色的对象0.0,0.76,1.0或0.0,0.78.1.0的部分。我想这可能是混色,所以我染成这个颜色,但同样的事情发生在场景中的每个对象,这也消除了,我想可能是另一个原因(尽管没有明确的实施轻型据我所知)任何照明问题。在几个颜色会发生此问题,不只是一个说明。

The problem only occurs when using certain colour values. For instance, if an object is given the colour 0.0f, 0.77f, 1.0f (RGB), it will not colour solidly. It will colour parts of the object 0.0,0.76,1.0 or 0.0,0.78.1.0. I thought it might be colour blending so I coloured every object in the scene this colour but the same thing happened, this also eliminates any lighting issues which I thought might be another cause (despite not implementing light explicitly to my knowledge). This issue occurs on a few colours, not just the one stated.

我如何知道对象或渲染色彩,而不是融合了它的颜色两侧?

How can I tell the object or the renderer to colour these objects solidly exactly as stated, instead of a blend of the colours either side of it?

颜色不通过的规定来了,如果R的颜色:0.0 G:0.77f B1.0f传递给glUniform4v&安培;调用glDrawArrays,它绘制(和glreadpixels读取)为R:0.0 G:0.78f B1.0f。这不是唯一的值与出现这种情况,这仅仅是一个例子。

The colours are not coming through as stated, if a color of R:0.0f G:0.77f B1.0f is passed to glUniform4v & glDrawArrays, it is drawn (and read by glreadpixels) as R:0.0f G:0.78f B1.0f. This is not the only value with which this happens, this is just an example.

有一个修复的任何建议都AP preciated

Any suggestions for a fix are appreciated

推荐答案

有能进来你得到确切的预期色彩的方式至少有两个方面的内容:

There are at least two aspects that can come in your way of getting exactly the expected color:

抖动的彩色输出默认情况下启用。根据我所看到的,它通常不会似乎发挥作用(或至少不以可衡量的方式),如果你渲染目标,每个组件8位。但是,这绝对是非常明显的,当你渲染到一个较低的颜色深度,如RGB565。

Dithering for color output is enabled by default. Based on what I've seen, it doesn't typically seem to come into play (or at least not in a measurable way) if you're rendering to targets with 8 bits per component. But it's definitely very noticeable when you're rendering to a lower color depth, like RGB565.

中到底发生了什么作为抖动的结果的细节显得十分依赖于供应商。

The details of what exactly happens as the result of dithering appears to be very vendor dependent.

抖动是启用默认情况下。在一般使用情况,这可能是一件好事,因为你只在乎外观。和抖动的整个想法显然是增强视觉质量。但是,如果你依赖于您的输出色彩越来越可控,predictable值,就像它是必要的,你采摘的情况下,你应该总是禁用抖动:

Dithering is enabled by default. For typical use, that's probably a good thing, because you only care about the visual appearance. And the whole idea of dithering is obviously to enhance the visual quality. But if you rely on getting controllable and predictable values for your output colors, like it's necessary in your picking case, you should always disable dithering:

glDisable(GL_DITHER);

precision

正如你已经知道根据您的code,precision是这里的一大问题。你显然不能指望得到的完全的相同的浮点值回你原来的颜色指定的。

Precision

As you're already aware based on your code, precision is a big concern here. You obviously can't expect to get exactly the same floating point value back as the one you originally specified for the color.

的precision的主要损失来自于颜色值转换为在颜色缓冲器的归一化值。随着8位/组件的颜色深度,即价值precision为1.0 / 255.0。这意味着你的应的罚款与发电和0.01 precision比较值。

The primary loss of precision comes from the conversion of the color value to a normalized value in the color buffer. With 8 bits/component color depth, the precision of that value is 1.0/255.0. Which means that you should be fine with generating and comparing values with a precision of 0.01.

precision损失的另一个来源是着色器处理。既然你指定 mediump 为precision着色器code,它给你至少约10位precision,这也像它不应该是有害的。

Another source of precision loss is the shader processing. Since you specify mediump for the precision in the shader code, which gives you at least about 10 bits of precision, that also looks like it should not be harmful.

一种可能性是,你实际上并没有得到与8位色彩分量的配置。这也将是与视觉抖动效果是一致的。如果你有一个RGB565面说,你观察到precision开始变得有意义。

One possibility is that you didn't actually get a configuration with 8-bit color components. This would also be consistent with the visual dithering effect. Say if you got a RGB565 surface, your observed precision starts to make sense.

例如,与RGB565,如果传递的0.77绿色成分,该值乘以63(1 2的6次方)。现在,该规范说:

For example, with RGB565, if you pass in 0.77 for the green component, the value is multiplied with 63 (2^6 - 1) during fixed point conversion, which gives 48.51. Now, the spec says:

值被转换(四舍五入至最接近的)到一个固定点的值具有m比特,其中m是分配给相应的R位的数目,G,B,A或深度缓冲成分

Values are converted (by rounding to nearest) to a fixed-point value with m bits, where m is the number of bits allocated to the corresponding R, G, B, A, or depth buffer component.

为48.51最接近的值是49。但是,如果你输了的任意的那种precision某处的方式,它可以很容易地成为48。

The nearest value for 48.51 is 49. But if you lose any kind of precision somewhere on the way, it could very easily become 48.

现在,当这些值转换回浮在你阅读他们回来,他们由63.0分。如果在帧缓冲值是48,结果是0.762,你会舍入到您的code 0.76。如果是49,则结果为0.777,其舍入到0.78。

Now, when these values are converted back to float while you read them back, they are divided by 63.0. If the value in the framebuffer was 48, the result is 0.762, which you would round to in your code 0.76. If it was 49, the result is 0.777, which rounds to 0.78.

因此​​,在短期:

要非常小心,你可以期望什么样的precision。 我想你可能有一个RGB565帧缓冲。

此外,如果使用0.01的倍数的值并不像一个理想的策略,因为它不与再presentation在帧缓冲区排队。我会用倍数2 ^ B - 1 ,其中 B 是位的颜色组件的数量。指定颜色时使用这些值,而当你比较,你读回与预期值的数值适用匹配的量化。

Also, using multiples of 0.01 for the values does not look like an ideal strategy because it does not line up with the representation in the framebuffer. I would use multiples of 2^b - 1, where b is the number of bits in the color components. Use those values when specifying colors, and apply the matching quantization when you compare the values you read back with the expected value.