WebGL着色器内置变量gl_PointSize、gl_Position、gl_FragColor、gl_FragCoord、gl_PointCoord
WebGL着色器内置变量
WebGL中文教程网
本文是WebGL教程(电子书)的2.7节内容
着色器语言在GPU的着色器单元执行,javascript语言、C语言在CPU上执行,任何一种语言的语法规则,整体设计都和它执行的硬件有一定的关系,GPU和CPU执行程序的硬件单元既有相同点,也有不同点。这里谈到GPU和CPU不是为了讲解硬件,而是为了提醒大家,学习着色器语言有些语法可以参考javascript、C等执行在CPU上的语言,比如if语句、for语句、浮点数、布尔值,有些语法完全没必要参考javascript、C等执行在CPU上的语言,比如着色器语言中的内置变量gl_PointSize
、gl_Position
、gl_FragColor
等等,声明一些变量使用的关键字attribute
、uniform
、varying
。学习着色器语言的时候,如果你有兴趣可以深入研究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.x
、gl_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_PointCoord
和gl_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.x
、gl_PointCoord.y
方式可以分别访问片元坐标的横坐标、纵坐标,
WebGL着色器内置变量gl_PointSize、gl_Position、gl_FragColor、gl_FragCoord、gl_PointCoord相关推荐
- webgl着色器初学习-顶点着色器和片元着色器
文章目录 webgl工作步骤 顶点着色器 片元着色器 案例 webgl工作步骤 每一个像素点都将执行这两个着色器 我理解为这两个着色器,顶点着色器决定渲染位置 ,片元着色器决定颜色 顶点着色器 编写一 ...
- OpenGL ES着色器语言之变量和数据类型
所有变量和函数在使用前必须声明.变量和函数名是标识符. 没有默认类型,所有变量和函数声明必须包含一个声明类型以及可选的修饰符.变量在声明的时候首先要标明类型,后边可以跟多个变量,之间用逗号隔开.很多情 ...
- OpenGL ES着色器语言之变量和数据类型(二)(官方文档第四章)
OpenGL ES着色器语言之变量和数据类型(二)(官方文档第四章) 4.5精度和精度修饰符 4.5.1范围和精度 用于存储和展示浮点数.整数变量的范围和精度依赖于数值的源(varying,unifo ...
- GLSL内置变量和内置函数
shader内置变量: attribute vec4 gl_Color; // 顶点颜色 attribute vec4 gl_SecondaryColor; // 辅助顶点颜色 attribute v ...
- webgl 着色器_“着色器”是什么意思? 如何使用HTML5和WebGL创建它们
webgl 着色器 本文是Microsoft的Web开发技术系列的一部分. 感谢您支持使SitePoint成为可能的合作伙伴. 您可能已经注意到,去年我们第一次谈论了babylon.js ,最近我们发 ...
- webgl 着色器_如何在WebAssembly中使用WebGL着色器
webgl 着色器 by Dan Ruta 通过Dan Ruta 在WebAssembly中使用WebGL着色器 (Using WebGL shaders in WebAssembly) WebAss ...
- 【Kettle】作业和转换中的内置变量
在作业和转换参数中使用Kettle内置变量,可以更方便的工作.下面是Kettle中常用的内置变量: 变量 描述 Internal.Kettle.Version 这是kettle的版本号,比如4.0.0 ...
- Perl常用的内置变量
先来一个例子吧 #!/usr/bin/perl usewarnings; @array =qw(a b c d); foreach(@array) { print$_,"\n"; ...
- awk 内置变量与自定义变量
点击上方"生信科技爱好者",马上关注真爱,请置顶或星标 作者:ghostwu 原文:https://www.cnblogs.com/ghostwu/p/9085653.html A ...
最新文章
- 如何强制Visual Studio重新生成aspx / ascx文件的.designer文件?
- 大一大专计算机考试题型,大专,计算机一级考试考什么内容,麻烦详细点,谢谢。...
- zbb20180415 cs 1.6 half-life launcher已停止工作
- midl会议_2020年医学图像处理领域值得关注的期刊和会议
- leetcode刷题:求容器中能乘最大多少水
- python的数组怎么用_python数组的使用
- 计算机械功的公式,机械功率计算公式
- 数控铣床法兰克系统代码完整版
- R语言-聚类分析(系统聚类)
- 19春学期《计算机应用基础》123,[东北大学]20春学期《计算机应用基础》在线平时作业123(参考答案)...
- rsync简介及部署
- Android知乎广告效果
- 苹果商城怎么调成中文_深入探讨:承德洋葱电商平台怎么开店
- Objective-C 属性
- C++练习小写变大写
- Java 遍历HashMap详解
- Datawhale组队学习周报(第027周)
- ES6学习笔记2:字符串的repeat()方法
- 大数据在线分析处理和常用工具
- Latex, overleaf 输入中文 可行方法
热门文章
- 很雷很有财也很搞笑的笔试答题
- [洪流学堂]Hololens开发:Unity3d与Visual Studio最佳实践
- 分享一个基于Vue的家谱图/组织结构图实现方案
- 【小沐学NLP】Python实现图片文字识别
- CDH启用kerberos认证问题导致GSS initiate failed
- 一般英文论文的大体结构
- 图片报道:2008年12月4日夜晚,暴风雪突袭烟台(上)
- idea 超实用的插件
- kafka Process ‘command ‘/jdk1.8.0_77/jre/bin/java.exe finished with non-zero exit value 1
- 艺展中国-一代名家刘泽仲作品展