在WebGL中,属性,统一和变量变量之间有什么区别?

Sko*_*ius 68 variables types matrix webgl

在比较这些不同的类型或者这些东西是如何工作时,我能想到一个类比吗?

另外,统一矩阵意味着什么?

Alf*_*nez 76

直接从http://www.lighthouse3d.com/tutorials/glsl-tutorial/data-types-and-variables/复制.实际网站有更详细的信息,值得一试.

可变限定符

限定符赋予变量特殊含义.可以使用以下限定符:

  • const - 声明是编译时常量.
  • attribute - 从OpenGL应用程序传递到顶点着色器的每个顶点可能更改的全局变量.此限定符只能在顶点着色器中使用.对于着色器,这是一个只读变量.请参见属性部分.
  • uniform - 从OpenGL应用程序传递到着色器的每个原语[...]可能更改的全局变量.此限定符可用于顶点着色器和片段着色器.对于着色器,这是一个只读变量.见统一部分.
  • 变化 - 用于顶点着色器和片段着色器之间的插值数据.可用于在顶点着色器中写入,并且在片段着色器中是只读的.请参阅变化部分.

至于类比,const和uniform就像C/C++中的全局变量,一个是常量而另一个是可以设置的.属性是伴随顶点的变量,如颜色或纹理坐标.变量变量可以由顶点着色器更改,但不能由片段着色器更改,因此实质上它们是沿着管道传递信息.


nee*_*eeh 50

  • uniform每个基元参数(在整个绘制调用期间保持不变);
  • attribute每顶点参数(通常:位置,法线,颜色,UV,......);
  • varying每片段(或每像素)参数:它们从像素到像素不等.

了解如何varying编程自己的着色器非常重要.
假设您v顶点着色器内的三角形的每个顶点定义变化参数.当此变化参数被发送到片段着色器时,其值将根据要绘制的像素的位置通过双线性插值自动插值.

在下图中,红色像素接收变化参数的内插值v.这就是我们称之为"变化"的原因.

变量参数是双线性插值的

  • 答案的精神是正确的,但请记住,对于_variing_,所做的默认插值称为透视正确插值,而不仅仅是双线性插值。当然,这可以通过[插值限定符](https://www.khronos.org/opengl/wiki/Type_Qualifier_(GLSL)#Interpolation_qualifiers)`noperspective`进行更改,以获得简单的双线性插值而不是透视正确的插值(由默认限定符标识:“smooth”)。请参阅[此示例](http://www.geeks3d.com/20130514/opengl-interpolation-qualifiers-glsl-tutorial/)。 (2认同)

tfm*_*gue 8

在OpenGL中,"程序"是"着色器"(较小程序)的集合,它们在管道中相互连接.

// "program" contains a shader pipeline:
//   vertex shader -> other shaders -> fragment shader
//
const program = initShaders(gl, "vertex-shader", "fragment-shader");
gl.useProgram(program);
Run Code Online (Sandbox Code Playgroud)

着色器处理光栅化3D模型所需的顶点(顶点着色器),几何(几何着色器),曲面细分(曲面细分着色器),片段(像素着色器)和其他批处理任务(计算着色器).

OpenGL(WebGL)着色器是用GLSL编写的(在GPU上编译的基于文本的着色器语言).

// Note: As of 2017, WebGL only supports Vertex and Fragment shaders

<!-- Vertex Shader -->
<script id="shader-vs" type="x-shader/x-vertex">

  // <-- Receive from WebGL application
  uniform vec3 vertexVariableA;

  // attribute is supported in Vertex Shader only
  attribute vec3 vertexVariableB;

  // --> Pass to Fragment Shader
  varying vec3 variableC;

</script>

<!-- Fragment Shader -->
<script id="shader-fs" type="x-shader/x-fragment">

  // <-- Receive from WebGL application
  uniform vec3 fragmentVariableA;

  // <-- Receive from Vertex Shader
  varying vec3 variableC;

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

记住这些概念:

着色器可以将数据传递到管道(out,inout)中的下一个着色器,并且它们还可以接受来自WebGL应用程序或先前着色器(in)的数据.

  • Vertex和Fragment着色器(实际上任何着色器)都可以使用uniform变量来从WebGL应用程序接收数据.

    // Pass data from WebGL application to shader
    const uniformHandle = gl.glGetUniformLocation(program, "vertexVariableA");
    gl.glUniformMatrix4fv(uniformHandle, 1, false, [0.1, 0.2, 0.3], 0);
    
    Run Code Online (Sandbox Code Playgroud)
  • Vertex Shader还可以使用attribute变量从WebGL应用程序接收数据,可以根据需要启用或禁用该变量.

    // Pass data from WebGL application to Vertex Shader
    const attributeHandle = gl.glGetAttribLocation(mProgram, "vertexVariableB");
    gl.glEnableVertexAttribArray(attributeHandle);
    gl.glVertexAttribPointer(attributeHandle, 3, gl.FLOAT, false, 0, 0);
    
    Run Code Online (Sandbox Code Playgroud)
  • 顶点着色器可以使用varying变量将数据传递到片段着色器.参见上面的GLSL代码(varying vec3 variableC;).