WebGL进阶(五)-可视域
理论基础:
顶点着色器 Vertex Shader
主要是负责处理顶点位置、顶点颜色、顶点向量等顶点的数据;处理一些顶点的变换:例如在进行视图变换和投影变换时MVP矩阵会改变顶点的位置信息。
输入:
顶点着色器输入部分主要是声明:
①储存着每个顶点属性的attribute变量;
②所有顶点都会实现的(例如MVP矩阵、透视变换矩阵等)全局的uniform变量;
③一些会传递给片元着色器的varying变量。
// 变量
attribute vwc3 aVertexPosition; // 顶点位置
attribute vec3 aNormalPosition; // 法线
attribute vec2 aTextureCoord; // uv坐标varying highp vec2 vTextureCoord; // 顶点着色器传递给片元着色器
varying highp vec3 vFragPos;
varying highp vec3 vNormal;// 矩阵
uniform mat4 uModelViewMatrix; // 视图变换矩阵
uniform mat4 uProjectionMatrix; // 透视变换矩阵
输出:
①顶点坐标gl_Position;
②给输入部分声明的varying变量赋值;
矩阵运算从右往左运算
vFragPos = aVertexPosition;
vNormal = aNormalPosition;// 计算点坐标
gl_Position = uProjextionMatrix * uModelViewMatrix * vec4(aVertexPosition,1.0);vTextureCoord = aTextureCoord;
片元着色器 Fragment Shader
用于颜色、贴图、光照阴影等
//除了上述出现的“着色器不支持高精度,限定浮点类型为中精度”
precision mediump float;//还有表示支持高精度的:“着色器支持高精度,限定浮点类型为高精度”
precision highp float;//以及仅支持低精度的:
prcision lowp float;
输入:
uniform声明
/声明一个纹理相关的变量,sampler2D 也是一种数据类型
//它是一种取样器类型的变量,该变量对应传入的纹理2D图片的像素数据
uniform sampler2D uSampler;
//Blinn-Phong需要的漫反射项kd、高光项ks、光源位置、相机位置、光强
uniform vec3 uKd;
uniform vec3 uKs;
uniform vec3 uLightPos;
uniform vec3 uCameraPos;
uniform float uLightIntensity;
// 这个TextureSample参数作用应该是:
// 以左上角为原点,通过UV截取图片,如果==1,则正常取值
uniform int uTextureSample;
varing变量
//继承varying参数
varying highp vec2 vTextureCoord;
varying highp vec3 vFragPos;
varying highp vec3 vNormal;
输出:
一般设置为gl_FragColor
参考:GAMES101-现代计算机图形学入门-闫令琪_哔哩哔哩_bilibili
gl.compileShader(shader), 传递需要编译的着色器,函数实现着色器编译。
gl.getShaderParameter(shader,COMPILE_STATUS),COMPILE_STATUS为:
gl.DELETE_STATUS
:标示着色器是否被删除,删除(GL_TRUE)未删除(GL_FALSE).gl.COMPILE_STATUS
: 标示着色器是否编译成功,是(GL_TRUE)不是(GL_FALSE)gl.SHADER_TYPE
: 标示着色器类型,是顶点着色器 (gl.VERTEX_SHADER
) 还是片段着色器 (gl.FRAGMENT_SHADER
)
WebGLRenderingContext.enableVertexAttribArray()
在 WebGL 中,作用于顶点的数据会先储存在attributes。这些数据仅对 JavaScript 代码和顶点着色器可用。属性由索引号引用到 GPU 维护的属性列表中。在不同的平台或 GPU 上,某些顶点属性索引可能具有预定义的值。创建属性时,WebGL 层会分配其他属性。
类型为GLuint 的索引,指向要激活的顶点属性。可以使用getAttribLocation方法来获取索引.
WebGLRenderingContext.vertexAttribPointer(index,size,type,normalized,stride,offset)
打开属性数组列表中指定索引处的通用顶点属性数组,
index:定要修改的顶点属性的索引。
size:指定每个顶点属性的组成数量,必须是 1,2,3 或 4。
type:
指定数组中每个元素的数据类型可能是:
-
gl.BYTE
: signed 8-bit integer, with values in [-128, 127] 有符号的 8 位整数,范围 [-128, 127] -
gl.SHORT
: signed 16-bit integer, with values in [-32768, 32767] 有符号的 16 位整数,范围 [-32768, 32767] -
gl.UNSIGNED_BYTE
: unsigned 8-bit integer, with values in [0, 255] 无符号的 8 位整数,范围 [0, 255] -
gl.UNSIGNED_SHORT
: unsigned 16-bit integer, with values in [0, 65535] 无符号的 16 位整数,范围 [0, 65535] -
gl.FLOAT
: 32-bit IEEE floating point number 32 位 IEEE 标准的浮点数 -
When using a WebGL 2 context, the following values are available additionally: 使用 WebGL2 版本的还可以使用以下值:
gl.HALF_FLOAT
: 16-bit IEEE floating point number 16 位 IEEE 标准的浮点数
normalize:
当转换为浮点数时是否应该将整数数值归一化到特定的范围。
- or types
gl.BYTE
andgl.SHORT
, normalizes the values to [-1, 1] if true. 对于类型gl.BYTE
和gl.SHORT
,如果是 true 则将值归一化为 [-1, 1] - For types
gl.UNSIGNED_BYTE
andgl.UNSIGNED_SHORT
, normalizes the values to [0, 1] if true. 对于类型gl.UNSIGNED_BYTE
和gl.UNSIGNED_SHORT
,如果是 true 则将值归一化为 [0, 1] - For types
gl.FLOAT
andgl.HALF_FLOAT
, this parameter has no effect. 对于类型gl.FLOAT
和gl.HALF_FLOAT
,此参数无效
stride:
一个 GLsizei,以字节为单位指定连续顶点属性开始之间的偏移量 (即数组中一行长度)。不能大于 255。如果 stride 为 0,则假定该属性是紧密打包的,即不交错属性,每个属性在一个单独的块中,下一个顶点的属性紧跟当前顶点之后。
offset:
指定顶点属性数组中第一部分的字节偏移量。必须是类型的字节长度的倍数。
WebGLRenderingContext.uniformMatrix[234]fv(location,transpose,value)
该方法的 3 个版本(uniformMatrix2fv()
、uniformMatrix3fv()
和 unifomMatrix4fv()
),分别以二阶、三阶和四阶方阵作为输入值,它们应是分别具有 4、9、16 个浮点数的数组。
WebGLRenderingContext.uniformMatrix2fv(location, transpose, value);
WebGLRenderingContext.uniformMatrix3fv(location, transpose, value);
WebGLRenderingContext.uniformMatrix4fv(location, transpose, value);
location
WebGLUniformLocation 对象包含了要修改的 uniform attribute 位置。位置使用 getUniformLocation()获得。
transpose
GLboolean 指定是否转置矩阵。必须为 false
。
value
Float32Array 型或者是 GLfloat
序列值。这些值被假定按列主序(column major order)的方式提供。
源码:
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><script src="gl-matrix.js"></script><script>let vertexstring = `attribute vec4 a_position;uniform mat4 u_formMatrix;uniform mat4 proj;attribute vec4 a_color;varying vec4 color;void main(void){gl_Position = u_formMatrix * a_position;color = a_color;} `;let fragmentstring = `precision mediump float;varying vec4 color;void main(void){gl_FragColor =color;}`;var webgl;var near=0;var far= 50;function init() {initWebgl();initShader();initBuffer();draw();inittext(near,far)initEvent();}function inittext(near,far){document.getElementById("text").innerHTML = "near:"+near +"<br/>"+ "far:"+far;}function initEvent() {document.onkeydown = handleKeyDown;}function handleKeyDown(event) {if (String.fromCharCode(event.keyCode) == 'W') {near += 1;}else if (String.fromCharCode(event.keyCode) == 'S') {near -=1;}else if (String.fromCharCode(event.keyCode) == 'A') {far -= 1;}else if (String.fromCharCode(event.keyCode) == 'D') {far += 1;}inittext(near,far)initBuffer();draw();}function initWebgl() {let webglDiv = document.getElementById('myCanvas');webgl = webglDiv.getContext("webgl");webgl.viewport(0, 0, webglDiv.clientWidth, webglDiv.clientHeight);}function initShader() {let vsshader = webgl.createShader(webgl.VERTEX_SHADER);let fsshader = webgl.createShader(webgl.FRAGMENT_SHADER);webgl.shaderSource(vsshader, vertexstring);webgl.shaderSource(fsshader, fragmentstring);webgl.compileShader(vsshader);webgl.compileShader(fsshader);if (!webgl.getShaderParameter(vsshader, webgl.COMPILE_STATUS)) {var err = webgl.getShaderInfoLog(vsshader);alert(err);return;}if (!webgl.getShaderParameter(fsshader, webgl.COMPILE_STATUS)) {var err = webgl.getShaderInfoLog(fsshader);alert(err);return;}let program = webgl.createProgram();webgl.attachShader(program, vsshader);webgl.attachShader(program, fsshader)webgl.linkProgram(program);webgl.useProgram(program);webgl.program = program}function initBuffer() {let ProjMatrix = glMatrix.mat4.create();glMatrix.mat4.identity(ProjMatrix);glMatrix.mat4.ortho(ProjMatrix,-100,100,-100,100,near,far) //修改可视域范围let arr = [0.0, 70, -40, 1, 1, 0, 0, 1,-50, -30, -40, 1, 1, 0, 0, 1, // 绿色50, -30, -40, 1, 1, 0, 0, 1,50, 40, -20, 1, 1.0, 1.0, 0.4, 1,-50, 40, -20, 1, 1.0, 1.0, 0.4, 1,0.0, -60,-20, 1, 1.0, 1.0, 0.4, 1,// 黄色0.0, 50, 0.0, 1, 0.4, 0.4, 1.0, 1,-50, -50, 0.0, 1, 0.4, 0.4, 1.0, 1,50, -50, 0.0, 1, 0.4, 0.4, 1.0, 1, // 蓝色]let pointPosition = new Float32Array(arr);let aPsotion = webgl.getAttribLocation(webgl.program, "a_position");let triangleBuffer = webgl.createBuffer();webgl.bindBuffer(webgl.ARRAY_BUFFER, triangleBuffer);webgl.bufferData(webgl.ARRAY_BUFFER, pointPosition, webgl.STATIC_DRAW);webgl.enableVertexAttribArray(aPsotion);webgl.vertexAttribPointer(aPsotion, 4, webgl.FLOAT, false, 8 * 4, 0);let aColor = webgl.getAttribLocation(webgl.program, "a_color");webgl.enableVertexAttribArray(aColor);webgl.vertexAttribPointer(aColor, 4, webgl.FLOAT, false, 8 * 4, 4 * 4);let uniformMatrix1 = webgl.getUniformLocation(webgl.program, "u_formMatrix");webgl.uniformMatrix4fv(uniformMatrix1, false, ProjMatrix)}function draw() {webgl.clearColor(0.0, 1.0, 0.0, 1.0);webgl.clear(webgl.COLOR_BUFFER_BIT);webgl.drawArrays(webgl.TRIANGLES, 0, 9);}</script>
</head><body onload="init()"><canvas id='myCanvas' width="1024" height='768'></canvas><div id="text"></div>
</body></html>
效果展示:
可操作键盘方向键进行显示变换。
复盘:
相关文章:

WebGL进阶(五)-可视域
理论基础: 顶点着色器 Vertex Shader 主要是负责处理顶点位置、顶点颜色、顶点向量等顶点的数据;处理一些顶点的变换:例如在进行视图变换和投影变换时MVP矩阵会改变顶点的位置信息。 输入: 顶点着色器输入部分主要是声明&…...

2024性价比家居好物有哪些?推荐五款值得每个家庭拥有的好物品牌!
每年双11的时候我都特别喜欢买一些家居好物,今年双11也不例外,经过我一两周的精心挑选,专门选了五款性价比高的家居好物,接下来给大家分享一下! 家居好物一、希亦ACE Pro内衣洗衣机 我买过、评测过的内衣洗衣机&#…...

字节青训-查找热点数据问题
问题描述 给你一个整数数组 nums 和一个整数 k,请你返回其中出现频率前 k 高的元素。请按升序排列。 1 < nums.length < 10^5k 的取值范围是 [1, 数组中不相同的元素的个数]题目数据保证答案唯一,换句话说,数组中前 k 个高频元素的集合…...
Codeforces Round 981 (Div. 3) (A~F)
文章目录 A. Sakurako and Kosuke思路code B. Sakurako and Water思路code C. Sakurakos Field Trip思路code D. Kousukes Assignment思路code E. Sakurako, Kosuke, and the Permutation思路code F. Kosukes Sloth思路code Codeforces Round 981 (Div. 3) A. Sakurako and Ko…...

shell脚本实例(4)while实现1+...+100,linux新增用户
while实现1到100求和 #!/bin/bash/ s0 i1 #-le小于等于 while [ $i -le 100 ] dos$[ $s$i ]i$[ $i1 ] done echo $s echo $i 执行结果如下 修改用户名密码脚本 #!/bin/bash/ #提示用户输入用户名 read -p "请输入用户名:"username useradd $username #提…...
docker XML详解
下列为一个基本的运行docker镜像文件 {"Id": "62a82b0e69930e54c291095f632adde58dd0b247adba3a048385a55c87e38eba","Created": "2024-07-11T04:00:09.36091853Z","Path": "java","Args": ["-ja…...

web前端边框详解,弹性盒子的使用(仿写购物网页)
边框详解 1. 边框宽度(border - width) - 具体取值:可以是具体的长度值,如 px (像素)、 pt (点)、 em (相对单位)等。例如, border - width: 2px…...

【ACM出版,EI稳定检索,九大高校联合举办, IEEE Fellow支持】2024年计算机视觉与艺术研讨会(CVA 2024)
在线投稿:学术会议-学术交流征稿-学术会议在线-艾思科蓝 2024年计算机视觉与艺术国际学术会议(CVA 2024)作为2024年人工智能、数字媒体技术与交互设计国际学术会议(ICADI 2024)的分会。此次大会旨在汇聚全球在计算机视觉与艺术…...

认识软件测试
博主主页: 码农派大星. 数据结构专栏:Java数据结构 数据库专栏:MySQL数据库 JavaEE专栏:JavaEE 软件测试专栏:软件测试 关注博主带你了解更多知识 1. 什么是测试? 测试在⽣活中处处可⻅ 例子: 对某款购物软件进⾏测试 启动测试:点击软件图标&#…...

poi处理excel文档时,与lombok的@Accessors(chain = true)注解冲突
poi在反射封装数据时会判断set方法的返回是不是Void,加上Accessors会造成NoSuchMethodException异常...
我接触csdn中的c++的时间
大家好,我是AC使者,不知不觉我也来到CSDN半年了!在这半年我也看到了自身的不足,我也还有了很多粉丝,所以我今天来总结一下这半年的东西。 第一篇--------结构体数组 关于结构体数组的理解-CSDN博客 第二篇--------字…...
go语言多态性(接口interface)的使用
前言 在Go语言中,接口类型(interface)完全可以作为一个函数的参数。这是Go语言多态性的一个重要体现,允许函数接受任何实现了接口中定义的方法的类型的实例。 一、接口(interface)定义 type Reader inte…...

如何将markdown文件转换为pdf
最近笔者在用vscode写markdown,但是提交时往往需要交pdf。所以就涉及到如何将markdown转化为pdf格式。 首先,需要在vscode上安装插件 markdown Preview Enhanced 之后在vscode的右上角即可看到下述图标,点击,vscode右半面就会显示…...

【python实操】python小程序之测试报告
引言 python小程序之测试报告 文章目录 引言一、测试报告1.1 概念1.1.1 使用Pytest和Allure生成测试报告1.1.2 使用unittest和HTMLTestRunner生成测试报告1.1.3 总结 1.2 题目1.3 代码1.3 代码解释 二、思考 一、测试报告 1.1 概念 python生成测试报告,常用的方法包…...

【Java基础】2、Java基础语法
f2/fnf2:选中点中的文件名 1.注释 为什么要有注释? 给别人和以后的自己可以看懂的解释 注释含义 注释是在程序指定位置的说明性信息;简单理解,就是对代码的一种解释 注释分类 单行注释 //注释信息 多行注释…...
MATLAB基础应用精讲-【数模应用】本量利分析(Cost-Volume-Profit Analysis)
目录 前言 几个高频面试题目 本量利分析与量本利分析的区别 算法原理 发展历程 几个相关概念 什么是CVP分析 基本假设 注意事项 本量利分析的作用 基本原理 多种产品量本利分析 盈亏平衡分析 目标利润分析 敏感性分析 边际分析 本量利分析基本模型 应用场景 …...

实习冲刺Day7
算法题 合并两个有序链表 class Solution { public:void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {for (int i 0; i<n; i) {nums1[m i] nums2[i];//直接将num2的数据插入到num1的尾部}sort(nums1.begin(), nums1.end());//排…...

《Python游戏编程入门》注-第4章1
《Python游戏编程入门》的第4章是“用户输入:Bomb Cathcer游戏”,通过轮询键盘和鼠标设备状态实现Bomb Cathcer游戏。 1 Bomb Cathcer游戏介绍 “4.1 认识Bomb Cathcer游戏”内容介绍了Bomb Cathcer游戏的玩法,即通过鼠标来控制红色“挡板”…...

一些硬件知识【2024/10/29】
千兆以太网有8条信号线,百兆以太网有4条线: 网络变压器构造图: 百兆以太网拓扑: BOB Smith电路: 【以太网接口电 路设计】https://www.bilibili.com/video/BV1i3411u7bv?vd_source3cc3c07b09206097d0d8b0aefdf07958&a…...

利用弱监督学习在全切片病理图像中检测和分型基底细胞癌|文献速递-基于生成模型的数据增强与疾病监测应用
Title 题目 Detection and subtyping of basal cell carcinoma in whole-slide histopathology using weakly-supervised learning 利用弱监督学习在全切片病理图像中检测和分型基底细胞癌 01 文献速递介绍 基底细胞癌 (BCC) 的发病率正在给病理诊断带来压力。BCC 的发病率…...

手游刚开服就被攻击怎么办?如何防御DDoS?
开服初期是手游最脆弱的阶段,极易成为DDoS攻击的目标。一旦遭遇攻击,可能导致服务器瘫痪、玩家流失,甚至造成巨大经济损失。本文为开发者提供一套简洁有效的应急与防御方案,帮助快速应对并构建长期防护体系。 一、遭遇攻击的紧急应…...

黑马Mybatis
Mybatis 表现层:页面展示 业务层:逻辑处理 持久层:持久数据化保存 在这里插入图片描述 Mybatis快速入门 
visual studio 2022更改主题为深色
visual studio 2022更改主题为深色 点击visual studio 上方的 工具-> 选项 在选项窗口中,选择 环境 -> 常规 ,将其中的颜色主题改成深色 点击确定,更改完成...

家政维修平台实战20:权限设计
目录 1 获取工人信息2 搭建工人入口3 权限判断总结 目前我们已经搭建好了基础的用户体系,主要是分成几个表,用户表我们是记录用户的基础信息,包括手机、昵称、头像。而工人和员工各有各的表。那么就有一个问题,不同的角色…...

屋顶变身“发电站” ,中天合创屋面分布式光伏发电项目顺利并网!
5月28日,中天合创屋面分布式光伏发电项目顺利并网发电,该项目位于内蒙古自治区鄂尔多斯市乌审旗,项目利用中天合创聚乙烯、聚丙烯仓库屋面作为场地建设光伏电站,总装机容量为9.96MWp。 项目投运后,每年可节约标煤3670…...

【开发技术】.Net使用FFmpeg视频特定帧上绘制内容
目录 一、目的 二、解决方案 2.1 什么是FFmpeg 2.2 FFmpeg主要功能 2.3 使用Xabe.FFmpeg调用FFmpeg功能 2.4 使用 FFmpeg 的 drawbox 滤镜来绘制 ROI 三、总结 一、目的 当前市场上有很多目标检测智能识别的相关算法,当前调用一个医疗行业的AI识别算法后返回…...

回溯算法学习
一、电话号码的字母组合 import java.util.ArrayList; import java.util.List;import javax.management.loading.PrivateClassLoader;public class letterCombinations {private static final String[] KEYPAD {"", //0"", //1"abc", //2"…...

day36-多路IO复用
一、基本概念 (服务器多客户端模型) 定义:单线程或单进程同时监测若干个文件描述符是否可以执行IO操作的能力 作用:应用程序通常需要处理来自多条事件流中的事件,比如我现在用的电脑,需要同时处理键盘鼠标…...
解决:Android studio 编译后报错\app\src\main\cpp\CMakeLists.txt‘ to exist
现象: android studio报错: [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 解决: 不要动CMakeLists.…...
SpringAI实战:ChatModel智能对话全解
一、引言:Spring AI 与 Chat Model 的核心价值 🚀 在 Java 生态中集成大模型能力,Spring AI 提供了高效的解决方案 🤖。其中 Chat Model 作为核心交互组件,通过标准化接口简化了与大语言模型(LLM࿰…...