当前位置: 首页 > news >正文

WebGL笔记:矩阵的变换之平移的实现

矩阵的变换

变换

  • 变换有三种状态:平移旋转缩放
  • 当我们变换一个图形时,实际上就是在移动这个图形的所有顶点。
  • 解释
    • webgl 要绘图的话,它是先定顶点的,就比如说我要画个三角形,那它会先把这三角形的三个顶点定出来。
    • 然后它再考虑以什么样的方式去绘制这个三角形, 就比如说在 gl.drawArrays(gl.TRIANGLES, 0, 3) 这个方法
      • 第一个参数是 TRIANGLES,让它画一个独立三角形,我依次连接这三个点,然后逐片元给它们填充颜色
      • 接下来我就可以对三角形进行变换操作了,比如:旋转,缩放,平移。
      • 我在做这三种操作的时候,实际上就是改变了三角形的顶点位置

平移

  • 对图形的平移啊,就是对图形所有顶点的平移

  • 举个简单的例子

    • 就比如说已知点p的位置是(x,y,z)
    • 那我要对它进行一个相对的移动,
    • 移动的三个分量分别是 tx, ty, tz, 那么求它移动完之后的位置 p’ (x’, y’, z’)
    • 只要让它这三个分量做加法就可以了
  • 即,如下图

    x'=x+tx
    y'=y+ty
    z'=z+tz
    

  • 如果上面这个图形中并非只有一个顶点,而是三个顶点或者更多,那么所有的顶点也是按同样的原理去进行位移的
  • 就比如下面这个图这个三角形在位移的时候啊,其实上也就是它的所有顶点去做一个相对的位移

向量的加法

  • 在实际的编码中,要有一个向量的概念。
  • 就比如说 (x,y,z) 这三个量可以构成一个三维点位
  • 我们可以说它是一个顶点位置,也可以说它是一个向量, 至于这个 (x,y,z) 到底是什么?我们要看它是要做什么的
  • 就比如说我把点p(x,y,z)作为点位的时候,那它就是个点
  • 如果我把p的移动距离 tx, ty, tz 封装成一个对象 pt(tx,ty,tz), 那么 pt 就是一个向量,一个为点p 指明移动方向和距离的向量
  • 那么,点 p 的移动结果 p’ 就可以这么写:p’ = p + pt
  • 由此可知,顶点的位移,就是向量的加法

编写向量加法代码

  • 在GLSLES语言里,是直接可以进行向量运算的,下面是顶点着色器里的代码:

    attribute vec4 a_Position;
    vec4 translation = vec4(0, 0.2, 0, 0);
    void main() {gl_Position = a_Position + translation;
    }
    
    • a_Position 是原始点位,属于attribute 变量
    • translation 是顶点着色器里的私有变量,没有向外部暴露,属于4维向量
    • a_Position + translation 便是着色器内的向量加法,这里是对原始点位进行位移
  • 基于对初始的这个a_Position 点位进行一个位移的话,那我可以直接让它加上一个四维的向量,就比如这里的这个translation,就是我声明的一个个四四维向量,让它直接加上即可

  • 上述 translation 是写死的 ,我们也可以把 translation 变量暴露出去,让js可以修改图形位置:

    <script id="vertexShader" type="x-shader/x-vertex">attribute vec4 a_Position;uniform vec4 u_Translation;void main() {gl_Position = a_Position + u_Translation;}
    </script>
    
  • 在js 中修改uniform 变量的方法,我们之前已经说过:

    // 获取 uniform 变量
    const u_Translation = gl.getUniformLocation(gl.program, 'u_Translation');
    // 为 uniform 变量赋值
    gl.uniform4f(u_Translation, 0, 0.5, 0, 0);
    
  • 之后,可以加一段逐帧动画:

    let y = 0;
    !(function animate() {y += 0.02;if(y > 1) y = -1;gl.uniform4f(u_Translation, 0, y, 0, 0);gl.clear(gl.COLOR_BUFFER_BIT);gl.drawArrays(gl.TRIANGLES, 0, 3);requestAnimationFrame(animate)
    })()
    


完整代码

<canvas id="canvas"></canvas>
<script id="vertexShader" type="x-shader/x-vertex">attribute vec4 a_Position;uniform vec4 u_Translation;void main() {gl_Position = a_Position + u_Translation;}
</script>
<script id="fragmentShader" type="x-shader/x-fragment">void main() {gl_FragColor = vec4(1.0,1.0,0.0,1.0);}
</script>
<script type="module">// 这里参考之前博文代码import { initShaders } from './util.js';const canvas = document.getElementById('canvas');canvas.width = window.innerWidth;canvas.height = window.innerHeight;const gl = canvas.getContext('webgl');const vsSource = document.getElementById('vertexShader').innerText;const fsSource = document.getElementById('fragmentShader').innerText;initShaders(gl, vsSource, fsSource);const vertices = new Float32Array([0.0, 0.1,-0.1, -0.1,0.1, -0.1])const vertexBuffer = gl.createBuffer();gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);const a_Position = gl.getAttribLocation(gl.program, 'a_Position');gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, 0, 0);gl.enableVertexAttribArray(a_Position);//获取uniform 变量const u_Translation = gl.getUniformLocation(gl.program, 'u_Translation');//为uniform 变量赋值gl.uniform4f(u_Translation, 0, 0.5, 0, 0);gl.clearColor(0.0, 0.0, 0.0, 1.0);gl.clear(gl.COLOR_BUFFER_BIT);gl.drawArrays(gl.TRIANGLES, 0, 3);let y = 0!(function animate() {y += 0.02;if (y > 1) y = -1;gl.uniform4f(u_Translation, 0, y, 0, 0);gl.clear(gl.COLOR_BUFFER_BIT);gl.drawArrays(gl.TRIANGLES, 0, 3);requestAnimationFrame(animate);})()
</script>

相关文章:

WebGL笔记:矩阵的变换之平移的实现

矩阵的变换 变换 变换有三种状态&#xff1a;平移、旋转、缩放。当我们变换一个图形时&#xff0c;实际上就是在移动这个图形的所有顶点。解释 webgl 要绘图的话&#xff0c;它是先定顶点的&#xff0c;就比如说我要画个三角形&#xff0c;那它会先把这三角形的三个顶点定出来…...

XTU-OJ 1187-Candy

WCB某天买了非常多的糖果并把它们分成N份&#xff0c;依次分别有1&#xff0c;2&#xff0c;3…,N个糖果。他想拿出其中的3份分给他的室友&#xff0c; 为了不让室友们闹意见&#xff0c;必须让这三份的糖果总数恰好能被三人均分。请问他一共有多少种不同的组合方案数&#xff…...

基于 nodejs+vue城市轨道交通线路查询系统mysql

目 录 摘 要 I ABSTRACT II 目 录 II 第1章 绪论 1 1.1背景及意义 1 1.2 国内外研究概况 1 1.3 研究的内容 1 第2章 相关技术 3 2.1 nodejs简介 4 2.2 express框架介绍 6 2.4 MySQL数据库 4 第3章 系统分析 5 3.1 需求分析 5 3.2 系统可行性分析 5 3.2.1技术可行性&#xff1a;…...

电商时代,VR全景如何解决实体店难做没流量?

近日&#xff0c;电商和实体经济的对立成为了热门话题&#xff0c;尽管电商的兴起确实对线下实体店造成了一定的冲击&#xff0c;但实体店也不是没有办法挽救。VR全景助力线下实体店打造线上店铺&#xff0c;打通流量全域布局&#xff0c;还能实现打开产品、查看产品内部细节等…...

操作系统-浅谈CPU与内存

目录 计算机的基本组成CPU内存虚拟内存内存分段内存分页 CPU与内存的交互过程高速缓存cache 所有图片均来自&#xff1a;小林coding 计算机的基本组成 计算机由软件和硬件组成 硬件由CPU(中央处理器&#xff09;存储器(内存外存&#xff09;外部设备组成。 软件由应用软件和系…...

K8s 部署 CNI 网络组件+k8s 多master集群部署+负载均衡

------------------------------ 部署 CNI 网络组件 ------------------------------ ---------- 部署 flannel ---------- K8S 中 Pod 网络通信&#xff1a; ●Pod 内容器与容器之间的通信 在同一个 Pod 内的容器&#xff08;Pod 内的容器是不会跨宿主机的&#xff09;共享同一…...

若依微服务上传图片文件代理配置

在使用若依微服务文件上传时候,文件上传成功会上传到D:/ruoyi/uploadPath目录下。默认使用9300端口进行访问图片文件,现在我想把它代理到80端口应该怎么做呢? 配置前:http://localhost:9300/statics/2023/09/24/test.jpg 配置后:http://localhost/statics/2023/09/24/test…...

物联网与 Linux 的相爱相生

Linux 无疑将在物联网中扮演一个关键角色&#xff0c;但是其光彩将与其它的一些分享。 随着 Canonical 重新关注于赢利和新技术&#xff0c;我们中的一些人发现我们正在思考 Linux 未来将走向何方&#xff0c;IoT&#xff08;物联网&#xff09;是否是 Linux 的未来&#xff1…...

python自动化测试(一):操作浏览器

通过Python的代码去操作浏览器的操作 目录 目录 1、导入自动化模块 2、定义打开的浏览器驱动、声明一个url变量保存打开的地址 3、使用函数&#xff1a;driver.get(url)打开浏览器的指定页面 4、最大化浏览器窗口&#xff1a;driver.maximize_window() 5、添加全局的等待…...

NReco.LambdaParser使用案例

使用案例集合&#xff1a; private async void RuleEngine_Click(object sender, EventArgs e){#region 获取变量string expression this.Rule.Text.Trim();string pattern "\$(.*?)\$";MatchCollection matches Regex.Matches(expression, pattern);foreach (Ma…...

苹果IOS安装IPA, plist形式 Safari 浏览器点击安装

快速链接 苹果开发者账号链接 网址: https://developer.apple.com/account 苹果应用上架链接 网址: https://appstoreconnect.apple.com/ 应用证书文件及打包 参考教程: 最新uniapp打包IOS详细步骤&#xff08;2022&#xff09; 证书在线制作工具 网址: https://app.121xuexi.…...

Django 注册及创建订单商品

注册功能的实现 user/views from rest_framework.generics import GenericAPIView from rest_framework.views import APIViewfrom apps.user.models import User from apps.user.serializers import UserSerializer from utils import ResponseMessage from utils.jwt_auth …...

15、Python -- 阶段总结:变量与流程控制

目录 变量变量没有类型&#xff0c;数据有类型 表达式程序流程 变量 变量&#xff1a;编程的本质就是处理数据&#xff0c;数据需要用变量保存 Python语言的特征&#xff1a; 所有变量无需声明&#xff0c;即可使用 变量没有类型 变量没有类型&#xff0c;数据有类型 已学过…...

信息检索与数据挖掘 | 【实验】排名检索模型

文章目录 &#x1f4da;实验内容&#x1f4da;相关概念&#x1f4da;实验步骤&#x1f407;分词预处理&#x1f407;构建倒排索引表&#x1f407;计算query和各个文档的相似度&#x1f407;queries预处理及检索函数&#x1f525;对输入的文本进行词法分析和标准化处理&#x1f…...

玩转AIGC:打造令人印象深刻的AI对话Prompt

玩转AIGC&#xff1a;打造令人印象深刻的AI对话Prompt 《玩转AIGC&#xff1a;打造令人印象深刻的AI对话Prompt》摘要引言正文良好的Prompt&#xff1a;引发AI深度交流的法宝 ✨探讨不同的提问方式1. 常规提问2. 创意提问 对话交流的艺术&#xff1a;倾听与引导的巧妙平衡 ⚖️…...

uniapp vue国际化 i18n

一、安装 vue-i18n npm i vue-i18n 二、新建i18n目录 1、en.json 内容 {"loginPage":{"namePh":"Please enter your login account","passwordPh":"Please enter password"} } 2、zh-CN.json 内容 {"loginPage&qu…...

Docker 启动远程服务访问不了

今天一下午在弄这个 1、防火墙是否关了 firewall-cmd --state2、ip转发开没开 sysctl net.ipv4.ip_forward3、service iptables是不是打开并拦截了 4、检查docker启动的端口号是否一致&#xff0c;或者启动时对不对 5、检查docker的服务是否起来了&#xff0c;比如你的端口号…...

[ACTF2020 新生赛]Exec

【解题过程】 1.打开链接 得到一个能ping 的网站&#xff0c;可以推测这个可以在终端运行的网站。 2.解题思路 在执行的时候我们可以想到命令执行的“&#xff1b;”分号的作用&#xff1a;命令用分号分隔开来&#xff0c;表示它们是两个独立的命令&#xff0c;需要依次执行。…...

Git(三).git 文件夹详解

目录 一、初始化新仓库二、.git 目录2.1 hooks 文件夹2.2 info 文件夹2.3 logs 文件夹2.4 objects 文件夹【重要】2.5 refs 文件夹【重要】2.6 COMMIT_EDITMSG2.7 config2.8 description2.9 FETCH_HEAD2.10 HEAD【重要】2.11 index【重要】2.12 ORIG_HEAD2.13 packed-refs 官网…...

esp32-S3 + visual studio code 开发环境搭建

一、首先在下面链接网页中下载esp-idf v5.1.1离线安装包 &#xff0c;并安装到指定位置。dl.espressif.cn/dl/esp-idf/https://dl.espressif.cn/dl/esp-idf/ 安装过程中会提示需要长路径支持&#xff0c;所以windows系统需要开启长路径使能 Step 1&#xff1a; 打开运行&…...

AI助手开发实战:从资源索引到生产级系统搭建指南

1. 项目概述&#xff1a;一个为AI助手开发者准备的“藏宝图” 如果你正在开发一个AI助手应用&#xff0c;或者正打算将大语言模型的能力集成到你的产品里&#xff0c;那你大概率会遇到一个经典难题&#xff1a;面对市面上眼花缭乱的模型、API和工具&#xff0c;我到底该怎么选&…...

SmarterRouter:基于软件定义与模块化构建智能路由器系统

1. 项目概述&#xff1a;一个更聪明的路由器&#xff0c;它到底想做什么&#xff1f;如果你和我一样&#xff0c;折腾过家里的网络&#xff0c;从刷第三方固件到组软路由&#xff0c;那你肯定对“路由器”这三个字有复杂的感情。它本该是默默无闻的网络基石&#xff0c;却常常因…...

终极免费城通网盘直连解析工具:告别下载限速的完整指南

终极免费城通网盘直连解析工具&#xff1a;告别下载限速的完整指南 【免费下载链接】ctfileGet 获取城通网盘一次性直连地址 项目地址: https://gitcode.com/gh_mirrors/ct/ctfileGet 还在为城通网盘下载速度慢、等待时间长而烦恼吗&#xff1f;ctfileGet是一款专为城通…...

DriveBench:面向真实驾驶场景的长序列多智能体交互基准测试框架

1. 项目概述&#xff1a;从“世界基准”到“驾驶基准”的演进如果你在自动驾驶或者计算机视觉领域摸爬滚打过几年&#xff0c;一定对“基准测试”&#xff08;Benchmark&#xff09;这个词又爱又恨。爱的是&#xff0c;它提供了一个相对公平的擂台&#xff0c;让不同算法、不同…...

芯片老化座的工作温度范围?

在芯片测试领域&#xff0c;老化座&#xff08;Burn-in Socket&#xff09;是保障半导体器件长期可靠性的关键设备。它不仅要在极端温度下稳定工作&#xff0c;还要确保测试数据的精准度。今天&#xff0c;我们以HMILU&#xff08;深圳市鸿怡电子有限公司&#xff09;为例&…...

虚实实景双向映射,升级高端楼宇精细化透明治理

虚实实景双向映射&#xff0c;升级高端楼宇精细化透明治理副标题&#xff1a;原生引擎驱动动态三维场景重构&#xff0c;结合无感化坐标解算、遮挡自适应跨镜接续、身体指纹无源身份匹配&#xff0c;构筑难以复刻、适配极强的楼宇透明化技术壁垒一、方案总览当下高端楼宇运营治…...

终极ThinkPad风扇控制指南:告别噪音,拥抱静音高效

终极ThinkPad风扇控制指南&#xff1a;告别噪音&#xff0c;拥抱静音高效 【免费下载链接】TPFanCtrl2 ThinkPad Fan Control 2 (Dual Fan) for Windows 10 and 11 项目地址: https://gitcode.com/gh_mirrors/tp/TPFanCtrl2 你是否曾经因为ThinkPad风扇的"直升机起…...

BiscuitLang:专为Web业务逻辑设计的轻量级脚本语言

1. 项目概述&#xff1a;一个为现代Web开发而生的轻量级语言如果你和我一样&#xff0c;长期在Web前端和全栈开发的泥潭里摸爬滚打&#xff0c;那你一定对JavaScript生态的“臃肿”与“复杂”深有体会。一个简单的项目动辄node_modules文件夹体积惊人&#xff0c;工具链配置繁琐…...

Pandrator:基于Python的自动化内容生成与数据转换工具实践

1. 项目概述与核心价值最近在折腾一些自动化数据处理和内容生成的工作流&#xff0c;发现了一个挺有意思的开源项目&#xff0c;叫Pandrator。乍一看这个名字&#xff0c;可能会联想到“潘多拉”和“生成器”的结合&#xff0c;实际上它也确实是一个功能强大的内容转换与生成工…...

AI绘图技能解析:用自然语言驱动Excalidraw自动生成图表

1. 项目概述&#xff1a;一个为Excalidraw注入AI灵魂的绘图技能如果你经常用Excalidraw画流程图、架构图或者白板草图&#xff0c;那你一定体会过那种“想法很丰满&#xff0c;画笔很骨感”的尴尬。脑子里明明有一个清晰的系统架构&#xff0c;但落到画布上&#xff0c;光是调整…...