【问题标题】:How I can draw each corner of each face of a cube in a diferent color?如何用不同的颜色绘制立方体每个面的每个角?
【发布时间】:2020-02-14 06:24:53
【问题描述】:

我是 GLSL 方面的新手,我一直在努力寻找一种方法来为立方体的所有顶点着色不同的颜色。每个面有 4 个顶点,一个立方体有 6 个面,所以 6 * 4 = 24。但我每个角只能绘制 1 种颜色。

顶点着色器:

#version 330

uniform mat4 u_m_matrix;
uniform mat4 u_vp_matrix;

layout (location=0) in vec3 a_position;
layout (location=1) in vec3 a_normal;

out vec3 normal;

void main()
{
    normal = a_position;
    gl_Position = u_vp_matrix * u_m_matrix * vec4(a_position, 1.0);
}

片段着色器:

#version 330

in vec3 normal;

out vec4 fragColor;

void main() {

    fragColor = vec4(normal, 1.0);
 }

结果:

【问题讨论】:

  • 你必须更具体。你想达到什么目标? “如何用不同的颜色绘制立方体的所有顶点?” - 顶点位于立方体的角上。所有的角落都有不同的颜色,不是吗?
  • 我需要用不同的颜色绘制所有顶点。每个面有 4 个顶点,因此 4 * 6 = 24 种颜色。
  • 每个面有 4 个顶点(正确!),一个立方体有 6 个面(再次正确!),所以 6 * 4 = 24.(现在让我阻止你,一个立方体有 8 个顶点,每个面与另一个面共享 2 个顶点)
  • @jalsh 每个面与任何封闭模型中的另一个面共享每个顶点。
  • 不要直言不讳,但你从哪里得到这个 24 数字?立方体有八个不同的顶点。您的示例图片已经用不同的颜色绘制了每一张。

标签: glsl shader


【解决方案1】:

如果你想用不同的颜色为每个面着色并且你想找到一个着色器内的解决方案,一个可能性是为立方体的片段着色,这取决于顶点坐标的分量与最大数量.

将顶点坐标传递给片段着色器:

#version 330

uniform mat4 u_m_matrix;
uniform mat4 u_vp_matrix;

layout (location=0) in vec3 a_position;
//layout (location=1) in vec3 a_normal;

out vec3 vertPos;

void main()
{
    vertPos     = a_position;
    gl_Position = u_vp_matrix * u_m_matrix * vec4(a_position, 1.0);
}

找到绝对值最大的顶点坐标的分量并选择颜色:

#version 330

in vec3 vertPos;

out vec4 fragColor;

void main() {

    vec3 posAbs  = abs(vertPos);
    vec3 color   = step(posAbs.yzx, posAbs) * step(posAbs.zxy, posAbs); 
    color       += (1.0 - step(color.zxy * vertPos.zxy, vec3(0.0)));

    fragColor = vec4(color, 1.0);
}


如果法线向量是面法线,那么使用法线向量还有一个更简单的解决方案:

将法线向量传递给片段着色器:

#version 330

uniform mat4 u_m_matrix;
uniform mat4 u_vp_matrix;

layout (location=0) in vec3 a_position;
layout (location=1) in vec3 a_normal;

out vec3 normal;

void main()
{
    normal      = a_normal;
    gl_Position = u_vp_matrix * u_m_matrix * vec4(a_position, 1.0);
}

根据法线向量计算颜色:

#version 330

in vec3 normal;

out vec4 fragColor;

void main() {

    vec3 color = abs(normal.xyz) + max(normal.zxy, 0.0);
    fragColor  = vec4(color, 1.0);
}

[...] 所以我需要 24 种颜色。 [...]

在这种情况下,我建议以下解决方案。

#version 330

in vec3 vertPos;

out vec4 fragColor;

void main() {

    vec3 posAbs = abs(vertPos);
    vec3 color  = (step(posAbs.yzx, posAbs) * step(posAbs.zxy, posAbs) +
                   step(0.0, vertPos.yzx)) * 0.5;
    fragColor   = vec4(color, 1.0);
}

【讨论】:

  • 我需要用 4 种不同的颜色为 echar 角上色,所以我需要 24 种颜色。对不起,如果我没有解释正确:/
  • @Andre 请参阅我现在添加的答案的最后一部分。
  • 非常感谢!这个答案超级有用!你怎么能使它在顶点解决方案?我只需要在顶点着色器上计算并将其传递给片段着色器?谢谢@Rabbid76
  • @Andre 遗憾的是,这在顶点着色器中不起作用,因为对于所有顶点坐标,顶点的所有分量的数量都是 1(至少相同)。片段着色器中的技巧是vertPos 的组件数量不相等,除了恰好在角落或边缘上,但这可以忽略不计。无论如何,计算并不昂贵,并且可以轻松地按片段完成。
  • 哦,好的,我明白了。非常感谢您花时间回答。你帮了我很多
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-29
  • 1970-01-01
  • 1970-01-01
  • 2020-04-08
  • 2021-10-02
  • 2011-09-12
相关资源
最近更新 更多