Webgl 存储限定符attribute、gl.getAttribLocation、gl.vertexAttrib3f及其同族函数和矢量版本的介绍

news/2024/11/17 0:40:22/

目录

attribute变量规范

 获取attribute变量的存储位置

gl.getAttribLocation()函数的规范:

向attribute变量赋值 

gl.vertexAttrib3f()的规范。 

gl.vertexAttrib3f()的同族函数 

 示例代码

效果图


attribute变量规范

关键词attribute被称为存储限定符,它表示接下来的变量是一个attribute变量。attribute变量必须声明成全局变量,数据将从着色器外部传给该变量。变量的声明必须按照以下的格式:<存储限定符> <类型> <变量名>,如图所示。

 一旦声明a_Position之后,我们将其赋值给gl_Position:

gl_Position = a_Position;\n' 

 获取attribute变量的存储位置

在WebGL系统中建立了顶点着色器。然后,WebGL就会对着色器进行解析,辨识出着色器具有的attribute变量,每个变量都具有一个存储地址,以便通过存储地址向变量传输数据。比如,当你想要向顶点着色器的a_Position变量传输数据时,首先需要向WebGL系统请求该变量的存储地址。我们使用gl.getAttribLocation()来获取attribute变量的地址。 

 

方法的第一个参数是一个程序对象gl.program,它包括了顶点着色器和片元着色器,注意,你必须在调用initShader()之后再访问gl.program,因为是initShader()函数创建了这个程序对象。第二个参数是想要获取存储地址的attribute变量的名称。 

方法的返回值是attribute变量的存储地址。这个地址被存储在JavaScript变量a_Position中,以备之后使用。

gl.getAttribLocation()函数的规范如下:

向attribute变量赋值 

一旦将attribute变量的存储地址保存在JavaScript变量a_Position中,下面就需要使用该变量来向着色器传入值。我们使用gl.vertexAttrib3f()函数来完成这一步。

下面是gl.vertexAttrib3f()的规范。 

该函数的第1个参数是attribute变量的存储地址,即gl.getAttribLocation()的返回值;第2、3、4个参数是三个浮点型数值,即点的x、y和z坐标值。函数被调用后,这三个值被一起传给顶点着色器中的a_Position变量。下图显示了获取attribute变量的存储地址并向其传值的过程。 

接着,在顶点着色器中,a_Position的值就被赋给了gl_Position,这样我们就成功地将点的x、y和z的坐标值从JavaScript传入了着色器,并赋值给了gl_Position,gl_Position的值还是(0.0,0.0,0.0,1.0)。

最后,使用gl.clear()清空<canvas>,并使用gl.drawArrays()绘制点。 

你可能已经注意到,第4行的a_Position变量是vec4类型的,但是gl.vertex-Attrib3f()仅传了三个分量值(x、y和z)而不是4个。是不是漏掉了1个呢?实际上,如果你省略了第4个参数,这个方法就会默认地将第4个分量设置为了1.0,如下图所示。颜色值的第4个分量为1.0表示该颜色完全不透明,而齐次坐标的第4个分量为1.0使齐次坐标与三维坐标对应起来,所以1.0是一个“安全”的第4分量。 

gl.vertexAttrib3f()的同族函数 


gl.vertexAttrib3f()是一系列同族函数中的一个,该系列函数的任务就是从JavaScript向顶点着色器中的attribute变量传值。gl.vertexAttrib1f()传输1个单精度值(v0),gl.vertexAttrib2f()传输2个值(v0和v1),而gl.vertexAttrib4f()传输4个值(v0、v1、v2和v3)。

你也可以使用这些方法的矢量版本,它们的名字以“v”(vector)结尾,并接受类型化数组作为参数,函数名中的数字表示数组中的元素个数 

其中,函数名中的4表示数组长度是4。

在上面的例子gl.vertexAttrib3f()中,基础函数名是vertexAttrib,参数个数是3,参数类型是f(即float,浮点数类型)。这个函数是OpenGL中的glVertexAttrib3f()的WebGL版本。另一种参数类型的字符表示是i,代表整型数。你可以使用gl.vertexAttrib[1234]f这样的符号来表示从gl.vertexAttrib1f()到gl.vertexAttrib4f()的所有函数。这里,[]表示可以使用其中的任何一个数字。

如果函数名后面跟着一个v,就表示函数也可以接收数组作为参数。在这种情况下,函数名中的数字表示数组中的元素个数。

 示例代码

// HelloPint2.js (c) 2012 matsuda 41
// Vertex shader program
var VSHADER_SOURCE = 'attribute vec4 a_Position;\n' + // attribute variable'attribute float a_PointSize;\n' + // attribute variable'void main() {\n' +'  gl_Position = a_Position;\n' +'  gl_PointSize = a_PointSize;\n' +'}\n'; // Fragment shader program
var FSHADER_SOURCE = 'void main() {\n' +'  gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n' +'}\n';function main() {// Retrieve <canvas> elementvar canvas = document.getElementById('webgl');// Get the rendering context for WebGLvar gl = getWebGLContext(canvas);if (!gl) {console.log('Failed to get the rendering context for WebGL');return;}// Initialize shadersif (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) {console.log('Failed to intialize shaders.');return;}// Get the storage location of a_Position 请求a_Position该attribute变量的存储位置 P4var a_Position = gl.getAttribLocation(gl.program, 'a_Position');if (a_Position < 0) {console.log('Failed to get the storage location of a_Position');return;}var a_PointSize = gl.getAttribLocation(gl.program, 'a_PointSize');if (a_PointSize < 0) {console.log('Failed to get the storage location of a_PointSize');return;}// Pass vertex position to attribute variable 将顶点属性传递给属性变量  P44gl.vertexAttrib3f(a_Position, 0.0, 0.3, 0.0); gl.vertexAttrib1fv(a_PointSize, new Float32Array([100.0])); // vertexAttrib方法的矢量版本,加v,数字表示数组item的个数// Specify the color for clearing <canvas>gl.clearColor(0.0, 0.0, 0.0, 1.0);// Clear <canvas>gl.clear(gl.COLOR_BUFFER_BIT);// Drawgl.drawArrays(gl.POINTS, 0, 1);
}

效果图


http://www.ppmy.cn/news/1050036.html

相关文章

【无监督】6、SimSiam | 基于孪生网络的对比学习的成功源于梯度截断!

文章目录 一、背景二、方法三、效果 论文&#xff1a;Exploring Simple Siamese Representation Learning 出处&#xff1a;FAIR | 何恺明大佬 本文作者抛出了两个爆炸&#x1f4a5;性结论&#xff1a; 结论一&#xff1a;基于孪生网络的对比的学习的成功&#xff0c;不源于 …

php如何持续监听redis的消息订阅

要监听Redis服务&#xff0c;可以使用PHP的redis扩展提供的subscribe方法实现。以下是一个使用PHP监听Redis的示例代码&#xff1a; <?php $redis new Redis();// 连接到Redis服务器 $redis->connect(127.0.0.1, 6379);// 订阅频道 $redis->subscribe([channel_nam…

c++——增强了(全局变量、变量和函数的都要有类型、类型转换、struct结构体、bool类型和三目运算符)

c中全局变量、变量和函数的都要有类型、类型转换、struct结构体、bool类型和三目运算符的增强 一、c全局变量的增强 1、在C语言中全局变量的声明和定义 //全局变量 int a;//定义 int a;//声明 int a;//声明相同变量&#xff0c;第一个是定义&#xff0c;后面的的变量a都是声…

【LeetCode-中等题】128. 最长连续序列

题目 题解一&#xff1a;HeshSet枚举 思路&#xff1a;先对数组进行set去重&#xff0c;核心就是&#xff0c;先找出临界值&#xff08;假设以最小临界为例&#xff0c;那么这个临界值自己就是最小值&#xff0c;&#xff09;&#xff0c;以临界值不断做加1操作&#xff0c;看…

来自西安交大的chisel教程

第零章 序 Chisel教程汇总__iChthyosaur的博客-CSDN博客 来自西安交大的chisel教程 出过书

R语言数据整理技巧(1)-读写、数据类型、重构

1、读取和写入数据&#xff1a;xlsx&#xff1b;txt; rdata pathC:\\Users setwd(path) #读取 #读取csv read.csv(.csv) #读取txt read.txt(.txt) #读取剪贴板 read.table("clipboard") #读取xlsx library(readxl) read_xlsx(.xlsx) #读取rdata文件 load(.radta) #写…

vue-router在vue2/3区别

构建选项区别 vue2-router const router-new VueRouter({mode:history,base:_name,})vue-next-router import { createRouter,createWebHistory} from vue-next-router const routercreateRouter({history:createHistory(/) })在上述代码中我们发现,vue2中的构建选项mode和ba…

代码随想录day11

20. 有效的括号 ● 力扣题目链接 ● 给定一个只包括 ‘(’&#xff0c;‘)’&#xff0c;‘{’&#xff0c;‘}’&#xff0c;‘[’&#xff0c;‘]’ 的字符串&#xff0c;判断字符串是否有效。 ● 有效字符串需满足&#xff1a; ● 左括号必须用相同类型的右括号闭合。 ● 左…