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.插入排序 由上面的动图可以知道插入排序的逻辑就是从第一个元素开始往后遍历,如果找到比前一个元素小的(或者大的)就往前排,所以插入排序的每一次遍历都会保证前面的数据是有序的,接下类用代码进行讲解。 我们这里传…...
模型参数、模型存储精度、参数与显存
模型参数量衡量单位 M:百万(Million) B:十亿(Billion) 1 B 1000 M 1B 1000M 1B1000M 参数存储精度 模型参数是固定的,但是一个参数所表示多少字节不一定,需要看这个参数以什么…...
【Linux】C语言执行shell指令
在C语言中执行Shell指令 在C语言中,有几种方法可以执行Shell指令: 1. 使用system()函数 这是最简单的方法,包含在stdlib.h头文件中: #include <stdlib.h>int main() {system("ls -l"); // 执行ls -l命令retu…...

解决Ubuntu22.04 VMware失败的问题 ubuntu入门之二十八
现象1 打开VMware失败 Ubuntu升级之后打开VMware上报需要安装vmmon和vmnet,点击确认后如下提示 最终上报fail 解决方法 内核升级导致,需要在新内核下重新下载编译安装 查看版本 $ vmware -v VMware Workstation 17.5.1 build-23298084$ lsb_release…...

智能在线客服平台:数字化时代企业连接用户的 AI 中枢
随着互联网技术的飞速发展,消费者期望能够随时随地与企业进行交流。在线客服平台作为连接企业与客户的重要桥梁,不仅优化了客户体验,还提升了企业的服务效率和市场竞争力。本文将探讨在线客服平台的重要性、技术进展、实际应用,并…...

vue3+vite项目中使用.env文件环境变量方法
vue3vite项目中使用.env文件环境变量方法 .env文件作用命名规则常用的配置项示例使用方法注意事项在vite.config.js文件中读取环境变量方法 .env文件作用 .env 文件用于定义环境变量,这些变量可以在项目中通过 import.meta.env 进行访问。Vite 会自动加载这些环境变…...

10-Oracle 23 ai Vector Search 概述和参数
一、Oracle AI Vector Search 概述 企业和个人都在尝试各种AI,使用客户端或是内部自己搭建集成大模型的终端,加速与大型语言模型(LLM)的结合,同时使用检索增强生成(Retrieval Augmented Generation &#…...

实战三:开发网页端界面完成黑白视频转为彩色视频
一、需求描述 设计一个简单的视频上色应用,用户可以通过网页界面上传黑白视频,系统会自动将其转换为彩色视频。整个过程对用户来说非常简单直观,不需要了解技术细节。 效果图 二、实现思路 总体思路: 用户通过Gradio界面上…...
微服务通信安全:深入解析mTLS的原理与实践
🔥「炎码工坊」技术弹药已装填! 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、引言:微服务时代的通信安全挑战 随着云原生和微服务架构的普及,服务间的通信安全成为系统设计的核心议题。传统的单体架构中&…...

【iOS】 Block再学习
iOS Block再学习 文章目录 iOS Block再学习前言Block的三种类型__ NSGlobalBlock____ NSMallocBlock____ NSStackBlock__小结 Block底层分析Block的结构捕获自由变量捕获全局(静态)变量捕获静态变量__block修饰符forwarding指针 Block的copy时机block作为函数返回值将block赋给…...

PydanticAI快速入门示例
参考链接:https://ai.pydantic.dev/#why-use-pydanticai 示例代码 from pydantic_ai import Agent from pydantic_ai.models.openai import OpenAIModel from pydantic_ai.providers.openai import OpenAIProvider# 配置使用阿里云通义千问模型 model OpenAIMode…...