gl_Position
优质
小牛编辑
130浏览
2023-12-01
gl_Position
内置变量主要和顶点相关,出现的位置是顶点着色器语言的main
函数中。gl_Position
内置变量表示最终传入片元着色器片元化要使用的顶点位置坐标。
如果只有一个顶点,直接在给顶点着色器中设置内置变量gl_Position
赋值就可以,内置变量gl_Position
的值是四维向量vec4(x,y,z,1.0)
,前三个参数表示顶点的xyz坐标值,第四个参数是浮点数1.0
。
void main() {
//顶点位置,位于坐标原点
gl_Position = vec4(0.0,0.0,0.0,1.0);
}
如果你想完全理解内置变量gl_Position
,必须建立逐顶点
的概念,如果javascript语言中出现一个变量赋值,你可以理解为仅仅执行一次,但是对于着色器中不能直接这么理解,如果有多个顶点,你可以理解为每个顶点都要执行一遍顶点着色器主函数main
中的程序。
多个顶点的时候,内置变量gl_Position
对应的值是attribute
关键字声明的顶点位置坐标变量apos
,顶点位置坐标变量apos
变量对应了javascript代码中多个顶点位置数据。
<!-- 顶点着色器源码 -->
<script id="vertexShader" type="x-shader/x-vertex">
//attribute声明vec4类型变量apos
attribute vec4 apos;
void main() {
//顶点坐标apos赋值给内置变量gl_Position
//逐顶点处理数据
gl_Position = apos;
}
</script>
逐顶点
处理的案例:WebGL的每一个顶点位置坐标都会通过平移矩阵m4
进行矩阵变换,相当于批量操作所有的顶点数据,进行了平移,只是平移的计算通过矩阵乘法运算完成的而已。所谓的逐顶点
,在这里体现的就是每一个顶点都会执行main
函数中的矩阵变换。你可以参照生活的流水线去理解,比如多个同样的设备从我这里经过,我会分别对他们进行同样的操作,比如安装一个零件。
<!-- 顶点着色器源码 -->
<script id="vertexShader" type="x-shader/x-vertex">
//attribute声明vec4类型变量apos
attribute vec4 apos;
void main() {
//创建平移矩阵(沿x轴平移-0.4)
//1 0 0 -0.4
//0 1 0 0
//0 0 1 0
//0 0 0 1
mat4 m4 = mat4(1,0,0,0, 0,1,0,0, 0,0,1,0, -0.4,0,0,1);
//平移矩阵m4左乘顶点坐标(vec4类型数据可以理解为线性代数中的nx1矩阵,即列向量)
// 逐顶点进行矩阵变换
gl_Position = m4*apos;
}
</script>
顶点数据传递
attribute
声明的顶点变量数据如何通过javascript的WebGL API批量传递所有顶点数据。
<script>
//顶点着色器源码
var vertexShaderSource = document.getElementById( 'vertexShader' ).innerText;
//片元着色器源码
var fragShaderSource = document.getElementById( 'fragmentShader' ).innerText;
//初始化着色器
var program = initShader(gl,vertexShaderSource,fragShaderSource);
//获取顶点着色器的位置变量apos,即aposLocation指向apos变量。
var aposLocation = gl.getAttribLocation(program,'apos');
//类型数组构造函数Float32Array创建顶点数组
var data=new Float32Array([0.5,0.5,-0.5,0.5,-0.5,-0.5,0.5,-0.5]);
//创建缓冲区对象
var buffer=gl.createBuffer();
//绑定缓冲区对象,激活buffer
gl.bindBuffer(gl.ARRAY_BUFFER,buffer);
//顶点数组data数据传入缓冲区
gl.bufferData(gl.ARRAY_BUFFER,data,gl.STATIC_DRAW);
//缓冲区中的数据按照一定的规律传递给位置变量apos
gl.vertexAttribPointer(aposLocation,2,gl.FLOAT,false,0,0);
//允许数据传递
gl.enableVertexAttribArray(aposLocation);
...
</script>