我无法阻止我的计算着色器代码覆盖数组中的项目而不是使用空索引

问题描述 投票:0回答:1
#pragma kernel CombTreeData;


bool SetEmptyIndex(int val) //write to an unwritten (-1) index and set it to val
{
    for (int i = 0; i < 10;i++)
    {
        if (emptyIndices[i] == -1)
        {
            emptyIndices[i] = val;
            return true;
        }
    }
    return false;
}

int GetAndClearEmptyIndex() //return first written index as val and clear that index to -1 (returns -1 if no index found)
{
    int val = 0;
    for (int i = 0; i < 10;i++)
    {
        if (emptyIndices[i] != -1)
        {
            val = emptyIndices[i];
            emptyIndices[i] = -1;
            return val;
        }
    }
    return -1;
}

[numthreads(1,1,1)]
void CombTreeData(uint3 id : SV_DispatchThreadID)
{
    for (int treePointer = 0; treePointer < 50000;treePointer++) // For all possiable trees, living or dead
    {
        if (Trees[treePointer].plantState == 0 && Trees[treePointer].growth > -1) // if the tree at index is dead
        {
            if (SetEmptyIndex(treePointer)) // Save the dead tree's index to the list of emptyIndices
            {
                Trees[treePointer].growth = -1; // Growth of -1 marks the index as already saved to the emptyIndices
            }
            
        }
        if (Trees[treePointer].plantState > 2) // if tree wants to create seeds
        {
            for (int i = 0; i < 4; i++) // Attempt 4 times
            {
                if (Trees[treePointer].plantState >2) // if tree still wants to create seeds
                {
                    int getEmptyVal = GetAndClearEmptyIndex(); // Find empty index and clear it
                    if (getEmptyVal != -1) // If empty index found succesfully
                    {
                        Trees[getEmptyVal].plantState = 1; // Empty tree index is now a seed
                        Trees[getEmptyVal].growth = 0; // with 0 growth
                        Trees[getEmptyVal].pos = Trees[treePointer].pos; // At the position of the seed-creating tree
                        Trees[treePointer].plantState -= 1; // The seed creating tree loses a seed
                    }
                }
            }
            
        }
        
    }
    
}

您好,抱歉出现大量代码转储!本质上,我有一个设置为-1的整数列表,称为emptyIndecies。我循环遍历一个大的树数组,如果树数组中的一个槽为空,我会将该空索引保存到emptyIndecies数组中以供以后使用。如果一棵树想要生成新的种子,我会在emptyIndicies数组中搜索要使用的空树数组索引,将其从emptyIndicies中清除并将树数组中的该索引转换为种子。

这对于第一批种子非常有用,但是在 10 棵左右的树之后(10 是emptyIndecies 的长度),新种子似乎都覆盖了相同的索引,这意味着一旦生成新种子,它们就会消失。我不知道为什么!

我查看了代码,检查了 if 和循环。此时我最好的猜测是我做了着色器不喜欢的事情,因为我对使用计算着色器非常陌生。要么是我错过了一个愚蠢的错误。我的目标是跟踪树数组中的一些空的不确定性,以用于生成新种子。

unity-game-engine indexing hlsl compute-shader
1个回答
0
投票

我发现问题源于计算着色器不想在变量索引处写入数组。但是,它可以准确地写入存储数组的结构化缓冲区的变量索引。因此,即使我不打算将此数据传递给 C# 脚本,将其存储为缓冲区也允许着色器动态索引它并执行我的代码。 (在我看来,这有点迂腐的着色器)

© www.soinside.com 2019 - 2024. All rights reserved.