小白学webgl合集-绘制有透视颜色不一样的立方体

效果

原理

结合透视矩阵和视觉矩阵进行绘制

知识点

01透视矩阵

透视矩阵将视图空间中的坐标转换为裁剪空间中的坐标,使得更远的物体看起来更小。

function perspectiveMatrix(fov, aspect, near, far) {const f = 1.0 / Math.tan(fov / 2);const nf = 1 / (near - far);return new Float32Array([f / aspect, 0, 0, 0,0, f, 0, 0,0, 0, (far + near) * nf, -1,0, 0, (2 * far * near) * nf, 0]);
}
参数解释

函数 perspectiveMatrix 创建并返回一个透视投影矩阵,用于3D图形的透视投影。以下是每个参数的详细说明:

  1. fov(Field of View, 视野)

    • 视野角度,即观察者在垂直方向上能够看到的视角。通常以弧度表示,角度单位可以通过 Math.PI / 180 转换为弧度。
    • 例如,45 * Math.PI / 180 表示45度的视角。
  2. aspect(Aspect Ratio, 纵横比)

    • 视图的宽高比,即视图的宽度除以高度。它决定了横向和纵向的缩放比例。
    • 例如,如果视口的宽度是800像素,高度是600像素,则 aspect = 800 / 600 = 4 / 3。
  3. near(Near Clipping Plane, 近裁剪平面)

    • 近裁剪平面的距离,即从观察者到最近可见物体的距离。该值必须大于0。
    • 例如,设置为0.1表示从0.1单位距离开始可见物体。
  4. far(Far Clipping Plane, 远裁剪平面)

    • 远裁剪平面的距离,即从观察者到最远可见物体的距离。该值必须大于 near 值。
    • 例如,设置为100.0表示到100单位距离结束可见物体。

02视图矩阵

视图矩阵将世界空间中的坐标转换为视图空间中的坐标,表示相机的视点。

function lookAtMatrix(eye, center, up) {const zAxis = normalize(subtractVectors(eye, center));const xAxis = normalize(cross(up, zAxis));const yAxis = normalize(cross(zAxis, xAxis));return new Float32Array([xAxis[0], yAxis[0], zAxis[0], 0,xAxis[1], yAxis[1], zAxis[1], 0,xAxis[2], yAxis[2], zAxis[2], 0,-dot(xAxis, eye), -dot(yAxis, eye), -dot(zAxis, eye), 1]);
}function normalize(v) {const length = Math.sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);return [v[0] / length, v[1] / length, v[2] / length];
}function subtractVectors(a, b) {return [a[0] - b[0], a[1] - b[1], a[2] - b[2]];
}function cross(a, b) {return [a[1] * b[2] - a[2] * b[1],a[2] * b[0] - a[0] * b[2],a[0] * b[1] - a[1] * b[0]];
}function dot(a, b) {return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
}
参数解释

函数 lookAtMatrix 用于生成一个视图矩阵,用于将场景从世界空间转换到观察者空间。它通常用于实现相机的视图转换,使得相机看向特定的方向。这个函数的参数如下:

  1. eye

    • 相机的位置,表示观察者所在的点。
    • 例如 [1, 1, 1] 表示相机位于 (1, 1, 1) 的位置。
  2. center

    • 视点,表示相机所看向的目标点。
    • 例如 [0, 0, 0] 表示相机看向 (0, 0, 0) 的位置。
  3. up

    • 上方向向量,表示哪一个方向是相机的“上”方向。通常为 [0, 1, 0],表示正Y方向。
函数 lookAtMatrix 用于生成一个视图矩阵,用于将场景从世界空间转换到观察者空间。它通常用于实现相机的视图转换,使得相机看向特定的方向。这个函数的参数如下:eye:相机的位置,表示观察者所在的点。
例如 [1, 1, 1] 表示相机位于 (1, 1, 1) 的位置。
center:视点,表示相机所看向的目标点。
例如 [0, 0, 0] 表示相机看向 (0, 0, 0) 的位置。
up:上方向向量,表示哪一个方向是相机的“上”方向。通常为 [0, 1, 0],表示正Y方向。

逻辑

设置透视矩阵和视觉矩阵

 代码

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>立方体绘制</title><style>* {margin: 0;padding: 0;}canvas {margin: 50px auto 0;display: block;background: yellow;}</style><script src="test.js"></script></head><body><canvas id="canvas" width="400" height="400"></canvas><script>// 获取const canvas = document.getElementById('canvas')const gl = canvas.getContext('webgl')// 定义片源着色器和顶点着色器const vsSource = `attribute vec4 apos;attribute vec4 acolor;varying vec4 vcolor;uniform mat4 u_projectionMatrix;uniform mat4 u_viewMatrix;void main() {gl_Position =u_projectionMatrix * u_viewMatrix * apos;vcolor = acolor;}`const fsSource = `precision mediump float;varying vec4 vcolor;void main() {gl_FragColor = vcolor;}`//   初始化webglconst program = initShader(gl, vsSource, fsSource)gl.useProgram(program)// 获取 uniform 位置const u_projectionMatrixLocation = gl.getUniformLocation(program, 'u_projectionMatrix')const u_viewMatrixLocation = gl.getUniformLocation(program, 'u_viewMatrix')// 创建透视矩阵和视图矩阵const fov = Math.PI / 4 // 45度视角const aspect = canvas.width / canvas.heightconst near = 0.1const far = 10.0// lookAtMatrix 函数通过计算相机的位置、目标点和上方向,生成一个视图矩阵const projectionMatrix = perspectiveMatrix(fov, aspect, near, far)const viewMatrix = lookAtMatrix([3, 1, 7], [0, 0, 0], [0, 1, 0])function lookAtMatrix(eye, center, up) {const zAxis = normalize(subtractVectors(eye, center))const xAxis = normalize(cross(up, zAxis))const yAxis = normalize(cross(zAxis, xAxis))return new Float32Array([xAxis[0],yAxis[0],zAxis[0],0,xAxis[1],yAxis[1],zAxis[1],0,xAxis[2],yAxis[2],zAxis[2],0,-dot(xAxis, eye),-dot(yAxis, eye),-dot(zAxis, eye),1])}function normalize(v) {const length = Math.sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2])return [v[0] / length, v[1] / length, v[2] / length]}function subtractVectors(a, b) {return [a[0] - b[0], a[1] - b[1], a[2] - b[2]]}function cross(a, b) {return [a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0]]}function dot(a, b) {return a[0] * b[0] + a[1] * b[1] + a[2] * b[2]}function perspectiveMatrix(fov, aspect, near, far) {const f = 1.0 / Math.tan(fov / 2)const nf = 1 / (near - far)return new Float32Array([f / aspect, 0, 0, 0, 0, f, 0, 0, 0, 0, (far + near) * nf, -1, 0, 0, 2 * far * near * nf, 0])}// 设置投影矩阵和视图矩阵gl.uniformMatrix4fv(u_projectionMatrixLocation, false, projectionMatrix)gl.uniformMatrix4fv(u_viewMatrixLocation, false, viewMatrix)// 创建缓存区function initBuffer(gl, program) {const aposLocation = gl.getAttribLocation(program, 'apos')const acolorLocation = gl.getAttribLocation(program, 'acolor')const verticesColors = new Float32Array([// 前面 (红色)-0.5,-0.5,0.5,1,0,0,1, // 左下0.5,-0.5,0.5,1,0,0,1, // 右下0.5,0.5,0.5,1,0,0,1, // 右上-0.5,0.5,0.5,1,0,0,1, // 左上// 后面 (绿色)-0.5,0.5,-0.5,0,1,0,1, // 左上-0.5,-0.5,-0.5,0,1,0,1, // 左下0.5,-0.5,-0.5,0,1,0,1, // 右下0.5,0.5,-0.5,0,1,0,1, // 右上// 左面 (蓝色)-0.5,-0.5,-0.5,0,0,1,1, // 后下-0.5,0.5,-0.5,0,0,1,1, // 后上-0.5,0.5,0.5,0,0,1,1, // 前上-0.5,-0.5,0.5,0,0,1,1, // 前下// 右面 (洋红色)0.5,-0.5,-0.5,1,0,1,1, // 后下0.5,0.5,-0.5,1,0,1,1, // 后上0.5,0.5,0.5,1,0,1,1, // 前上0.5,-0.5,0.5,1,0,1,1, // 前下// 顶面 (黄色)-0.5,0.5,0.5,1,1,0,1, // 前左0.5,0.5,0.5,1,1,0,1, // 前右0.5,0.5,-0.5,1,1,0,1, // 后右-0.5,0.5,-0.5,1,1,0,1, // 后左// 底面 (青色)-0.5,-0.5,0.5,0,1,1,1, // 前左0.5,-0.5,0.5,0,1,1,1, // 前右0.5,-0.5,-0.5,0,1,1,1, // 后右-0.5,-0.5,-0.5,0,1,1,1 // 后左])const indices = new Uint16Array([// 前面0, 1, 2, 0, 2, 3,// 后面4, 5, 6, 4, 6, 7,// 左面8, 9, 10, 8, 10, 11,// 右面12, 13, 14, 12, 14, 15,// 顶面16, 17, 18, 16, 18, 19,// 底面20, 21, 22, 20, 22, 23])const vertexColorBuffer = gl.createBuffer()gl.bindBuffer(gl.ARRAY_BUFFER, vertexColorBuffer)gl.bufferData(gl.ARRAY_BUFFER, verticesColors, gl.STATIC_DRAW)const indexBuffer = gl.createBuffer()gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer)gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW)const FSIZE = verticesColors.BYTES_PER_ELEMENT// 启用顶点属性并指向顶点缓冲区中的数据gl.vertexAttribPointer(aposLocation, 3, gl.FLOAT, false, FSIZE * 7, 0)gl.enableVertexAttribArray(aposLocation)gl.vertexAttribPointer(acolorLocation, 4, gl.FLOAT, false, FSIZE * 7, FSIZE * 3)gl.enableVertexAttribArray(acolorLocation)}initBuffer(gl, program)// 启用深度测试// 清除缓冲区时同时清除颜色缓冲区和深度缓冲区:gl.enable(gl.DEPTH_TEST)gl.clearColor(0, 0, 0, 1)gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT)gl.drawElements(gl.TRIANGLES, 36, gl.UNSIGNED_SHORT, 0)</script></body>
</html>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/40448.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

德旺训练营称重问题

这是考小学的分治策略&#xff0c;小学的分治策略几乎都是分三组。本着这个策略&#xff0c;我们做看看。 第一次称重&#xff1a; 分三组&#xff0c;16,16,17&#xff0c;拿两个16称&#xff0c;得到A情况&#xff0c;一样重&#xff0c;那么假铜钱在那组17个里面。B情况不…

亚马逊SC账号升级VC账号的新浪潮已然席卷整个电商界!

当前电商市场竞争激烈&#xff0c;亚马逊卖家追求业务增长。现有Amazon SC账号卖家有机会升级为VC账号&#xff0c;提供重要机遇。 SC账号是亚马逊常见卖家类型&#xff0c;为众多个人和企业提供销售平台。而VC账号则代表与亚马逊更紧密的合作关系&#xff0c;享有更多优惠、广…

Linux系统之安装Firefox浏览器

Linux系统之安装Firefox浏览器 一、Firefox浏览器介绍1.1 Firefox浏览器介绍1.2 Firefox浏览器特点 二、环境介绍二、本次实践环境介绍2.1 环境规划2.2 本次实践介绍 三、安装firefox浏览器3.1 安装epel3.2 检查yum仓库状态3.3 安装Firefox浏览器3.4 查看Firefox版本 四、在命令…

【图书推荐】《HTML5+CSS3 Web前端开发与实例教程(微课视频版)》

本书用来干什么 详解HTML5、CSS3、Flex布局、Grid布局、AI技巧&#xff0c;通过两个网站设计案例提升Web前端开发技能&#xff0c;为读者深入学习Web前端开发打下牢固的基础。 配套资源非常齐全&#xff0c;可以当Web前端基础课的教材。 内容简介 本书秉承“思政引领&#…

你的地理空间数据神器:Global Mapper 使用体验分享

你的地理空间数据神器&#xff1a;Global Mapper 使用体验分享 作为一名地理信息系统&#xff08;GIS&#xff09;专业人士&#xff0c;我在工作中经常需要处理各种地理空间数据。在使用过多种GIS软件后&#xff0c;我最终找到了一个既高效又功能强大的工具——Global Mapper。…

nacos开启鉴权后,springboot注册失败

1.确认Nacos版本 我的Nacos版本是1.4.2 2.确认Nacos相关依赖的版本之间兼容&#xff0c;一下是我的一些pom.xml依赖 <!--父级项目的--><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifa…

旧衣回收小程序:减少资源浪费,提高回收效率

当下&#xff0c;旧衣服回收成为了大众热衷的事&#xff0c;不少居民都会把闲置的衣物进行回收&#xff0c;旧衣回收行业逐渐火爆。不过&#xff0c;传统的旧衣回收模式已经不符合当下时代发展&#xff0c;具有较大的不便利性。 因此&#xff0c;为解决这一问题&#xff0c;线…

魔改Transformer!9种提速又提效的模型优化方案

Transformer目前已经成为人工智能领域的主流模型&#xff0c;应用非常广泛。然而Transformer中注意力机制计算代价较高&#xff0c;随着序列长度的增加&#xff0c;这个计算量还会持续上升。 为了解决这个问题&#xff0c;业内出现了许多Transformer的魔改工作&#xff0c;以优…

STM32 Cannot access memory

问题描述 最近自己做了一块STM32F103ZET6的板子&#xff0c;在焊接完成后可以在下载器界面看到idcode&#xff0c;但烧录时报错 Cannot access memory 。 解决办法 测量STM32各个供电项&#xff0c;发现时33脚处VDDA电压只有1.8V&#xff0c;是因为R3电阻过大&#xff0c;…

Oracle23ai安装。

1. 事前准备 使用虚拟机安装一个 Oracle Linux 8.9 操作系统下载 oracle-database-free-23ai-1.0-1.el8.x86_64.rpm下载 oracle-database-preinstall-23ai-1.0-2.el8.x86_64.rpm 2.开始安装 2.1 安装 database-preinstall dnf -y install oracle-database-preinstall-23ai-…

docker容器间网络仿真工具-pumba

docker-tc&pumba docker-tc:docker-tc项目仓库 pumba:pumba项目仓库 这两个项目理论上都可以实现对容器间的网络环境进行各种模拟干预&#xff0c;包括延迟&#xff0c;丢包&#xff0c;带宽限制等。 但是我在实际使用时&#xff0c;发现docker-tc这个工具在进行网络进行模…

bWAPP靶场安装

bWAPP安装 下载 git地址&#xff1a;https://github.com/raesene/bWAPP 百度网盘地址&#xff1a;链接&#xff1a;https://pan.baidu.com/s/1Y-LvHxyW7SozGFtHoc9PKA 提取码&#xff1a;4tt8 –来自百度网盘超级会员V5的分享 phpstudy中打开根目录&#xff0c;并将下载的文…

AI:开发者的助力还是终结者?

作为一名科技工作研发者&#xff0c;在科技浪潮汹涌澎湃的当下&#xff0c;AI 对于开发者的角色定位成为了一个备受瞩目的焦点话题。 AI 是在助力开发者&#xff0c;还是会取而代之&#xff1f;让我们从技术的角度深入剖析。 不可否认&#xff0c;AI 为开发者带来了前所未有的便…

Mysql在Windows系统下安装以及配置

目录 一、下载Mysql 二、安装Mysql及环境配置 一、下载Mysql 1. 下载地址 官网:https://www.mysql.com&#xff0c;这里我选用的是Mysql8.0.37版本&#xff08;版本无所谓&#xff0c;随便下8.0.几都行&#xff09; 2.点击DOWNLOADS 然后&#xff0c;点击 MySQL Community…

高考志愿填报,选热门专业还是选自己喜欢的专业

对于每一个结束高考的学生来说&#xff0c;都要面临选专业这个严峻的挑战。选专业可以说是妥妥的大工程&#xff0c;因为这关系到接下来的几年要学什么内容&#xff0c;关键是未来的几十年要从事什么样的工作。 所以在谈及选专业这个问题的时候&#xff0c;每个人的内心都有些…

LeetCode热题100刷题5:189. 轮转数组、238. 除自身以外数组的乘积、41. 缺失的第一个正数

189. 轮转数组 两次翻转&#xff0c;借助swap实现reverse class Solution { public:void reverse(vector<int>& nums, int left, int right) {int ileft, j right-1;while(i<j) {swap(nums[i],nums[j]);i;j--;}}void rotate(vector<int>& nums, int…

从零实现一套低代码(保姆级教程)【运行时】 --- 【30】实现组件的删除和复制功能

摘要 本篇主要来实现一下&#xff0c;在设计器里&#xff0c;对组件进行删除和复制的功能。这一篇不该在运行时的分组里面&#xff0c;但是写到这里来&#xff0c;就继续写下去吧。 因为在设计页面的时候&#xff0c;一定会出现拖拽错组件的情况。所以我们给设计器增加删除组…

MES系统如何支持多品种小批量生产

MES系统&#xff08;制造执行系统&#xff09;在多品种小批量生产环境中发挥着至关重要的作用。它通过一系列先进的技术手段&#xff0c;提高了生产线的灵活性和效率&#xff0c;从而有效地支持了多品种小批量生产。以下是MES系统如何支持多品种小批量生产的详细分析&#xff1…

LVS FILTER UNUSED OPTION

我正在「拾陆楼」和朋友们讨论有趣的话题,你⼀起来吧? 拾陆楼知识星球入口 过滤一些版图与spice网表对不上的器件。 一般后端遇不到这个问题,因为通常是需要写到网表中的decap没有写出来造成的,如下图。

【Matlab 路径优化】基于蚁群算法的XX市旅游景点线路优化系统

基于蚁群算法的XX市旅游景点线路优化系统 &#xff08;一&#xff09;客户需求&#xff1a; ①考虑旅游景点的空间分布、游客偏好等因素&#xff0c;实现了旅游线路的智能规划 ②游客选择一景点出发经过所要游览的所有景点只一次&#xff0c;最后回到出发点的前提下&#xf…