为什么'gl_Position'与'position'的数据类型不同

use*_*847 4 opengl-es webgl

我从代码示例中学习了GLSL着色器,我对以下内容感到困惑:gl_Position是vec4数据类型,position是vec3数据类型,为什么?这个"位置"变量到底是什么?我在哪里可以找到某种文档?我能找到的是gl_Position参考,gl_projectionMatrix和projectionMatrix也是如此.即使在GLSL备忘单中也未定义projectionMatrix.

<script type="x-shader/x-vertex" id="vertexshader">

    varying vec3 col;

    void main()
    {
        col         = vec3( uv, 1.0 );
        gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
    }

</script>

<script type="x-shader/x-fragment" id="fragmentshader">

    varying vec3 col;

    void main()
    {
        gl_FragColor = vec4(col, 1);
    }

</script>
Run Code Online (Sandbox Code Playgroud)

gma*_*man 16

position是一个名为变量的用户.position对WebGL没有任何意义.它可能被称为foobarwhatever.对于WebGL没有任何意义,就像变量xyz在JavaScript中没有意义一样

JavaScript的

var xyz = 123;      // this has no meaning to JavaScript, only to the programmer
var position = 789; // this has no meaning to JavaScript either.
Run Code Online (Sandbox Code Playgroud)

WebGL GLSL

attribute vec3 xyz;       // this has no meaning to WebGL
attribute vec3 position;  // this has no meaning to WebGL either
Run Code Online (Sandbox Code Playgroud)

同样如此projectionMatrix.它是程序员制作的变量.WebGL并不关心名称是什么.如果您正在使用某些库(例如说three.js),这些库可能构成变量的某些名称,但这些变量和所选的名称是库的一部分,而不是WebGL的一部分.日本程序员可能会使用haichishaeigyouretu而不是position和的名称projectionMatrix.

以...开头的变量gl_是特殊的全局变量.WebGL快速参考卡上有一个列表.所有其他变量都由程序员组成.

内置输入,输出和常量[7]

着色器程序使用特殊变量与管道的固定功能部分进行通信.写入后可以回读输出特殊变量.输入特殊变量是只读的.所有特殊变量都具有全球范围.

顶点着色器特殊变量[7.1]

Outputs:
Variable                   |Description           | Units or coordinate system
---------------------------+----------------------+------------------
highp vec4 gl_Position;    |transformed vertex    |clip coordinates
                           |position              | 
---------------------------+----------------------+------------------
mediump float gl_PointSize;|transformed point size|pixels
                           |(point rasterization  |
                           |only)                 |
---------------------------+----------------------+------------------
Run Code Online (Sandbox Code Playgroud)

片段着色器特殊变量[7.2]

片段着色器可以写入gl_FragColor或写入一个或多个元素gl_FragData[],但不能同时写入两个元素.gl_FragData数组的大小由内置常量给出gl_MaxDrawBuffers.

Inputs:
Variable                   |Description           | Units or coordinate system
---------------------------+----------------------+------------------
mediump vec4 gl_FragCoord; |fragment position     | window coordinates
                           | within frame buffer  |
---------------------------+----------------------+------------------
bool gl_FrontFacing;       |fragment belongs to a | Boolean
                           |front-facing primitive|
---------------------------+----------------------+------------------
mediump vec2 gl_PointCoord;|fragment position     | 0.0 to 1.0 for
                           |within a point (point | each component
                           |rasterization only)   | 
---------------------------+----------------------+------------------

Outputs:
Variable                   |Description           | Units or coordinate system
---------------------------+----------------------+------------------
mediump vec4 gl_FragColor; |fragment color        | RGBA color
---------------------------+----------------------+------------------
mediump vec4 gl_FragData[n]|fragment color for    | RGBA color
                           |color attachment n    |
---------------------------+----------------------+------------------
Run Code Online (Sandbox Code Playgroud)

具有最小值的内置常量[7.4]

Built-in Constant                                 | Minimum value
--------------------------------------------------+------------------
const mediump int gl_MaxVertexAttribs             | 8
--------------------------------------------------+------------------
const mediump int gl_MaxVertexUniformVectors      | 128
--------------------------------------------------+------------------
const mediump int gl_MaxVaryingVectors 8          |
--------------------------------------------------+------------------
const mediump int gl_MaxVertexTextureImageUnits   | 0
--------------------------------------------------+------------------
const mediump int gl_MaxCombinedTextureImageUnits | 8
--------------------------------------------------+------------------
const mediump int gl_MaxTextureImageUnits         | 8
--------------------------------------------------+------------------
const mediump int gl_MaxFragmentUniformVectors    | 16
--------------------------------------------------+------------------
const mediump int gl_MaxDrawBuffers               | 1
--------------------------------------------------+------------------
Run Code Online (Sandbox Code Playgroud)

内置统一状态[7.5]

指定窗口坐标中的深度范围.如果实现不支持片段语言中的highp精度,并且state列为highp,则该状态将仅作为片段语言中的mediump使用.

struct gl_DepthRangeParameters {
   highp float near; // n
   highp float far; // f
   highp float diff; // f - n
};

uniform gl_DepthRangeParameters gl_DepthRange;
Run Code Online (Sandbox Code Playgroud)

作为positionvec3的var 也是程序员的决定.它就像一个vec4或一个float或任何你想要的一样好.

虽然着色器可以是你想要的任何东西并使用你想要的任何变量名称,但最常见的顶点着色器可能是

attribute vec4 position;
uniform mat4 projectionMatrix;
uniform mat4 modelViewMatrix;

void main() {
  gl_Position = projectionMatrix * modelViewMatrix * position;
}
Run Code Online (Sandbox Code Playgroud)

有些程序员使用vec3position但他们必须把它强制为vec4反正

attribute vec3 position;
uniform mat4 projectionMatrix;
uniform mat4 modelViewMatrix;

void main() {
  gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1);
}
Run Code Online (Sandbox Code Playgroud)

由于wvec4属性的值默认为1.0,因此没有理由手动执行.

您可能会发现这些文章有助于解释WebGL


pep*_*ppe 10

gl_Position是一个内置的顶点着色器输出变量,其类型由OpenGL规范定义为a vec4.

position是一个顶点着色器属性,并且自引入可编程着色器后,(作为开发人员)完全控制其格式.

最有可能的是,你有每顶点3D坐标(因此,每个顶点只有3个浮点数),你通过调用glVertexAttribPointer(或类似)配置为顶点着色器输入,告诉OpenGL从缓冲区一次拉出3个浮点数的position属性.由于需要gl_Position4个浮点数,因此在顶点着色器中需要扩展vec4(通过填充w到1.0).

  • 另外要注意的是,如果使用ShaderMaterial,threejs会自动将position属性(作为vec3)预先添加到顶点着色器.可能是OP困惑的原因. (2认同)