【问题标题】:Why bool func of HasFlag analog ((data & flag) == flag) always return true为什么 HasFlag 模拟的 bool func ((data & flag) == flag) 总是返回 true
【发布时间】:2020-07-23 12:46:15
【问题描述】:

我在检查标志时遇到问题。由于某种原因,它总是返回 True。 (同样的功能在 CPU 上也能正常工作。)

bool HasFlag(uint data, uint flag) { return (data & flag) == flag; }

检查:

if (HasFlag(tag, Invisible | Deleted)) 

在没有函数的情况下编写检查时,一切都被认为是正确的:

if (tag & (Invisible | Deleted) == (Invisble | Deleted))

完整代码:

const uint Invisible = 1 << 0;
const uint Deleted = 1 << 1;
const uint Selected = 1 << 2;

struct Tag
{
    uint tag;
};

RWStructuredBuffer<uint> IndexBuffer;
StructuredBuffer<float3> PositionBuffer;
StructuredBuffer<float> ScaleBuffer;
RWStructuredBuffer<Tag> TagsBuffer;
AppendStructuredBuffer<uint> SelectedItems;
AppendStructuredBuffer<uint> SelectedIndex;
int Length;

float3 RayOrigin;
float3 RayDirection;
float ScaleFactor;

uint SetFlag(uint data, uint flag) { return data | flag; }
uint UnsetFlag(uint data, uint flag) { return data & (~flag); }
uint FlipFlag(uint data, uint flag) { return data ^ flag; }
bool HasFlag(uint data, uint flag) { return (data & flag) == flag; } //<-- problem func

#pragma kernel PointSelect
[numthreads(64, 1, 1)]
void PointSelect(uint3 id : SV_DispatchThreadID)
{
    if (id.x < Length)
    {
        uint tag = TagsBuffer[id.x].tag;

        if (HasFlag(tag, Invisible | Deleted)) //<--- always passes (tag == 0)
        {
            float3 pos = PositionBuffer[id.x];
            float3 spos = pos - RayOrigin;
            float scale = ScaleBuffer[id.x] * 0.2f * ScaleFactor;

            float dist = sqrt(spos.x*spos.x + spos.y*spos.y + spos.z*spos.z);
            float3 rayPos = RayOrigin + dist*RayDirection;
            float3 srPos = rayPos - pos;

            if (srPos.x*srPos.x + srPos.y*srPos.y + srPos.z*srPos.z <= scale * scale)
            {
                TagsBuffer[id.x].tag = tag | Selected;
                SelectedItems.Append(IndexBuffer[id.x]);
                SelectedIndex.Append(id.x);
            }
        }
    }
}

提前谢谢你。 附言谷歌翻译

编辑 1:我注意到在我的示例中,括号的排列方式不同,并决定检查运算符的优先级 (https://en.cppreference.com/w/c/language/operator_precedence)。因此,== 优先于 &。结果,“正确执行的变体”看起来像:date &amp; (flag == flag)。为什么它有效 - 我无法想象。我会去想办法的。

编辑 2:这些函数在 CPU 上正常工作,但在 GPU 上总是由于某种未知原因返回 true:

inline bool AllFlags(uint data, uint flags) { return (data & flags) == flags; }
inline bool AnyFlags(uint data, uint flags) { return (data & flags) > 0; }
inline bool NoneFlags(uint data, uint flags) { return (data & flags) == 0; }

编辑 3:当我在调用函数时使用数字而不是常量时,一切正常。错误在于常量的定义。

【问题讨论】:

    标签: unity3d compute-shader


    【解决方案1】:

    据我所知,问题隐藏在声明常量时我没有注册它们是静态的这一事实。结果,据我了解,无论我为它们分配了什么值,它们都取值为 0。 改的时候问题解决了:

    const uint Invisible = 1 << 0;
    const uint Deleted = 1 << 1;
    const uint Selected = 1 << 2;
    

    在:

    static const uint Invisible = 1 << 0;
    static const uint Deleted = 1 << 1;
    static const uint Selected = 1 << 2;
    

    我希望没有其他人会踩到我的耙子。由于最平庸的事情,很多时间都付诸东流了。

    【讨论】:

      猜你喜欢
      • 2019-11-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多