首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >计算着色器浮点算法确实不准确。

计算着色器浮点算法确实不准确。
EN

Stack Overflow用户
提问于 2022-06-10 12:04:01
回答 1查看 125关注 0票数 4

我目前正在编写一个计算着色器,它需要一个浮点数和一个uint3的简单浮点乘法,而且我得到的结果非常不准确。

例如,uint3(1,2,3) * 0.25

预期结果: uint3(0.25,0.5,0.75)

实际结果: uint3(0.3,0.5,0.8)

知道怎么提高精度吗?

计算机着色器:

代码语言:javascript
复制
[numthreads(X_THREADS, Y_THREADS, Z_THREADS)]
void CSMain (uint3 id : SV_DispatchThreadID)
{
    // Fill the array
    uint tid = id.x;
    while (tid < octree_length)
    {
        // Normalize tid
        uint depth = OctreeDepth(tid);
        uint mid = tid - depth_offsets[depth];

        // Compute node data
        float node_size = bounds_size / pow(2, depth);
        float3 node_min = MortonToXYZ(mid) * node_size; 

        // Build node
        octree[tid].anchor = node_min;
        octree[tid].size = node_size;

        // Move tid
        tid += total_num_threads;
    }
}

不准确的乘法:

代码语言:javascript
复制
float3 node_min = MortonToXYZ(mid) * node_size; 

thread

  • MortonToXYZ:的
  • mid:该的Morton代码返回元素介于0,无穷大之间的uint3,这是解码的Morton code
    • node_size:,在0之间浮动,在无穷大

    之间。

启动着色器并将数据读取回的代码:

代码语言:javascript
复制
ComputeBuffer BuildOctree(Vector3 boundsMin, float boundsSize, int octreeDepth, Vector3Int numThreadGroups) 
{
    // Compute constants
    int totalNumThreads = numThreadGroups.x * numThreadGroups.y * numThreadGroups.z * THREADS_PER_GROUPS;

    // Compute depth offsets and octree length
    int[] depthOffsets = new int[octreeDepth];
    int length = 0;

    for (int i = 0; i < octreeDepth; i++)
    {
        depthOffsets[i] = length;
        length += (int) Mathf.Pow(8, i);
    }

    // Prepare buffers
    ComputeBuffer octree = new ComputeBuffer(length, 4 * sizeof(float), ComputeBufferType.Structured);
    ComputeBuffer depthOffsetsGPU = new ComputeBuffer(octreeDepth, sizeof(int), ComputeBufferType.Structured);

    depthOffsetsGPU.SetData(depthOffsets);
    octree.SetData(new OctreeNode[length]);

    // Load data into shader
    OCTREE_BUILDER.SetBuffer(0, "octree", octree);
    OCTREE_BUILDER.SetBuffer(0, "depth_offsets", depthOffsetsGPU);
    OCTREE_BUILDER.SetInt("total_num_threads", totalNumThreads);
    OCTREE_BUILDER.SetInt("octree_length", length);
    OCTREE_BUILDER.SetFloat("bounds_size", boundsSize);

    // Launch kernal
    OCTREE_BUILDER.Dispatch(0, numThreadGroups.x, numThreadGroups.y, numThreadGroups.z);

    OctreeNode[] output = new OctreeNode[length];
    octree.GetData(output);

    for (int i = 0; i < output.Length; i++)
        Debug.Log("cell[" + i + "]: " + output[i].anchor + ", " + output[i].size);

    // Return octree buffer
    return octree;
}

注:\

  • I尝试了一个只计算uint3(1,1,1) * 0.25的最小示例

预期结果: uint3(0.25,0.25,0.25)

实际结果: uint3(0.3,0.3,0.3)\

  • I正在使用RTX 2070
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-06-10 14:28:09

正如user @bart指出的,问题在打印中,统一打印2位格式,舍入我的值,使用ToString("F5")在我的打印中显示正确的值

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72574015

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档