初级入门 --- web GL绘制点

万丈高楼平地起。

01基础知识

一、相关术语

  • 图元 :WebGL 能够绘制的基本图形元素,包含三种:线段三角形

  • 片元:可以理解为像素,像素着色阶段是在片元着色器中。
  • 裁剪坐标系:裁剪坐标系是顶点着色器中的 gl_Position 内置变量接收到的坐标所在的坐标系。
  • 设备坐标系:又名 NDC 坐标系,是裁剪坐标系各个分量对 w 分量相除得到的坐标系,特点是 x、y、z 坐标分量的取值范围都在 【-1,1】之间,可以将它理解为边长为 2 的正方体,坐标系原点在正方体中心。

二、GLSL


  • gl_Position:内置变量,用来设置顶点的裁剪坐标系坐标,包含 X, Y, Z,W 四个坐标分量。顶点着色器接收到这个坐标之后,对它进行透视除法,即将各个分量同时除以 W,转换成 NDC 坐标,NDC 坐标每个分量的取值范围都在【-1, 1】之间,GPU 获取这个属性值作为顶点的最终位置进行绘制。

  • gl_PointSize:内置变量,用来设置顶点大小。只有在绘制图元是的时候才会生效。
  • gl_FragColor:片元(像素)颜色,包含 R, G, B, A 四个颜色分量,且每个分量的取值范围在【0,1】之间,GPU 获取这个值作为像素的最终颜色进行着色。
  • gl_FragColor:内置变量,用来设置像素颜色。
  • attribue 变量:只能在顶点着色器中定义。
  • uniform 变量:既可以在顶点着色器中定义,也可以在片元着色器中定义。
  • 最后一种变量类型 varing 变量:它用来从顶点着色器中往片元着色器传递数据。使用它我们可以在顶点着色器中声明一个变量并对其赋值,经过插值处理后,在片元着色器中取出插值后的值来使用。
  • vec4:4 维向量,包含四个浮点元素的容器类型,vec 是 vector(向量)的单词简写,vec4 代表包含 4 个浮点数的向量。此外,还有 vec2vec3 等类型,代表包含2个或者3个浮点数的容器。
  • precision:精度设置限定符,使用此限定符设置完精度后,之后所有该数据类型都将沿用该精度,除非单独设置。
  • 运算符:向量的对应位置进行运算,得到一个新的向量。
    • vec * 浮点数:vec2(x, y) * 2.0 = vec(x * 2.0, y * 2.0)。

    • vec2 * vec2:vec2(x1, y1) * vec2(x2, y2) = vec2(x1 * x2, y1 * y2)。
    • 加减乘除规则基本一致。但是要注意一点,如果参与运算的是两个 vec 向量,那么这两个 vec 的维数必须相同。

GLSL 中 gl_Position 所接收的坐标所在坐标系是裁剪坐标系 ,不同于我们的浏览器窗口坐标系。所以当我们赋予 gl_Position 位置信息的时候,需要对其进行转换才能正确显示。

三、JAVASCRIPT程序如何向连接着色器程序


  • createShader:创建着色器对象

  • shaderSource:提供着色器源码
  • compileShader:编译着色器对象
  • createProgram:创建着色器程序
  • attachShader:绑定着色器对象
  • linkProgram:链接着色器程序
  • useProgram:启用着色器程序

四、JAVASCRIPT如何往着色器中传递数据


  • getAttribLocation:找到着色器中的 attribute 变量地址。

  • getUniformLocation:找到着色器中的 uniform 变量地址。
  • vertexAttrib2f:给 attribute 变量传递两个浮点数。
  • uniform4f:给uniform变量传递四个浮点数。

五、WebGL 绘制函数


  • drawArrays: 用指定的图元进行绘制。

gl.drawArrays 是执行绘制的 API,上面示例中的第一个参数 gl.POINTS 代表我们要绘制的是点图元,第二个参数代表要绘制的顶点的起始位置,第三个参数代表顶点绘制个数。

六、WebGL 图元


  • gl.POINTS: 将绘制图元类型设置成点图元

02代码

<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <title>WebGL 绘制点</title>    <script type="x-shader/x-vertex" id="vertexShader">        //设置浮点数精度为中等精度        precision mediump float;        // 接收点在canvas坐标系上的坐标(x,y)        attribute vec2 a_Position;        // 接受canvas 的宽高尺寸        attribute vec2 a_Screen_Size;        void main(){            //start 将屏幕坐标系转化为裁剪坐标(裁剪坐标系)            vec2 position = (a_Position / a_Screen_Size) * 2.0 - 1.0;            position = position * vec2(1.0, -1.0);            gl_Position = vec4(position, 0.0, 1.0);            //end 将屏幕坐标系转化为裁剪坐标(裁剪坐标系)            //声明要绘制的点的大小。            gl_PointSize = 10.0;        }    </script>    <script type="x-shader/x-fragment" id="fragmentShader">        //设置浮点数精度为中等精度        precision mediump float;        //接收 JavaScript 传过来的颜色值(RGBA)。        uniform vec4 u_Color;        void main(){            //将普通的颜色表示转化为 WebGL 需要的表示方式,即将【0-255】转化到【0,1】之间。            vec4 color = u_Color / vec4(255, 255, 255, 1);            gl_FragColor = color;        }    </script></head><body><canvas id="canvas"></canvas></body></html><script>    function createShaderFromScript(gl, mode, id) {        // 获取着色器源码        var shaderSource = document.getElementById(id).innerHTML;        // 创建着色器对象        var shader = gl.createShader(mode);        // 将源码分配给着色器对象        gl.shaderSource(shader,shaderSource);        // 编译着色器        gl.compileShader(shader);

return shader;    }    function createProgram(gl, vertexShader, fragmentShader) {        var program = gl.createProgram();        // 将顶点着色器挂载在着色器程序上。        gl.attachShader(program, vertexShader);        //将片元着色器挂载在着色器程序上。        gl.attachShader(program, fragmentShader);        //链接着色器程序        gl.linkProgram(program);

return program;    }

var canvas = document.getElementById(‘canvas‘);    var gl = canvas.getContext(‘webgl‘) || canvas.getContext("experimental-webgl");

<!--region 创建着色器对象-->    var vertexShader = createShaderFromScript(gl, gl.VERTEX_SHADER, ‘vertexShader‘);    var fragmentShader = createShaderFromScript(gl, gl.FRAGMENT_SHADER, ‘fragmentShader‘)    <!--endregion-->

<!--region 创建着色器程序-->    //创建着色器程序    let program = createProgram(gl, vertexShader, fragmentShader);

// 使用刚刚创建好的着色器程序    gl.useProgram(program);    <!--endregion-->

//找到顶点着色器中的变量a_Position    var a_Position = gl.getAttribLocation(program, ‘a_Position‘);    //找到顶点着色器中的变量a_Screen_Size    var a_Screen_Size = gl.getAttribLocation(program, ‘a_Screen_Size‘);    //找到片元着色器中的变量u_Color    var u_Color = gl.getUniformLocation(program, ‘u_Color‘);    //为顶点着色器中的 a_Screen_Size 传递 canvas 的宽高信息    gl.vertexAttrib2f(a_Screen_Size, canvas.width, canvas.height);    //存储点击位置的数组。    var points = [];    function randomColor(){        return {            r: Math.ceil(Math.random() * 255),            g: Math.ceil(Math.random() * 255),            b: Math.ceil(Math.random() * 255),            a: Math.ceil(Math.random()),        };    }    canvas.addEventListener(‘click‘,e=>{        var x = e.pageX;        var y = e.pageY;

var color = randomColor();

points.push({x,y,color});        gl.clearColor(0, 0, 0, 1.0);        //用上一步设置的清空画布颜色清空画布。        gl.clear(gl.COLOR_BUFFER_BIT);

for (let i = 0; i < points.length; i++) {            let color = points[i].color;            gl.uniform4f(u_Color, color.r, color.g, color.b, color.a);            //为顶点着色器中的 a_Position 传递顶点坐标。            gl.vertexAttrib2f(a_Position, points[i].x, points[i].y);

// 绘制点            gl.drawArrays(gl.POINTS, 0, 1);        }    })

//设置清空画布颜色为黑色。    gl.clearColor(0.0,0.0,0.0,1.0);    //用上一步设置的清空画布颜色清空画布。    gl.clear(gl.COLOR_BUFFER_BIT);

</script>

vec2 position = (a_Position / a_Screen_Size) * 2.0 - 1.0

上面这句代码用来将浏览器窗口坐标转换成裁剪坐标,之后通过透视除法,除以 w 值(此处为 1 )转变成设备坐标(NDC坐标系)。这个算法首先将(x,y) 转化到【0, 1】区间,再将 【0, 1】之间的值乘以 2 转化到 【0, 2】区间,之后再减去 1 ,转化到 【-1, 1】之间的值,即 NDC 坐标

原文地址:https://www.cnblogs.com/yaoyinglong/p/12250865.html

时间: 2024-10-16 14:49:40

初级入门 --- web GL绘制点的相关文章

响应式Web初级入门

本文来自我的前端博客,原文地址:http://www.hacke2.cn/about-responsive/ 跨终端时代的到来 当你乘坐各种交通工具(公交.地铁.轻轨.火车)时你会发现,人们都个个低下头在玩自己的手机.平板.Kindle,没错,你正在处于一个多终端设备的时代!手机用户连年上升,前几天我们在感叹以前玩沙包.陀螺,现在小孩的娱乐就是玩手机–.另外,微软的Xbox和任天堂的Wii等游戏设备也有自己的浏览器.设备真的来了.. 现在网站主流跨终端的有以下方式: 单域 比如前端乱炖和我的个人

零基础快速入门web学习路线(含视频教程)

下面小编专门为广大web学习爱好者汇总了一条完整的自学线路:零基础快速入门web学习路线(含视频教程)(绝对纯干货)适合初学者的最新WEB前端学习路线汇总! 在当下来说web前端开发工程师可谓是高福利.高薪水的职业了.所以现在学习web前端开发的技术人员也是日益增多了,但是在学习web前端开发中盲目的去学习而没有一个完整的思路和学习路线也是不行的. 成为一个合格的web前端开发工程师的具备什么条件? 熟练的掌握HTML.CSS.JS.JQ等最基本的技术. 现在,只掌握这些已经远远不够了.无论是开

功能测试转型必备课程 零基础入门Web自动化测试

第1章 课程介绍本章主要对整个课程简单介绍,并且把学习过程中会经常遇见的问题进行讲解. 第2章 手工测试转型自动化测试必备技能本章讲解从手工测试转型自动化测试必须掌握的一些知识,学会的技能点,以及从思想的转变到框架的了解,让初级学者对自动化测试不再迷茫,轻松学习起来. 第3章 从功能测试角度出发讲解自动化测试selenium基础本章通过功能测试分析到自动化测试的转变,从功能角度出发,讲解自动化selenium的基本知识,让你真的把浏览器操作起来,进一步的了解自动化测试. 第4章 HTML基础定位

初学者入门web前端 C#基础知识:数组与集合

对于初学者,想要入门web前端,要有足够的信念和坚持,不然只会越走越远,我现在就深深的体会到. 我本是一个很拒绝代码的人,以前想过UI设计,但是在这段学习时间里,发现其实只要认真,代码并不是很难 所以我整理了一套前期学C#的知识点,对于后期学习JavaScript有很大的帮助. 一.数组与集合数组:能存放任意多个同类型的数据 数据项:类型相同 ①每一个数据型都有一个编号(索引或下标) ②数据的索引(下标)是一个int类型的数字 ③从0开始,依次为数据中每一个数组项编号 数组的声明与赋值 声明:数

Asp组件初级入门与精通系列之七

在运行前几章的例子,可能或多或少的都会碰上一些问题 如:组件编译后,又要修改,发生"权限被拒绝,'f:\csdn\fcom.dll'"等等的错误. 当asp页面浏览时,打开任务管理器,会看到一个dllhost.exe,用户名为IWAM_YANG的进程.IWAM_YANG会根据计算机名而有所不同. 可以使用以下几种方式来解决 1. 重新启动iis. 在控制面板中找到管理工具->internet信息服务->右键点击左边树图第二层本地计算机->所有任务->重新启动II

Spring Cloud实战之初级入门(四)— 利用Hystrix实现服务熔断与服务监控

目录 1.环境介绍 2.服务监控 2.1 加入依赖 2.2 修改配置文件 2.3 修改启动文件 2.4 监控服务 2.5 小结 3. 利用hystrix实现消费服务熔断 3.1 加入服务熔断 3.2 测试服务熔断 4. 利用turbine监控所有应用 4.1 创建工程 4.2 修改配置文件 4.3 修改启动文件 4.4 启动 5.一点点重要的事情 1.环境介绍 本篇文章涉及到前面文章的工程,mirco-service-provider.mirco-service-consumer以及需要另外新建

2019Python开发学习路线(初级入门)

Python虽然是脚本语言,但是因为容易学,迅速成为科学家的工具,从而积累了大量的工具库.架构,人工智能涉及大量的数据计算,用Python是很自然的,简单高效.因此Python大受欢迎,2019Python开发学习路线(初级入门)免费送给大家:Python允许你分割你的程序模块,可以重复使用在其他Python程序上.它配备了一个标准的模块,你可以使用你的程序的基础 - 或作为例子开始学习Python编程的大集合.这些模块提供了一些事情,如文件I / O,系统调用,插座,甚至像Tk图形用户界面接口

Jeecg 初级入门

Jeecg 初级入门 1.部署jeecg 1.1.下载jeecg 请在jeecg 发布地址下载jeecg工程 1.2 导入myeclipse8.5 按照如下视图选择jeecg项目存放路径然后导入项目工程 1.3jeecg工程结构 1.4 相关配置文件说明 0)framemark 模版文件以及配置文件 1) CKfinderConfig.xml 富文本框配置文件 2)dbconfig.properties 数据库配置文件 3)  ehcache.xml 缓存配置文件 4) log4j 配置文件 5

极客学院Web前端开发技术实战视频教程 初级入门+高级实战++专家课程+面试指导

===============课程目录=============== ├<初级中级>│  ├<1. HTML5开发前准备>│  │  ├1.HTML5开发前准备.mp4│  │  └2.开发前的准备-快捷键.mp4│  ├<10. React.js>│  │  ├React.js简介.txt│  │  ├<1.React 概述>│  │  │  ├React 开发环境搭建.mp4│  │  │  ├编写第一个 React 程序.mp4│  │  │  └什么