webgl之helloworld
从今天开始,正式进入webgl的世界,正式由一个写C++,C#,java的码农转变成写前端的码农。还是有那么一点点兴奋。
这是webgl的第一篇博客,主要通过webgl绘制一个三角形。
调用流程:
1 | 获取webgl上下文 |
2 | 获取着色器字符串 |
3 | 创建,加载,编译着色器 |
4 |
给着色器的变量赋值 |
5 | 绘制图形 |
效果图:
详细步骤:
步骤一:获取webgl上下文,并告诉webgl作用的空间大小,设置画布的默认值为黑色
// 获取WebGL上下文var canvas = document.getElementById("canvas");var gl = canvas.getContext("webgl");if (!gl) {return;}// 告诉WebGL怎样把提供的gl_Position裁剪空间坐标对应到画布像素坐标(屏幕空间)gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);// 清空画布gl.clearColor(0, 0, 0, 1);gl.clear(gl.COLOR_BUFFER_BIT);
步骤二:获取着色器字符串,这里主要分为两个阶段,第一个阶段,定义着色器,第二个阶段 获取着色器字符串
着色器需要定义定点着色器和片元着色器
定点着色器定义如下:主要实现对坐标点位置的设置
<script id="2d-vertex-shader" type="notjs">// 一个属性值,将会从缓冲中获取数据attribute vec4 a_position;// 所有着色器都有一个main方法void main() {// gl_Position 是一个顶点着色器主要设置的变量gl_Position = a_position;}</script>
片元着色器定义如下,主要设置渲染的颜色
<script id="2d-fragment-shader" type="notjs">// 片断着色器没有默认精度,所以我们需要设置一个精度// mediump是一个不错的默认值,代表“medium precision”(中等精度)precision mediump float;void main() {// gl_FragColor是一个片断着色器主要设置的变量gl_FragColor = vec4(1, 0, 0.5, 1); // 返回“瑞迪施紫色”}</script>
最后在js代码里面,获取着色器字符串
// 获取着色器字符串var vertexShaderSource = document.getElementById("2d-vertex-shader").text;var fragmentShaderSource = document.getElementById("2d-fragment-shader").text;
步骤三:创建程序,加载,编译,连接着色器
创建一个着色器的公共函数:
function createShader(gl, type, source) {var shader = gl.createShader(type);// 创建着色器对象gl.shaderSource(shader, source);// 提供数据源gl.compileShader(shader);// 编译 -> 生成着色器var success = gl.getShaderParameter(shader, gl.COMPILE_STATUS);if (success) {return shader;}console.log(gl.getShaderInfoLog(shader));gl.deleteShader(shader);}
创建定点着色器和片元着色器
// 创建,加载,编译着色器var vertexShader = createShader(gl, gl.VERTEX_SHADER, vertexShaderSource);var fragmentShader = createShader(gl, gl.FRAGMENT_SHADER, fragmentShaderSource);
把定点着色器和片元着色器link到着色程序,这里写成一个公共函数
// 然后我们将这两个着色器 link(链接)到一个 program(着色程序)function createProgram(gl, vertexShader, fragmentShader) {var program = gl.createProgram();//创建着色程序gl.attachShader(program, vertexShader);// 附加顶点着色器gl.attachShader(program, fragmentShader);// 附加片元着色器gl.linkProgram(program);//链接到着色程序var success = gl.getProgramParameter(program, gl.LINK_STATUS);//判断着色程序是否创建成功if (success) {return program;}console.log(gl.getProgramInfoLog(program));gl.deleteProgram(program);}
在js代码中,链接到着色程序以及告诉webgl使用这个着色程序
// 链接连个着色器到着色程序var program = createProgram(gl, vertexShader, fragmentShader);// 告诉它用我们之前写好的着色程序(一个着色器对)gl.useProgram(program);
第四步:给着色器的变量赋值,这里主要是给定点变量赋值
下面代码功能为:获取变量a_position,定义一个数组,有3个点,再把数据放置到webgl的缓冲区,通过函数vertexAttribPointer告诉程序如何从缓冲区获取数据。最后启用属性
// 从刚才创建的GLSL着色程序中找到a_position属性值所在的位置var positionAttributeLocation = gl.getAttribLocation(program, "a_position");// 三个二维点坐标var positions = new Float32Array([0, 0, 0, 0.5,0.7, 0,]);// 属性值从缓冲中获取数据,所以我们创建一个缓冲var positionBuffer = gl.createBuffer();// 绑定位置信息缓冲(下面的绑定点就是ARRAY_BUFFER)gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);gl.bufferData(gl.ARRAY_BUFFER, positions, gl.STATIC_DRAW);// 告诉属性怎么从positionBuffer中读取数据 (ARRAY_BUFFER)var size = 2; // 每次迭代运行提取两个单位数据var type = gl.FLOAT; // 每个单位的数据类型是32位浮点型var normalize = false; // 不需要归一化数据var stride = positions.BYTES_PER_ELEMENT*2; // 0 = 移动单位数量 * 每个单位占用内存(sizeof(type))每次迭代运行运动多少内存到下一个数据开始点var offset = 0; // 从缓冲起始位置开始读取gl.vertexAttribPointer(positionAttributeLocation, size, type, normalize, stride, offset);// 启用对应属性gl.enableVertexAttribArray(positionAttributeLocation);
第五步:绘制图像,这里绘制一个三角形,一共3个点。
// 绘制var primitiveType = gl.TRIANGLES;var offset = 0;var count = 3;gl.drawArrays(primitiveType, offset, count);
webgl之helloworld相关推荐
- 【超图】SuperMap iClient3D 11i for WebGL新产品食用指南(一)
作者:taco 前言: 为了做到日更博主,或者周更博主.准备开一个新坑来提高我的动力.使用超图的webgl产品也大概有一两年左右了,就在前两天看到超图官网更新了新版本的webgl产品,肯定是马不停蹄就 ...
- 【ThreeJS基础教程-初识Threejs】1.ThreeJS的HelloWorld
ThreeJS的HelloWorld 学习ThreeJS的捷径 杂项 第一个案例 案例效果 案例解析 引入threejs 创建一个场景(演出舞台) 创建相机(摄影师) 创建一个渲染器(相片处理) 创建 ...
- HTML5 学习总结(四)——canvas绘图、WebGL、SVG
目录 一.Canvas 1.1.创建canvas元素 1.2.画线 1.3.绘制矩形 1.4.绘制圆弧 1.5.绘制图像 1.6.绘制文字 1.7.随机颜色与简单动画 二.WebGL 2.1.HTML ...
- Babylonjs入门01——HelloWorld及babylon获取
Babylonjs入门01-HelloWorld 1 介绍 2 Babylonjs的HelloWorld 2.1 Playgroud 2.2 在自己的HTML中使用Babylonjs 3 获取Baby ...
- webgl 实现地球月球绕转(时间原因有内存泄漏问题后续优化)带阴影雾化光照效果
代码纯webgl原生实现 <!DOCTYPE html> <html><head><meta charset="UTF-8">< ...
- mysql cesium_Cesium案例解析(一)——HelloWorld
1. 概述 感觉网上已经有不少关于cesium的教程了,但是学习一个框架最快的办法就是熟悉其自带的实例了.cesium网站上提供了一系列实例,就想通过这些实例总结下学习cesium的知识:当然,如果有 ...
- Docker安装Apache与运行简单的web服务——httpd helloworld
Docker运行简单的web服务--httpd helloworld目录[阅读时间:约5分钟] 一.Docker简介 二.Docker的安装与配置[CentOS环境] 三.Docker运行简单的web ...
- CentOS Docker安装配置部署Golang web helloworld
目录[阅读时间:约5分钟] 一.Docker简介 二.Docker的安装与配置[CentOS环境] 三.Docker部署Golang web helloworld 四.Docker与虚拟机的区别 五. ...
- 简单图文配置golang+vscode【win10/centos7+golang helloworld+解决install failed等情况】
博客目录(阅读时间:10分钟) 一.win10 0.系统环境 1. win10配置golang环境 ①下载相关软件 ②创建gowork工作空间 ③配置环境变量(GOPATH+PATH) ④验证环境配置 ...
最新文章
- 如何画出高级酷炫的神经网络图?优秀程序员都用了这几个工具
- re管理器Java_自定义布局管理器-FormLayout
- mysql日志管理_关于MySQL的日志管理(binlog)
- 【论文写作】毕业论文中容易栽的九个坑
- 发布一个MsBuild任务组件-可用于同时发布多个网站
- Ubuntu16.04 使用小米WiFi 变无线网卡
- MySQL、SQLyog、navicat安装
- JavaWeb之HttpSession
- 安徽 计算机一级考试题库,计算机一级考试题库和答案
- Java进制转换工具类
- CNN卷积神经网络原理讲解+图片识别应用(附源码)
- 5G新方案!升级现有的基站和UE模拟器至5G毫米波频段
- aso优化师是什么_来肯云商app官网下载_做ASO优化师,只懂刷榜就够了吗
- 2022年6月编程语言排行,第一名居然是它?!
- 如何在C加加的面向对象写游戏 我的世界
- 硬核数据处理笔记本推荐(2023版)
- stata画时间趋势图时横坐标标签太长重叠怎么办
- 对于M1卡密钥控制字设置的总结
- spark入门案例以及sbt安装与打包(Linux环境)
- 天边一朵云-徒手用html生成一朵云,很真的那种
热门文章
- SQL Server创建计划任务
- 如何写文章,如何说话
- .NET 6 Preview 5 终于发布
- 开源大数据:Databricks Lakehouse
- Spring Boot 的 GraphQL 框架DGS
- 本地缓存到分布式缓存( Guava, Caffeine, Memcached, Redis)
- 10个最棒的jQuery视频插件
- MySQL 主键相关操作
- oracle clob 粘贴,使用Oracle SQL Developer将CLOB导出到文本文件
- 弱网测试用什么农_弱网测试--使用fiddler进行弱网测试