WebGL着色器内置变量gl_PointSize、gl_Position、gl_FragColor、gl_FragCoord、gl_PointCoord

article/2025/9/15 14:24:01

WebGL着色器内置变量

WebGL中文教程网

本文是WebGL教程(电子书)的2.7节内容

着色器语言在GPU的着色器单元执行,javascript语言、C语言在CPU上执行,任何一种语言的语法规则,整体设计都和它执行的硬件有一定的关系,GPU和CPU执行程序的硬件单元既有相同点,也有不同点。这里谈到GPU和CPU不是为了讲解硬件,而是为了提醒大家,学习着色器语言有些语法可以参考javascript、C等执行在CPU上的语言,比如if语句、for语句、浮点数、布尔值,有些语法完全没必要参考javascript、C等执行在CPU上的语言,比如着色器语言中的内置变量gl_PointSizegl_Positiongl_FragColor等等,声明一些变量使用的关键字attributeuniformvarying。学习着色器语言的时候,如果你有兴趣可以深入研究GPU,对于WebGL学习来说,把GPU当成一个黑箱就可以,你只需要学会着色器语言的编程规则即可

普通变量,着色器语言和javascript语言一样需要先声明后使用,所谓内置变量就是不用声明可以直接赋值,主要是为了实现特定的功能。

内置变量含义值数据类型
gl_PointSize点渲染模式,方形点区域渲染像素大小float
gl_Position顶点位置坐标vec4
gl_FragColor片元颜色值vec4
gl_FragCoord片元坐标,单位像素vec2
gl_PointCoord点渲染模式对应点像素坐标vec2

gl_PointSize

当WebGL执行绘制函数gl.drawArrays()绘制模式是点模式gl.POINTS的时候,顶点着色器语言main函数中才会用到内置变量gl_PointSize,使用内置变量gl_PointSize主要是用来设置顶点渲染出来的方形点像素大小。

void main() {//给内置变量gl_PointSize赋值像素大小,注意值是浮点数gl_PointSize=20.0;
}
//绘制函数绘制模式:点gl.POINTS
gl.drawArrays(gl.POINTS,0,点数量);

gl_Position

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类型变量aposattribute vec4 apos;void main() {//顶点坐标apos赋值给内置变量gl_Position//逐顶点处理数据gl_Position = apos;}
</script>

逐顶点处理的案例:WebGL的每一个顶点位置坐标都会通过平移矩阵m4进行矩阵变换,相当于批量操作所有的顶点数据,进行了平移,只是平移的计算通过矩阵乘法运算完成的而已。所谓的逐顶点,在这里体现的就是每一个顶点都会执行main函数中的矩阵变换。你可以参照生活的流水线去理解,比如多个同样的设备从我这里经过,我会分别对他们进行同样的操作,比如安装一个零件。

<!-- 顶点着色器源码 -->
<script id="vertexShader" type="x-shader/x-vertex">//attribute声明vec4类型变量aposattribute vec4 apos;void main() {//创建平移矩阵(沿x轴平移-0.4)//1   0   0  -0.4//0   1   0    0//0   0   1    0//0   0   0    1mat4 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>

gl_Position的顶点数据传递

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();//绑定缓冲区对象,激活buffergl.bindBuffer(gl.ARRAY_BUFFER,buffer);//顶点数组data数据传入缓冲区gl.bufferData(gl.ARRAY_BUFFER,data,gl.STATIC_DRAW);//缓冲区中的数据按照一定的规律传递给位置变量aposgl.vertexAttribPointer(aposLocation,2,gl.FLOAT,false,0,0);//允许数据传递gl.enableVertexAttribArray(aposLocation);
...
</script>

gl_FragColor

gl_FragColor内置变量主要用来设置片元像素的颜色,出现的位置是片元着色器语言的main函数中。

内置变量gl_Position的值是四维向量vec4(r,g,b,a),前三个参数表示片元像素颜色值RGB,第四个参数是片元像素透明度A,1.0表示不透明,0.0表示完全透明。

// 片元颜色设置为红色
gl_FragColor = vec4(1.0,0.0,0.0,1.0);

理解内置变量gl_Position需要建立逐顶点的概念,对于内置变量gl_FragColor而言,需要建立逐片元的概念。顶点经过片元着色器片元化以后,得到一个个片元,或者说像素点,然后通过内置变量gl_FragColor给每一个片元设置颜色值,所有片元可以使用同一个颜色值,也可能不是同一个颜色值,可以通过特定算法计算或者纹理像素采样。

根据位置设置渐变色

  void main() {// 片元沿着x方向渐变gl_FragColor = vec4(gl_FragCoord.x/500.0*1.0,1.0,0.0,1.0);}

纹理采样

// 接收插值后的纹理坐标
varying vec2 v_TexCoord;
// 纹理图片像素数据
uniform sampler2D u_Sampler;
void main() {// 采集纹素,逐片元赋值像素值gl_FragColor = texture2D(u_Sampler,v_TexCoord);
}

片元坐标gl_FragCoord

内置变量gl_FragCoord表示WebGL在canvas画布上渲染的所有片元或者说像素的坐标,坐标原点是canvas画布的左上角,x轴水平向右,y竖直向下,gl_FragCoord坐标的单位是像素,gl_FragCoord的值是vec2(x,y),通过gl_FragCoord.xgl_FragCoord.y方式可以分别访问片元坐标的纵横坐标。

在这里插入图片描述

下面代码是把canvas画布上不同区域片元设置为不同颜色。

<!-- 片元着色器源码 -->
<script id="fragmentShader" type="x-shader/x-fragment">void main() {// 根据片元的x坐标,来设置片元的像素值if(gl_FragCoord.x < 300.0){// canvas画布上[0,300)之间片元像素值设置gl_FragColor = vec4(1.0,0.0,0.0,1.0);}else if (gl_FragCoord.x <= 400.0) {// canvas画布上(300,400]之间片元像素值设置gl_FragColor = vec4(0.0,1.0,0.0,1.0);}else {// canvas画布上(400,500]之间片元像素值设置gl_FragColor = vec4(0.0,0.0,1.0,1.0);}    // 所有片元设置为红色// gl_FragColor = vec4(1.0,0.0,0.0,1.0);}
</script>

片元的颜色随着坐标变化(设置一个渐变色效果)

<!-- 片元着色器源码 -->
<script id="fragmentShader" type="x-shader/x-fragment">void main() {// 片元沿着x方向渐变gl_FragColor = vec4(gl_FragCoord.x/500.0*1.0,1.0,0.0,1.0);}
</script>

渲染点片元坐标gl_PointCoord

如果你想了解内置变量gl_PointCoord表示的坐标含义,就需要了解WebGL绘制函数gl.drawArrays()的绘制模式参数gl.POINTS

绘制函数gl.drawArrays()绘制模式参数设置为点渲染模式gl.POINTS,WebGL会把顶点渲染为一个方形区域,在顶点着色器代码中可以通过内置变量gl_PointSize设置顶点渲染的方向区域像素大小。

一个顶点渲染为一个方形区域,每个方形区域可以以方向区域的左上角建立一个直角坐标系,然后使用内置变量gl_PointCoord描述每个方形区域中像素或者说片元的坐标,比如方形区域的左上角坐标是(0.0,0.0),每个方形区域几何中心坐标是(0.5,0.5),右下角坐标是(1.0,1.0)

注意内置变量gl_PointCoordgl_FragCoord表示的像素坐标含义不同,查看下图表示。
在这里插入图片描述

// 点绘制模式渲染10个顶点
gl.drawArrays(gl.POINTS,0,10);

顶点着色器中通过内置变量gl_PointSize设置点渲染的方形区域像素尺寸。

void main() {//点渲染的方形区域像素大小gl_PointSize = 20.0;...
}

gl_PointCoord应用案例

gl.POINTS绘制模式点默认渲染效果是方形区域,通过下面片元着色器代码设置可以把默认渲染效果更改为圆形区域。

<!-- 片元着色器源码 -->
<script id="fragmentShader" type="x-shader/x-fragment">precision lowp float;// 所有float类型数据的精度是lowpvoid main() {// 计算方形区域每个片元距离方形几何中心的距离// gl.POINTS模式点渲染的方形区域,方形中心是0.5,0.5,左上角是坐标原点,右下角是1.0,1.0,float r = distance(gl_PointCoord, vec2(0.5, 0.5));//根据距离设置片元if(r < 0.5){// 方形区域片元距离几何中心半径小于0.5,像素颜色设置红色gl_FragColor = vec4(1.0,0.0,0.0,1.0);}else {// 方形区域距离几何中心半径不小于0.5的片元剪裁舍弃掉:discard;}}</script>

通过gl_PointCoord返回的是片元纵横坐标vec2(x,y),自然通过xy分量gl_PointCoord.xgl_PointCoord.y方式可以分别访问片元坐标的横坐标、纵坐标,


http://chatgpt.dhexx.cn/article/4F733WbR.shtml

相关文章

Unity画线之GL

上一篇中&#xff0c;SetPixel的方法&#xff0c;卡顿严重&#xff0c;暂未解决&#xff0c;又去看了原来的GL画线&#xff0c;自己画图思考了一下适配UI的问题&#xff0c;最终解决。 特此说明&#xff0c;GL画线功能&#xff0c;及Shader均为借鉴&#xff0c;自己做了优化。…

GL823K

下面是另一家SD/TF解码芯片的方案 ![](https://img-blog.csdnimg.cn/20210319145313645.png?x-oss-processimage/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80OTU3MDgwNA,size_16,color_FFFFFF,t_70 13030533945 VX

GL各个表结构总结

NewProgramer EBS GL表结构学习(转) gl_code_combinations&#xff1a;科目组合 字段名 含义 备注 code_combination_id 主键&#xff0c;科目编码ID&#xff0c;自动编号 segment1 分行代码 setgment2 是受益部门 segment3 科目代码 segment4 产品…

初识mapbox GL

一、概述 最近由于项目的需求&#xff0c;借此机会对mapbox GL做了一个系统的学习&#xff0c;同时也对整个学习过程做一个记录&#xff0c;一方面留作自用&#xff0c;另一方面也希望看到此文的人在学习mapbox GL的时候&#xff0c;能够有所启发、有所收获。 二、快速认识 …

支持Genero BDL 4gl语言的编辑器

内测版本出来啦。点此下载: FglDeveloper v1.0 →此版本已下架 还有bug,分享几张截图 模板产生器&#xff1a; 画面产生器&#xff1a; 编辑器各种变量提醒 详细功能小伙伴们下载后体验。

TOPGP5.3:导入jar包并在4GL中引用

查看环境$CLASSPATH 上传引用到的JAR包到以下目录 /u1/topprod/tiptop/ds4gl2/bin/javaad/jar 以上为GP5.3目录&#xff0c;其他版本系统可根据查看到的$CLASSPATH上传到相应目录设置环境变量 GP5.3系统中&#xff0c;$CLASSPATH环境变量的设置存在下图文件中&#xff1a; …

4gl调用WEB API,实现JSON传递(Demo)

测试环境: GP5.25 , fjs版本2.32,解析json所需要的jar依赖包 (PS: 如果没有记错是fjs2.32版本及以上才支持java bridge,所以GP 5.25以下的同学就不要用这种方式去测试) 测试内容: 利用此fjs版本对java bridge的支持,实现4gl调用WEB API,实现json传递 测试步骤如下: 1.下载本…

给大家展示一下4gl编辑器

&#xff08;正式版已发布点击下载&#xff09;特地为编辑器开发内置语法解析器&#xff0c;将在代码编辑过程中实时提示代码错误&#xff0c;并且错误提示都是中文显示(楼主英文太垃圾只有做中文了),不再需要频繁上传服务器了哦&#xff0c; 经过楼主努力已经把所有的内置函数…

【实习之T100开发】Genero FGL (TIPTOP4GL) 学习笔记(1)

Genero FGL 学习 Genero FGL 简介Genero FGL 开发&#xff08;编译、连接、执行&#xff09;第一个程序 Hello World变量与运算符变量定义&#xff08;DEFINE&#xff09;预定义变量变量集合&#xff08;RECORD &#xff09;数据结构&#xff08;TYPE&#xff09;变量赋值&…

win10忘记密码重置密码,一行代码帮你解决

步骤如下&#xff1a; 1.右击windows图标&#xff0c;选择进入Windows PowerShell(管理员&#xff09; 2.敲入代码net user 加上你的用户名和新密码&#xff0c;Ok&#xff0c;问题解决&#xff0c;你就可以用你的新密码登陆了

win10 重置登录账户密码

在登陆界面按下强制关机&#xff08;重复3次&#xff09;。注意&#xff1a;不能进到登陆界面 出现下图时&#xff0c;选择“高级选项”&#xff1a; 选择“疑难解答”&#xff1a; 选择“高级选项”&#xff1a; 选择“命令提示符”&#xff1a; 在管理员窗口输入diskpart 回车…

服务器2008系统设置密码,win2008服务器设置密码

win2008服务器设置密码 内容精选 换一换 修改服务IP地址&#xff0c;并且将DNS地址指向本机&#xff0c;然后修改计算机名为server。安装AD域服务之后&#xff0c;机器名称会自动变成“主机名域名”的形式&#xff0c;例如server.huawei.com。在命令行下输入dcpromo.exe &#…

Win10系统修改开机密码

愚蠢的人才能进步&#xff0c;对于我这种记忆力差的人&#xff0c;密码这个东东随时忘&#xff0c;今天早上大无语事件&#xff0c;我自己都惊呆了&#xff0c;每天都用的办公电脑&#xff0c;今天死活想不起密码&#xff0c;死活打不开电脑&#xff0c;明明就是那些组合&#…

win10忘记密码_电脑忘记密码没关系,这招教你简单轻松改密码

相信"忘记电脑开机密码"这件事经常发生,忘记密码该怎么办呢?这个问题困扰了许多小伙伴,今天就教大家一种最简单的方法轻松重置电脑开机密码(本方法适用win10、win8、win7系统)。 划重点: 重置电脑开机密码一共分为三个步骤「 制作PE系统」「进入PE系统 」「重置密…

win10计算机默认用户名和密码是什么,win10共享的文件夹需要密码和用户名登陆...

一、共享文件夹所在电脑设置 1、右键我的电脑→管理→系统工具→本地用户和组→用户→中间空白区域右键→新用户&#xff1b; 2、输入自设的用户名和密码&#xff0c;如图勾选→创建&#xff1b; 3、右键需要共享的文件见→安全→编辑&#xff1b; 4、点击添加&#xff1b; 5、…

WIN10取消密码和休眠密码

安装Win10系统之后&#xff0c;发现每次开机都会出现登录密码&#xff1f;有些用户觉得很麻烦&#xff0c;所以想要取消Win10开机密码。那么&#xff0c;该如何操作呢&#xff1f; 按下winx组合键&#xff0c;启动快捷菜单 在弹出菜单选择运行&#xff0c;如下图所示 在运行框…

计算机共享网络的账号密码怎么设置密码,怎样才能给win10共享设置密码的操作方法...

怎样才能给win10共享设置密码呢&#xff1f;一些善于使用win10共享设置的小伙伴们&#xff0c;一定会为了隐私而设置win10的共享设置密码&#xff0c;为了可以完美的设置共享密码&#xff0c;小伙伴们找了好多方法&#xff0c;都没有解决&#xff0c;针对这一问题&#xff0c;小…

win10系统mysql重新配置密码

前言 最近捣鼓自己的破烂笔记本&#xff0c;想着写点玩具项目&#xff0c;想着&#xff1a;写项目不能没有mysql吧&#xff0c;点击mysqlbench开始上号。这个时候发现坏了&#xff0c;登录不上&#xff0c;想着估计mysql没装好呗&#xff0c;于是重装了mysql和mysqlbench&…

win10重置网络命令_Win10怎么重置网络 Win10重置网络命令使用方法

有时候Windows系统出问题的时候&#xff0c;会导致网络异常&#xff0c;无法正常上网&#xff0c;甚至是重新连接网络&#xff0c;依然会出现无法连接的现象。下面就来为大家分享2种重置网络的方法&#xff0c;有需要了解的小伙伴&#xff0c;快来涨知识吧 方法一&#xff1a;使…

win10 linux重置密码忘记了,忘记密码时如何重新设置Windows10密码

忘记了Windows10计算机的本地管理员密码&#xff0c;如果忘记密码&#xff0c;您将无法访问PC上的任何数据。为什么会这样呢&#xff1f;可能您的Microsoft帐户密码可能已被盗用&#xff0c;针对此疑问&#xff0c;接下去和大家分享忘记密码时重新设置Windows10密码的方法。 但…