WebGL笔记:图形缩放的原理和实现
缩放
1 )原理
- 缩放可以理解为对向量长度的改变,或者对向量坐标分量的同步缩放
- 如下图,比如
- 让向量OA 收缩到点B的位置,也就是从OA变成OB,缩放了一半
2 )公式
-
已知
- 点A的位置是(ax,ay,az)
- 点A基于原点內缩了一半
-
求
- 点A內缩了一半后的bx、by、bz位置B
-
解
bx = ax * 0.5 by = ay * 0.5 bz = az * 0.5
在着色器中缩放
1 )核心代码
-
可以对gl_Position 的x、y、z依次缩放
<script id="vertexShader" type="x-shader/x-vertex">attribute vec4 a_Position;float scale = 1.2; // 注意这里声明了浮点型,一点要用浮点数,否则会导致 UseProgram: program not valid 的警告void main() {gl_Position.x = a_Position.x * scale;gl_Position.y = a_Position.y * scale;gl_Position.z = a_Position.z * scale;gl_Position.w = 1.0; // 注意 w 的值,默认1.0} </script> -
也可以从a_Position中抽离出由x、y、z组成的三维向量,对其进行一次性缩放
<script id="vertexShader" type="x-shader/x-vertex">attribute vec4 a_Position;float scale = 1.2;void main() {gl_Position = vec4(vec3(a_Position) * scale, 1.0);} </script>
2 )完整代码
<canvas id="canvas"></canvas>
<script id="vertexShader" type="x-shader/x-vertex">attribute vec4 a_Position;float scale = 1.0;void main() {gl_Position = vec4(vec3(a_Position) * scale, 1.0);}
</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 './utils.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);gl.clearColor(0.0, 0.0, 0.0, 1.0);gl.clear(gl.COLOR_BUFFER_BIT);gl.drawArrays(gl.TRIANGLES, 0, 3);
</script>
用js缩放图形
1 )核心代码
- 同样的我们也可以把缩放系数暴露给js,通过js 缩放图形
- 建立uniform变量
<script id="vertexShader" type="x-shader/x-vertex">attribute vec4 a_Position;uniform float u_Scale;void main() {gl_Position = vec4(vec3(a_Position) * u_Scale, 1.0);} </script> - 使用js获取并修改uniform 变量
const u_Scale = gl.getUniformLocation(gl.program, 'u_Scale') gl.uniform1f(u_Scale, 1.0) - 添加动画让其动起来
let angle = 0 !(function animate() {angle += 0.05;const scale = Math.sin(n) + 1; // 借助三角函数正弦进行缩放 (-1, 1) + 1 => (0, 2)gl.uniform1f(u_Scale, scale);gl.clear(gl.COLOR_BUFFER_BIT);gl.drawArrays(gl.TRIANGLES, 0, 3);requestAnimationFrame(animate) })()
- 建立uniform变量
2 )完整代码
<canvas id="canvas"></canvas>
<script id="vertexShader" type="x-shader/x-vertex">attribute vec4 a_Position;uniform float u_Scale;void main() {gl_Position = vec4(vec3(a_Position) * u_Scale, 1.0);}
</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 './utils.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);const u_Scale = gl.getUniformLocation(gl.program, 'u_Scale')gl.uniform1f(u_Scale, 1);gl.clearColor(0.0, 0.0, 0.0, 1.0);gl.clear(gl.COLOR_BUFFER_BIT);gl.drawArrays(gl.TRIANGLES, 0, 3);let angle = 0;!(function animate() {angle += 0.05;const scale = Math.sin(angle) + 1;gl.uniform1f(u_Scale, scale);gl.clear(gl.COLOR_BUFFER_BIT);gl.drawArrays(gl.TRIANGLES, 0, 3);requestAnimationFrame(animate);})()
</script>
相关文章:
WebGL笔记:图形缩放的原理和实现
缩放 1 )原理 缩放可以理解为对向量长度的改变,或者对向量坐标分量的同步缩放 如下图,比如让向量OA 收缩到点B的位置,也就是从OA变成OB,缩放了一半 2 )公式 已知 点A的位置是(ax,ay,az)点A基于原点內缩了…...
前端学习--React(5)
一、useReducer 管理相对复杂的状态数据 定义一个reducer函数,根据action值的不同返回不同的状态 在组件中调用useReducer并传入reducer函数和状态的初始值 事件发生时,通过dispatch函数分派一个对象,即通知reducer具体返回哪个状态对应的操…...
【数据结构】平衡树引入
数据结构-平衡树 前置知识 二叉树二叉树的中序遍历 问题 维护一个数据结构,支持插入元素、删除元素、查询元素的排名、查询排名对应的元素、查询元素的前驱、查询元素的后继等。 BST(二叉搜索树) 作为一个基本无效(很容易卡掉…...
机器视觉相机镜头光源选型
镜头选型工具 - HiTools - 海康威视 Hikvisionhttps://www.hikvision.com/cn/support/tools/hitools/cl8a9de13648c56d7f/ 海康机器人-机器视觉产品页杭州海康机器人股份有限公司海康机器人HIKROBOT是面向全球的机器视觉和移动机器人产品及解决方案提供商,业务聚焦于…...
Appium:iOS测试比Android测试更难?
iOS测试与Android测试: Appium 是一个开源的自动化测试框架,用于iOS、Android和Web应用程序。它允许开发者使用自己的语言来编写测试脚本,并且可以运行在多种平台上。 就Appium本身而言,它为iOS和Android提供了相似的测试能力和…...
使用c#罗列、监视、控制进程
个人简介:本人多年从事研发和测试领域工作,有一定的经验; 口号:懒人推动科技进步,学习编程啊脚本啊目的就是要将人从做相同的工作脱离出来,手懒可以但是脑子不能懒,让重复的事情自动完成,能动一下就完成任务就不能动两下,懒到极致才是目标! 方向:本人不怎么将理论的…...
Vue:绘制图例
本文记录使用Vue框架绘制图例的代码片段。 可以嵌入到cesium视图中,也可以直接绘制到自己的原生系统中。 一、绘制图例Vue组件 <div v-for="(color, index) in colors" :key="index" class="legend-item"><div class="color-…...
Web(8)SQL注入
Web网站(对外门户) 原理:not>and>or(优先级) 一.低级注入 order by的作用是对字段进行排序,如order by 5,根据第五个字段 进行排序,如果一共有4个字段,输入order by 5系统就会报错不 …...
kafka入门(三):kafka多线程消费
kafka消费积压 如果生产者发送消息的速度过快,或者是消费者处理消息的速度太慢,那么就会有越来越多的消息无法及时消费,也就是消费积压。 消费积压时, (1) 可以增加Topic的分区数,并且增加消费组的消费者数量&#…...
android通过广播打印RAM信息
通过广播打印ram相关log 参数说明: 广播:com.android.settings.action.RAM_INFO int型参数index:0 - 3h, 1 - 6h, 2 - 12h, 3 - 24h 代表过去时间app使用ram情况(平均/最大占用) Index: frameworks/base/services/cor…...
C++新经典模板与泛型编程:策略类模板
策略类模板 在前面的博文中,策略类SumPolicy和MinPolicy都是普通的类,其中包含的是一个静态成员函数模板algorithm(),该函数模板包含两个类型模板参数。其实,也可以把SumPolicy和MinPolicy类写成类模板—直接把algorithm()中的两…...
微信小程序引入Vant Weapp修改样式不起作用,使用外部样式类进行覆盖
一、引入Vant Weapp后样式问题 在项目中使用第三方组件修改css样式时,总是出现各种各样问题,修改的css样式不起作用,没有效果,效果不符合预期等。 栗子(引入一个搜索框组件)实现效果: 左侧有一个搜索文字背景为蓝色,接着跟一个搜索框 wxml <view class"container&q…...
python核酸检测 青少年电子学会等级考试 中小学生python编程等级考试二级真题答案解析2022年6月
目录 python核酸检测 一、题目要求 1、编程实现 2、输入输出...
搭建React项目,基于Vite+React+TS+ESLint+Prettier+Husky+Commitlint
基于ViteReactTSESLintPrettierHuskyCommitlint搭建React项目 node: 20.10.0 一、创建项目 安装包管理器pnpm npm i pnpm -g基于Vite创建项目 pnpm create vitelatest web-gis-react --template react-ts进入项目目录安装依赖 $ cd web-gis-react $ pnpm i启动项目 $ pnpm…...
ChatGPT在国内的使用限制,国内的ChatGPT替代工具
人工智能技术的发展不仅改变了我们的生活方式,也在各行各业发挥着越来越重要的作用。ChatGPT(Generative Pre-trained Transformer)作为一种先进的自然语言处理模型,由OpenAI推出,其在生成人类般流畅对话方面表现出色。…...
服务器如何保证数据安全_Maizyun
服务器如何保证数据安全 在当今的数字化时代,数据安全已经成为企业和社会组织必须面对的重要问题。服务器作为存储和处理大量数据的核心组件,必须采取有效的措施来确保数据的安全。本文将探讨服务器如何保证数据安全。 一、访问控制和身份认证 访问控…...
sql2005日志文件过大如何清理
由于安装的时候没有计划好空间,默认装在系统盘,而且又没有做自动备份、截断事务日志等,很快LDF文件就达到十几G,或者几十G ,此时就不得不处理了。 备份和计划就不说了,现在就说下怎么把它先删除吧…...
Linux--学习记录(2)
解压命令: gzip命令: 参数: -k:待压缩的文件会保留下来,生成一个新的压缩文件-d:解压压缩文件语法: gzip -k pathname(待压缩的文件夹名)gzip -kd name.gz(待解压的压缩包名&#x…...
字符串函数`strlen`、`strcpy`、`strcmp`、`strstr`、`strcat`的使用以及模拟实现
文章目录 🚀前言🚀库函数strlen✈️strlen的模拟实现 🚀库函数strcpy✈️strcpy的模拟实现 🚀strcmp✈️strcmp的模拟实现 🚀strstr✈️strstr的模拟实现 🚀strcat✈️strcat的模拟实现 🚀前言 …...
插入排序与希尔排序(C语言实现)
1.插入排序 由上面的动图可以知道插入排序的逻辑就是从第一个元素开始往后遍历,如果找到比前一个元素小的(或者大的)就往前排,所以插入排序的每一次遍历都会保证前面的数据是有序的,接下类用代码进行讲解。 我们这里传…...
shell脚本--常见案例
1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件: 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...
DockerHub与私有镜像仓库在容器化中的应用与管理
哈喽,大家好,我是左手python! Docker Hub的应用与管理 Docker Hub的基本概念与使用方法 Docker Hub是Docker官方提供的一个公共镜像仓库,用户可以在其中找到各种操作系统、软件和应用的镜像。开发者可以通过Docker Hub轻松获取所…...
循环冗余码校验CRC码 算法步骤+详细实例计算
通信过程:(白话解释) 我们将原始待发送的消息称为 M M M,依据发送接收消息双方约定的生成多项式 G ( x ) G(x) G(x)(意思就是 G ( x ) G(x) G(x) 是已知的)࿰…...
【JVM】- 内存结构
引言 JVM:Java Virtual Machine 定义:Java虚拟机,Java二进制字节码的运行环境好处: 一次编写,到处运行自动内存管理,垃圾回收的功能数组下标越界检查(会抛异常,不会覆盖到其他代码…...
系统设计 --- MongoDB亿级数据查询优化策略
系统设计 --- MongoDB亿级数据查询分表策略 背景Solution --- 分表 背景 使用audit log实现Audi Trail功能 Audit Trail范围: 六个月数据量: 每秒5-7条audi log,共计7千万 – 1亿条数据需要实现全文检索按照时间倒序因为license问题,不能使用ELK只能使用…...
微信小程序 - 手机震动
一、界面 <button type"primary" bindtap"shortVibrate">短震动</button> <button type"primary" bindtap"longVibrate">长震动</button> 二、js逻辑代码 注:文档 https://developers.weixin.qq…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个生活电费的缴纳和查询小程序
一、项目初始化与配置 1. 创建项目 ohpm init harmony/utility-payment-app 2. 配置权限 // module.json5 {"requestPermissions": [{"name": "ohos.permission.INTERNET"},{"name": "ohos.permission.GET_NETWORK_INFO"…...
(转)什么是DockerCompose?它有什么作用?
一、什么是DockerCompose? DockerCompose可以基于Compose文件帮我们快速的部署分布式应用,而无需手动一个个创建和运行容器。 Compose文件是一个文本文件,通过指令定义集群中的每个容器如何运行。 DockerCompose就是把DockerFile转换成指令去运行。 …...
重启Eureka集群中的节点,对已经注册的服务有什么影响
先看答案,如果正确地操作,重启Eureka集群中的节点,对已经注册的服务影响非常小,甚至可以做到无感知。 但如果操作不当,可能会引发短暂的服务发现问题。 下面我们从Eureka的核心工作原理来详细分析这个问题。 Eureka的…...
【C++特殊工具与技术】优化内存分配(一):C++中的内存分配
目录 一、C 内存的基本概念 1.1 内存的物理与逻辑结构 1.2 C 程序的内存区域划分 二、栈内存分配 2.1 栈内存的特点 2.2 栈内存分配示例 三、堆内存分配 3.1 new和delete操作符 4.2 内存泄漏与悬空指针问题 4.3 new和delete的重载 四、智能指针…...
