【问题标题】:opengl - unique color for each triangleopengl - 每个三角形的唯一颜色
【发布时间】:2015-03-07 02:53:43
【问题描述】:

我正在尝试对我的模型进行着色,以使每个三角形都是基于其在缓冲区中的位置的纯色、独特的颜色。我想知道这是否是一种正确的方法。

如果您不需要有关 OpenGL 的信息,可以直接跳到最后一段

这是我的片段着色器,它将根据缓冲区中三角形的索引进行着色。

#version 420 core
out vec3 color
void main(){
    float r, g, b;
    r = (gl_PrimitiveID % 255) / 255.0f;
    g = ((gl_PrimitiveID / 255) % 255) / 255.0f;
    b = ((gl_PrimitiveID / (255 * 255)) % 255) / 255.0f;
    color = vec3(r, g, b);
}

它使用gl_PrimitiveID,它本质上给出了它正在着色的三角形在缓冲区中的位置。因此,如果我执行命令绘制缓冲区并说缓冲区中有三角形,gl_PrimitiveID 会说第一个是0,然后第二个三角形是1,第n 个三角形是n-1

OpenGL 的 RGB 值在 0.0f 和 1.0f 之间浮动(我不知道 1.0f 是否包含在内,这是我的问题的一部分)。

如果 1.0f end 是包容性的,我假设我上面显示的方法将准确地工作,但如果它是独占的,我认为我可能必须除以 256.0f 而不是 255.0f。哪个合适?

替换示例:

r = (gl_PrimitiveID % 255) / 256.0f; // notice 256.0f instead of 255.0f

【问题讨论】:

    标签: c++ opengl glsl


    【解决方案1】:

    我建议另一种可能更简单的方法。你写道:

    OpenGL 的 RGB 值在 0.0f 和 1.0f(我不知道 1.0f 是否具有包容性并且是我的问题的一部分)。

    那不是真的。 OpenGL 支持各种不同的格式,浮点、规范化整数和非规范化整数。对于您的用例,我只建议使用GL_R32UI 格式,这样您就可以直接将gl_PrimitiveID 分配给着色器的输出变量。

    【讨论】:

      【解决方案2】:

      我决定将我对基数 256 的使用情况与基数为 10 的情况进行比较:

      [n / (10^digit_place)] % 10
      

      此公式将在 digit_place 的位置给出从 0 到 9 的数字(仅限整数)。

      例如,如果你想得到n = 1729 的最右边的数字(一个位),你可以这样做:

      步骤:

      1. [1729 / (10^0)] % 10
      2. [1729 / (1)] % 10
      3. 1729 % 10
      4. ans = 9

      让这个公式更抽象:

      radix 是基数的一个奇特术语。示例:在 普通 数字中(0 - 9;以 10 为底),基数为 10

      [n / (radix ^ place)] % radix
      

      我的问题的应用:

      经过一些额外的研究,OpenGL中的rgb值是从0.0f1.0f包括。这意味着(1.0f, 1.0f, 1.0f)rgb 是白色的,而(0.0f, 0.0f, 0.0f)rgb 是黑色的。

      以字节形式(0 - 255;基数/基数 256),rgb 的白色和黑色值如下(按顺序),(255, 255, 255)(0, 0, 0)。将这些值转换为介于0.0f1.0f 之间的数字是(再次按顺序)(255/255.0f, 255/255.0f, 255/255.0f)(0/255.0f, 0/255.0f, 0/255.0f)

      与我的初始着色器比较:

      r = (gl_PrimitiveID % 255) / 255.0f;
      

      此示例中的r 只能介于(包括)0/255.0f254/255.0f 之间。我们想要的是(包括)0/255.0f255/255.0f 之间,如上所示。

      如果我们查看我对r 的计算并将其与公式进行比较,我们就会明白为什么我们会得到一系列不想要的数字。问题源于这部分:(gl_PrimitiveID % 255)。由于模的工作方式,n (n > 1) 的模只能给出0n-1 之间的整数。在这种情况下,或者n255,这给了我们从0254 的问题范围。为了解决这个问题,我们只需将 255 替换为 256(这是我们正在使用的基数/基数),这样计算就可以工作了。

      固定着色器:

      #version 420 core
      out vec3 color
      void main(){
          float r, g, b;
          // notice the 256's instead of 255
          r = (gl_PrimitiveID % 256) / 255.0f;
          g = ((gl_PrimitiveID / 256) % 256) / 255.0f;
          b = ((gl_PrimitiveID / (256 * 256)) % 256) / 255.0f;
          color = vec3(r, g, b);
      }
      

      【讨论】:

      • 虽然如果你希望颜色是平坦的,你应该在片段着色器的输入中为color指定flat
      • @ratchetfreak 你能解释一下这会有什么影响吗?你能链接到文档吗?谢谢你的信息
      • 它阻止颜色在三角形上插值,因此flat in color; 将声明只使用来自 1 个顶点的值
      • 嗯,我不确定这会对我的程序产生任何影响。 gl_PrimitiveID 给出了 Primitive 的 ID,在这种情况下是三角形,而不是三角形的顶点,所以所有顶点应该是相同的颜色。
      • @ratchetfreak:他的 FS 中没有 in,只有 out vec3 color,所以插值限定符根本不适用。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多