代码之家  ›  专栏  ›  技术社区  ›  Hazel へいぜる

数值条件从来都不是真的?

  •  0
  • Hazel へいぜる  · 技术社区  · 6 年前

    概述

    上周我在 HLSL . 目标是只给满足特定条件的像素上色。在我的情况下,情况是基于 “时间” 因为这不是我们所认为的传统时间。我在三维空间中绘制了一条线,这是一项微不足道的任务。但是,根据当前用户选择的时间,只应显示行的某个百分比。

    我创造了一个 Line 类并添加了 SliderControl 以允许用户控制当前时间点。这非常简单,可以完成,就像设置所有底层代码一样。


    问题

    当我创建底层代码时,我在时间类型上犯了一个简单的错误。在当前时间的常量缓冲区中,我使用 double 在我的内心 Vertex 结构(任意定义和输入,以及像素着色输入),我使用 float . 这导致我的像素着色器中的条件始终导致 false . 差异的原因是原始数据是 双重的 但我最终选择了 浮动 为了匹配代码中的所有其他内容,加上使用 双重的 类型在 HLSL .


    HLSL

    代码非常简单:

    cbuffer TimeBuffer : register(b4) {
        double CurrentTime;
    }
    struct VertexInput {
        float Time;
        //...
    }
    struct PixelInput {
        float Time;
        //...
    }
    float4 PSMain(PixelInput input) : SV_Target {
        float4 result = 0;
        if (input.Time < CurrentTime)
            result = input.Diffuse;
    
        return result;
    }
    

    问题

    为什么从未渲染线条?

    1 回复  |  直到 6 年前
        1
  •  0
  •   Hazel へいぜる    6 年前

    这里的问题是由于 cbuffer 以及 struct 输入。只需使类型匹配:

    cbuffer TimeBuffer : register(b4) {
        float CurrentTime;
    }
    struct VertexInput {
        float Time;
        //...
    }
    struct PixelInput {
        float Time;
        //...
    }
    float4 PSMain(PixelInput input) : SV_Target {
        float4 result = 0;
        if (input.Time < CurrentTime)
            result = input.Diffuse;
    
        return result;
    }
    

    只需更改 result float4(0, 1, 0, 0) 或者其他纯色将显示线条确实正在渲染,但条件从未评估为 true .


    我们可以找到一个很好的彻底的答案来解释为什么这是一个问题。 here .我最初不明白这是个问题,因为我认为 double float 可以像其他数字类型一样进行比较。但是我错了,正如上面链接的帖子所说:

    考虑浮点数或双位数的重要因素有:

    精度: 浮点数的精度是指在不丢失所包含的任何信息的情况下,它可以表示的位数。

    舍入: 两者之间没有明显的区别 binary decimal (base 10) 数字。考虑分数 1/10 . 在 decimal ,这可以很容易地表示为 0.1 零点一 可以认为是一个容易表示的数字。然而,在二进制中, 零点一 由无限序列表示: 0.00011001100110011… .


    然而,这似乎也与 int 浮动 而不是 双重的 浮动 .