3

我的代码需要根据对象的位置以不同的方式呈现对象的区域。我正在尝试使用颜色图来定义这些区域。

问题是当我从我的颜色图中取样时,我会遇到碰撞。即,颜色图中具有不同颜色的两个区域从采样器返回相同的值。

我尝试了各种格式的颜色图。在每种情况下,我将每个区域的颜色设置为“5”;

  • 索引颜色
  • RGB、RGBA:区域 1 将具有 RGB 5%、5%、5%。区域 2 将具有 RGB 10%、10%、10% 等。
  • HSV 灰度:区域 1 的 HSV 为 0,0,5%。区域 2 将具有 HSV 0,0,10%,依此类推。

(在 Gimp 中选择的值)

tex2D 采样器返回一个值 [0..1]。

[然后我打算从 region 派生一个 int 数组索引。与此相关的代码无关,因此已从问题中删除]

float region = tex2D(gColourmapSampler,In.UV).x;

对“5%”颜色进行采样给出了 hlsl 中 0.05098 的“区域”。据此,我假设 5% 表示 5/100*255,即 12.75,当存储在纹理中时四舍五入为 13。(推理:0.05098 * 255 ~= 13)

按照这个逻辑,50% 应该存储为 127.5。
采样后,我得到 0.50196,这意味着它存储为 128。

70% 应存储为 178.5。
采样后,我得到 0.698039,这意味着它存储为 178。

这里发生了什么舍入
(127.5 变成 128,178.5 变成 178 ?!)

编辑:好的, http ://en.wikipedia.org/wiki/Bankers_rounding#Round_half_to_even 显然这是“银行家的四舍五入”。我不知道为什么要使用它,但它解决了我的问题。显然,这是一个 Gimp 问题。


我正在使用 Shader Model 2 和 FX Composer。这是我的采样器声明;

//Colour map
texture gColourmapTexture <
    string ResourceName = "Globe_Colourmap_Regions_Greyscale.png";
    string ResourceType = "2D";
>;
sampler2D gColourmapSampler : register(s1) = sampler_state {
Texture = <gColourmapTexture>;
#if DIRECT3D_VERSION >= 0xa00
    Filter = MIN_MAG_MIP_LINEAR;
#else /* DIRECT3D_VERSION < 0xa00 */
    MinFilter = Linear;
    MipFilter = Linear;
    MagFilter = Linear;
#endif /* DIRECT3D_VERSION */
    AddressU = Clamp; 
    AddressV = Clamp;
};   
4

3 回答 3

1

我从未使用过 HLSL,但我确实使用过 GLSL(我必须承认它在我的脑海中非常遥远)。

我对纹理的一个问题是 0 不是第一个像素。1 不是第二个。0 是纹理的边缘,1 是第一个像素的右边缘。这些值会自动插值,如果您需要的是精度,例如应用查找表而不是应用普通纹理时,这可能会导致严重的问题。您需要瞄准像素的中间,因此要求 [0.5,0.5]、[1.5,0.5] 而不是 [0,0]、[1, 0] 等等。

至少,在 GLSL 中是这样的。

于 2010-04-20T14:43:53.377 回答
1

注意:levels[region] 中的区域被四舍五入。当您在图像编辑器中看到 5 % 时,纹理 8b 表示中的实际值是 5/100*255 = 12.75,可能是 12 或 13。如果是 12,则四舍五入会影响您。如果要四舍五入到最接近,则需要将其更改为级别 [区域 + 0.5]。

另一件类似的事情(已经由 Louis-Philippe 编写)可能会打动你,那就是纹理坐标舍入规则。你总是需要点击纹素中的一个点,这样你就不会在两个纹素之间,否则结果是不明确的(你可能会随机得到两个纹素中的任何一个),并且你的一些源纹素可能会消失而其他重复。这些规则对于双线和点采样是不同的,您可能需要在采样时添加一半的纹素大小来弥补这一点。

于 2010-04-20T14:55:11.440 回答
1

GIMP 使用银行家四舍五入法。显然。

这抛出了我的代码来导出区域索引。

于 2010-04-21T13:59:05.610 回答