我从kevin brothaler那里快速了解了opengl es 2.0这本书。
他写了一个顶点着色器:
attribute vec4 a_Position;
attribute vec4 a_Color;
varying vec4 v_Color;
void main()
{
v_Color = a_Color;
gl_Position = a_Position;
gl_PointSize = 10.0;
}
和像这样的片段着色器:
precision mediump float;
varying vec4 v_Color;
void main()
{
gl_FragColor = v_Color;
}
我的问题:为什么我们需要将颜色传递给顶点着色器?我们不能直接将颜色传递给片段着色器吗?它表示顶点着色器仅用于顶点位置,片段着色器用于片段颜色。
答案 0 :(得分:2)
您可以使用制服直接将颜色传递给片段着色器。然后,这种颜色是每次绘制调用(每个对象)。另一方面,您可以在顶点着色器中传递每个顶点的颜色,然后传递给片段着色器。
虽然第一个程序非常直接,但第二个程序却没有。如果要传递每个顶点的颜色,则必须使用属性。然后,每个顶点都需要具有颜色属性。然后如何使用这些颜色取决于顶点着色器,但通常这些颜色将在光栅化中按照片段进行插值。例如,它是如何工作的:你画一条线有2个点,一个是白色,另一个是黑色。您将看到的结果将是从白色到黑色的渐变线(中间为灰色)。三角形也是如此(尝试3个具有红色,绿色和蓝色的顶点)。这曾经是最常见的测试(教程)应用程序;一个openGL版本的" hello world"。
您实施的这两项中的哪一项实际上取决于您的需求,并且在许多情况下,它们都在片段着色器中使用和相乘。
varying
值用于从顶点着色器传递到片段着色器。这意味着您希望每个片段插入的任何值都必须以这种方式使用。您需要做的是在顶点着色器中定义这样的值,然后您可以在片段着色器中使用它。这两个定义是相似的,关于它的说法不多,但您可以将其视为使用extern
,尽管后面还有更多内容。
色彩插值确实是一个不好学习的例子,因为你通常没有使用它。这种插值的极常常见的用法是法线。如果你想使用光线绘制一个漂亮的曲面,你想要插入法线,这样形状就不会太过于前卫。
答案 1 :(得分:1)
不,我们不需要将任何颜色传递给顶点着色器,唯一的要求是片段着色器必须存储输出值或丢弃片段。 最常见的输出存储在gl_FragColor变量中。
顶点着色器可以将一些颜色值传递给片段着色器,可以从某些属性传输,可以执行光照或几乎任何着色器开发人员想要的。
片段着色器可以使用任何及所有输入数据计算输出颜色,在最简单的情况下,可以传递一些常量或统一(由调用代码提供)值。