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

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)
      })()
      

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 &#xff09;原理 缩放可以理解为对向量长度的改变&#xff0c;或者对向量坐标分量的同步缩放 如下图&#xff0c;比如让向量OA 收缩到点B的位置&#xff0c;也就是从OA变成OB&#xff0c;缩放了一半 2 &#xff09;公式 已知 点A的位置是(ax,ay,az)点A基于原点內缩了…...

前端学习--React(5)

一、useReducer 管理相对复杂的状态数据 定义一个reducer函数&#xff0c;根据action值的不同返回不同的状态 在组件中调用useReducer并传入reducer函数和状态的初始值 事件发生时&#xff0c;通过dispatch函数分派一个对象&#xff0c;即通知reducer具体返回哪个状态对应的操…...

【数据结构】平衡树引入

数据结构-平衡树 前置知识 二叉树二叉树的中序遍历 问题 维护一个数据结构&#xff0c;支持插入元素、删除元素、查询元素的排名、查询排名对应的元素、查询元素的前驱、查询元素的后继等。 BST&#xff08;二叉搜索树&#xff09; 作为一个基本无效&#xff08;很容易卡掉…...

机器视觉相机镜头光源选型

镜头选型工具 - HiTools - 海康威视 Hikvisionhttps://www.hikvision.com/cn/support/tools/hitools/cl8a9de13648c56d7f/ 海康机器人-机器视觉产品页杭州海康机器人股份有限公司海康机器人HIKROBOT是面向全球的机器视觉和移动机器人产品及解决方案提供商&#xff0c;业务聚焦于…...

Appium:iOS测试比Android测试更难?

iOS测试与Android测试&#xff1a; Appium 是一个开源的自动化测试框架&#xff0c;用于iOS、Android和Web应用程序。它允许开发者使用自己的语言来编写测试脚本&#xff0c;并且可以运行在多种平台上。 就Appium本身而言&#xff0c;它为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网站&#xff08;对外门户&#xff09; 原理&#xff1a;not>and>or(优先级) 一.低级注入 order by的作用是对字段进行排序&#xff0c;如order by 5&#xff0c;根据第五个字段 进行排序&#xff0c;如果一共有4个字段&#xff0c;输入order by 5系统就会报错不 …...

kafka入门(三):kafka多线程消费

kafka消费积压 如果生产者发送消息的速度过快&#xff0c;或者是消费者处理消息的速度太慢&#xff0c;那么就会有越来越多的消息无法及时消费&#xff0c;也就是消费积压。 消费积压时&#xff0c; (1) 可以增加Topic的分区数&#xff0c;并且增加消费组的消费者数量&#…...

android通过广播打印RAM信息

通过广播打印ram相关log 参数说明&#xff1a; 广播&#xff1a;com.android.settings.action.RAM_INFO int型参数index&#xff1a;0 - 3h, 1 - 6h, 2 - 12h, 3 - 24h 代表过去时间app使用ram情况&#xff08;平均/最大占用&#xff09; Index: frameworks/base/services/cor…...

C++新经典模板与泛型编程:策略类模板

策略类模板 在前面的博文中&#xff0c;策略类SumPolicy和MinPolicy都是普通的类&#xff0c;其中包含的是一个静态成员函数模板algorithm()&#xff0c;该函数模板包含两个类型模板参数。其实&#xff0c;也可以把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替代工具

人工智能技术的发展不仅改变了我们的生活方式&#xff0c;也在各行各业发挥着越来越重要的作用。ChatGPT&#xff08;Generative Pre-trained Transformer&#xff09;作为一种先进的自然语言处理模型&#xff0c;由OpenAI推出&#xff0c;其在生成人类般流畅对话方面表现出色。…...

服务器如何保证数据安全_Maizyun

服务器如何保证数据安全 在当今的数字化时代&#xff0c;数据安全已经成为企业和社会组织必须面对的重要问题。服务器作为存储和处理大量数据的核心组件&#xff0c;必须采取有效的措施来确保数据的安全。本文将探讨服务器如何保证数据安全。 一、访问控制和身份认证 访问控…...

sql2005日志文件过大如何清理

由于安装的时候没有计划好空间&#xff0c;默认装在系统盘&#xff0c;而且又没有做自动备份、截断事务日志等&#xff0c;很快LDF文件就达到十几G&#xff0c;或者几十G &#xff0c;此时就不得不处理了。 备份和计划就不说了&#xff0c;现在就说下怎么把它先删除吧&#xf…...

Linux--学习记录(2)

解压命令&#xff1a; gzip命令&#xff1a; 参数&#xff1a; -k&#xff1a;待压缩的文件会保留下来&#xff0c;生成一个新的压缩文件-d&#xff1a;解压压缩文件语法&#xff1a; gzip -k pathname(待压缩的文件夹名)gzip -kd name.gz&#xff08;待解压的压缩包名&#x…...

字符串函数`strlen`、`strcpy`、`strcmp`、`strstr`、`strcat`的使用以及模拟实现

文章目录 &#x1f680;前言&#x1f680;库函数strlen✈️strlen的模拟实现 &#x1f680;库函数strcpy✈️strcpy的模拟实现 &#x1f680;strcmp✈️strcmp的模拟实现 &#x1f680;strstr✈️strstr的模拟实现 &#x1f680;strcat✈️strcat的模拟实现 &#x1f680;前言 …...

插入排序与希尔排序(C语言实现)

1.插入排序 由上面的动图可以知道插入排序的逻辑就是从第一个元素开始往后遍历&#xff0c;如果找到比前一个元素小的&#xff08;或者大的&#xff09;就往前排&#xff0c;所以插入排序的每一次遍历都会保证前面的数据是有序的&#xff0c;接下类用代码进行讲解。 我们这里传…...

日语AI面试高效通关秘籍:专业解读与青柚面试智能助攻

在如今就业市场竞争日益激烈的背景下&#xff0c;越来越多的求职者将目光投向了日本及中日双语岗位。但是&#xff0c;一场日语面试往往让许多人感到步履维艰。你是否也曾因为面试官抛出的“刁钻问题”而心生畏惧&#xff1f;面对生疏的日语交流环境&#xff0c;即便提前恶补了…...

盘古信息PCB行业解决方案:以全域场景重构,激活智造新未来

一、破局&#xff1a;PCB行业的时代之问 在数字经济蓬勃发展的浪潮中&#xff0c;PCB&#xff08;印制电路板&#xff09;作为 “电子产品之母”&#xff0c;其重要性愈发凸显。随着 5G、人工智能等新兴技术的加速渗透&#xff0c;PCB行业面临着前所未有的挑战与机遇。产品迭代…...

ssc377d修改flash分区大小

1、flash的分区默认分配16M、 / # df -h Filesystem Size Used Available Use% Mounted on /dev/root 1.9M 1.9M 0 100% / /dev/mtdblock4 3.0M...

涂鸦T5AI手搓语音、emoji、otto机器人从入门到实战

“&#x1f916;手搓TuyaAI语音指令 &#x1f60d;秒变表情包大师&#xff0c;让萌系Otto机器人&#x1f525;玩出智能新花样&#xff01;开整&#xff01;” &#x1f916; Otto机器人 → 直接点明主体 手搓TuyaAI语音 → 强调 自主编程/自定义 语音控制&#xff08;TuyaAI…...

Hive 存储格式深度解析:从 TextFile 到 ORC,如何选对数据存储方案?

在大数据处理领域&#xff0c;Hive 作为 Hadoop 生态中重要的数据仓库工具&#xff0c;其存储格式的选择直接影响数据存储成本、查询效率和计算资源消耗。面对 TextFile、SequenceFile、Parquet、RCFile、ORC 等多种存储格式&#xff0c;很多开发者常常陷入选择困境。本文将从底…...

使用Matplotlib创建炫酷的3D散点图:数据可视化的新维度

文章目录 基础实现代码代码解析进阶技巧1. 自定义点的大小和颜色2. 添加图例和样式美化3. 真实数据应用示例实用技巧与注意事项完整示例(带样式)应用场景在数据科学和可视化领域,三维图形能为我们提供更丰富的数据洞察。本文将手把手教你如何使用Python的Matplotlib库创建引…...

解决:Android studio 编译后报错\app\src\main\cpp\CMakeLists.txt‘ to exist

现象&#xff1a; android studio报错&#xff1a; [CXX1409] D:\GitLab\xxxxx\app.cxx\Debug\3f3w4y1i\arm64-v8a\android_gradle_build.json : expected buildFiles file ‘D:\GitLab\xxxxx\app\src\main\cpp\CMakeLists.txt’ to exist 解决&#xff1a; 不要动CMakeLists.…...

【UE5 C++】通过文件对话框获取选择文件的路径

目录 效果 步骤 源码 效果 步骤 1. 在“xxx.Build.cs”中添加需要使用的模块 &#xff0c;这里主要使用“DesktopPlatform”模块 2. 添加后闭UE编辑器&#xff0c;右键点击 .uproject 文件&#xff0c;选择 "Generate Visual Studio project files"&#xff0c;重…...

spring Security对RBAC及其ABAC的支持使用

RBAC (基于角色的访问控制) RBAC (Role-Based Access Control) 是 Spring Security 中最常用的权限模型&#xff0c;它将权限分配给角色&#xff0c;再将角色分配给用户。 RBAC 核心实现 1. 数据库设计 users roles permissions ------- ------…...

小智AI+MCP

什么是小智AI和MCP 如果还不清楚的先看往期文章 手搓小智AI聊天机器人 MCP 深度解析&#xff1a;AI 的USB接口 如何使用小智MCP 1.刷支持mcp的小智固件 2.下载官方MCP的示例代码 Github&#xff1a;https://github.com/78/mcp-calculator 安这个步骤执行 其中MCP_ENDPOI…...