WebGL笔记: 2D和WebGL坐标系对比和不同的画图方式, 程序对象通信,顶点着色器,片元着色器

2023-09-19 12:57:52

WebGL 坐标系

  • canvas2d画布和webgl画布使用的坐标系都是二维直角坐标系,但它们坐标原点、y 轴的坐标方向,坐标基底都不一样
  • canvas2d
    • 坐标系的原点在左上角, x轴朝右,y轴朝下
    • 1个单位的宽就是一个像素的宽,1个单位的高就是一个像素的高,都是按像素来走
  • webgl
    • 坐标系的原点在画布中心,x轴朝右,y轴朝上
    • 1个单位的宽是画布宽度的一半,1个单位的高就是画布高度的一半

Canvas2D 画图示例

// canvas画布
const canvas = document.getElementById('canvas');
// 二维画笔
const ctx = canvas.getContext('2d');
// 设置画笔的颜色
ctx.fillStyle = 'red';
// 用画笔画一个矩形
ctx.fillRect(100, 100, 300, 200);

WebGL 画出一个点

  • webgl并不是基于js来绘制,而是基于专业的三维图形渲染引擎来绘制,也就是 GLSL ES 语言来实现三维绘制
  • 在webgl中我们使用js来编程, 基于一个 “程序对象” 的概念来和 GLSL ES 语言 进行通信
<canvas id="canvas"></canvas>

<!-- 顶点着色器 -->
<script id="vertexShader" type="x-shader/x-vertex">
  void main() {
    gl_Position = vec4(0,0,0,1); // 设置点位, 注意webgl坐标系中的单位
    gl_PointSize = 50.0; // 设置尺寸
  }
</script>

<!-- 片元着色器 -->
<script id="fragmentShader" type="x-shader/x-fragment">
  void main() {
    gl_FragColor = vec4(1,1,0,1); // 黄色
  }
</script>

<!-- js脚本 -->
<script type="module">
  import { initShaders } from "./utils.js";

  const canvas = document.querySelector("#canvas");
  canvas.width = 200;
  canvas.height = 200;

  // 获取着色器文本,这里就是上述我们写的GLSL ES语言着色器代码
  const vsSource = document.querySelector("#vertexShader").innerText;
  const fsSource = document.querySelector("#fragmentShader").innerText;

  //三维画笔
  const gl = canvas.getContext("webgl");

  // 初始化着色器
  // 功能:解析着色器文本,整合到程序对象里,关联webgl上下文对象,实现两种语言的相互通信
  initShaders(gl, vsSource, fsSource);

  // 刷颜色
  gl.clearColor(0, 0, 0, 1);
  gl.clear(gl.COLOR_BUFFER_BIT);

  // 绘制顶点 以点来画
  gl.drawArrays(gl.POINTS, 0, 1);
</script>

工具脚本 util.js

export function initShaders(gl, vsSource, fsSource) {
  // 创建程序对象
  const program = gl.createProgram();
  // 建立着色对象
  const vertexShader = loadShader(gl, gl.VERTEX_SHADER, vsSource);
  const fragmentShader = loadShader(gl, gl.FRAGMENT_SHADER, fsSource);
  // 把顶点着色对象装进程序对象中
  gl.attachShader(program, vertexShader);
  // 把片元着色对象装进程序对象中
  gl.attachShader(program, fragmentShader);
  // 连接webgl上下文对象和程序对象
  gl.linkProgram(program);
  // 启动程序对象
  gl.useProgram(program);
  // 将程序对象挂到上下文对象上
  gl.program = program;
  return true;
}

function loadShader(gl, type, source) {
  // 根据着色类型,建立着色器对象
  const shader = gl.createShader(type);
  // 将着色器源文件传入着色器对象中
  gl.shaderSource(shader, source);
  // 编译着色器对象
  gl.compileShader(shader);
  // 返回着色器对象
  return shader;
}
  • 着色器语言就是 GLSL ES 语言, 不是JS语言
  • 顶点着色器(Vertex shader):描述顶点的特征,如位置、颜色等
    • 是绘图的框架,类似于html(不恰当的比喻)
    • 顶点着色器里的顶点就是补间动画里的关键帧
    • 顶点着色器里的顶点就是决定这一条直线的两个点
    • 顶点着色程序,要写在type=“x-shader/x-vertex” 的script中
    • 在顶点着色器中,gl_Position 是顶点的位置,gl_PointSize 是顶点的尺寸,这种名称都是固定写法
    • vec4() 是一个4维矢量对象, 将vec4() 赋值给顶点点位gl_Position 的时候,其中的前三个参数是x、y、z,第4个参数默认1.0,
  • 片元着色器(Fragment shader):进行逐片元处理,如光照
    • 是绘图的装饰,类似于css(不恰当的比喻), 片元着色器不会给顶点着色,而是给顶点间的片元着色
    • 片元着色器里的片元就是关键帧之间以某种算法算出的插值, 举个例子,就像是把直线画到画布上后,这两个点之间构成直线的每个像素
    • 在webgl里的片元是像素的意思
    • 片元着色程序,要写在type=“x-shader/x-fragment” 的script中
    • 在片元着色器中,gl_FragColor 是片元的颜色
  • 注意:
    • void main() {…… } 是主体函数
    • gl_Position, gl_PointSize, gl_FragColor 是固定写死的着色器语言变量
    • 将vec4() 赋值给片元颜色gl_FragColor 的时候,其中的参数是r,g,b,a
    • 上述 util.js 中的执行顺序,就是webgl必须要实现的逻辑
  • drawArrays
更多推荐

Java版分布式微服务云开发架构 Spring Cloud+Spring Boot+Mybatis 电子招标采购系统功能清单

项目说明随着公司的快速发展,企业人员和经营规模不断壮大,公司对内部招采管理的提升提出了更高的要求。在企业里建立一个公平、公开、公正的采购环境,最大限度控制采购成本至关重要。符合国家电子招投标法律法规及相关规范,以及审计监督要求;通过电子化平台提高招投标工作的公开性和透明性;通过电子化招投标,使得招标采购的质量更高、速度

Linux内核顶层Makefile的make过程总结

一.Linux内核源码的make编译本文对Linux内核源码的make时,顶层Makefile所做的事进行总结。即总结一下Linux内核源码的make过程。本文续上一篇文章,地址如下:Linux内核顶层Makefile的make过程说明二_凌肖战的博客-CSDN博客二.Linux的make过程总结之前几篇文章,分析了L

Pikachu Burte Force(暴力破解)

一、BurteForce(暴力破解)概述​“暴力破解”是一攻击具手段,在web攻击中,一般会使用这种手段对应用系统的认证信息进行获取。其过程就是使用大量的认证信息在认证接口进行尝试登录,直到得到正确的结果。为了提高效率,暴力破解一般会使用带有字典的工具来进行自动化操作。​理论上来说,大多数系统都是可以被暴力破解的,只要

【Vue】快速入门和生命周期

目录前言一、vue的介绍1.Vue.js是什么?2.库和框架的区别3.基本概念和用法:二、MVVM的介绍1.什么是MVVM?2.MVVM的组成部分3.MVVM的工作流程4.MVVM的优势5.MVVM的应用场景三、vue实例1.模板语法:2.双向数据绑定3.虚拟dom实例四、vue生命周期钩子总结前言Vue.js是一款流

数据在C++中的大小(占用内存)

C++中的大小(占用内存)摘要正文获取数据类型的大小注意结论摘要在C++中,了解数据类型的大小及其在内存中的占用情况对于编写高效的代码至关重要。本文将介绍C++中不同数据类型的大小以及如何计算它们所占用的内存空间。正文在C++中,每个数据类型都有不同的字节大小,这取决于编译器和操作系统的实现。下面是一些常见的数据类型及

fastjson反序列化漏洞(CVE-2017-18349)

文章目录fastjson序列化FastJson序列化操作反序列化漏洞原理漏洞复现(CVE-2017-18349)fastjsonfastjson是阿里巴巴开发的java语言编写的高性能JSON库,用于将数据在Json和JavaObject之间相互转换。它没有用java的序列化机制,而是自定义了一套序列化机制。提供两个主

Open Interpreter,一个让ChatGPT入驻你的电脑并获得联网能力成为贾维斯!

OpenInterpreter,一个让ChatGPT入驻你的电脑并获得联网能力成为贾维斯!介绍安装使用介绍最近看了Github最近大火的程序员终端大升级,发现了openinterpreter这个可以部署到本地命令行的对话AI,其依赖ChatGPT,可以使用联网功能和本地模型,很好地拓展了原有的功能并且能结合物理设备软硬

勇立潮头!高品质SFT语音数据实现Zero-Shot语音复刻大模型

文本到语音合成(TexttoSpeech,TTS)作为生成式人工智能(GenerativeAI或AIGC)的重要课题,在近年来取得了飞速发展。为了实现高效合成既自然又高质量的人类语音,有不少机构及企业都进行了相关项目的研究,包括微软亚洲研究院机器学习组和微软Azure语音团队去年推出的NaturalSpeech(htt

企业微信 API 接口调用教程:图文详解企业微信 API 的使用方法

本文通过access_token凭证的方式来讲解怎么调用企业微信API,并一步步介绍如何获取企业微信API的corpsecret、corpid、access_token凭证以及怎么向企业微信的应用发送消息。企业微信API在线地址为:概述-企业微信API,这个在线地址的项目你可以克隆到Apifox,以方便调试。话不多说,

基于深度学习的加密恶意流量检测

加密恶意流量检测研究目标定位数据收集数据处理基于特征分类算法的数据预处理基于源数据分类算法的数据预处理特征提取模型选择基于数据特征的深度学习检测算法基于特征自学习的深度学习检测算法训练和评估精确性指标实时性指标应用检验改进摘录自:MingfangZHAI,XingmingZHANG,BoZHAO.Surveyofenc

应用在苹果应用商店该如何进行优化

众所周知,ASO最大化的提高应用程序在商店中的可见性,其目标是获得更多的下载量,同时它也与下载的转化率有关。1、根据应用阶段追求不同的目标。它可以是有机增长或转化率的提高,获得更多安装并降低用户获取成本,增加收入或提高保留率,达到一定的参与水平或提高每日或每月活跃用户。2、应用的文本字段。应用名称需要包含一些主要关键词

热文推荐