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 and gl.SHORT, normalizes the values to [-1, 1] if true. 对于类型gl.BYTEgl.SHORT,如果是 true 则将值归一化为 [-1, 1]
  • For types gl.UNSIGNED_BYTE and gl.UNSIGNED_SHORT, normalizes the values to [0, 1] if true. 对于类型gl.UNSIGNED_BYTEgl.UNSIGNED_SHORT,如果是 true 则将值归一化为 [0, 1]
  • For types gl.FLOAT and gl.HALF_FLOAT, this parameter has no effect. 对于类型gl.FLOATgl.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>

效果展示:

可操作键盘方向键进行显示变换。 

复盘:

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

gin入门教程(10):实现jwt认证

使用 github.com/golang-jwt/jwt 实现 JWT&#xff08;JSON Web Token&#xff09;可以有效地进行用户身份验证,这个功能往往在接口前后端分离的应用中经常用到。以下是一个基本的示例&#xff0c;演示如何在 Gin 框架中实现 JWT 认证。 目录结构 /hello-gin │ ├── cmd/ …

三星瞄准2026年推出400层垂直NAND技术,2030年前剑指1000层NAND闪存

据报道&#xff0c;三星计划在2026年前推出400层的垂直NAND闪存&#xff0c;并且目标是在2030年前实现1000层的NAND技术。随着人工智能&#xff08;AI&#xff09;浪潮的到来&#xff0c;高带宽内存&#xff08;HBM&#xff09;已经成为存储巨头之间的关键战场&#xff0c;而同…

端口号和ip地址一样吗?区别是什么

在网络通信的世界里&#xff0c;端口号和IP地址是两个不可或缺的概念&#xff0c;它们各自扮演着独特的角色&#xff0c;共同维系着数据在网络中的有序传输。然而&#xff0c;对于许多初学者而言&#xff0c;这两者往往容易被混淆&#xff0c;认为它们是同一事物的不同表述。那…

前端自学资料(笔记八股)分享—CSS(4)

更多详情&#xff1a;爱米的前端小笔记&#xff08;csdn~xitujuejin~zhiHu~Baidu~小红shu&#xff09;同步更新&#xff0c;等你来看&#xff01;都是利用下班时间整理的&#xff0c;整理不易&#xff0c;大家多多&#x1f44d;&#x1f49b;➕&#x1f914;哦&#xff01;你们…

JavaScript字符串不可变性与ES6 新增字符串方法详解

非 VIP 用户可前往公众号“前端基地”进行免费阅读,文章链接如下: JavaScript字符串不可变性与ES6 新增字符串方法详解本文介绍了 JavaScript 中字符串的不可变性以及 ES6 新增的字符串方法。包括判断是否包含、以指定字符串开头或结尾,还有重复指定次数等方法,并结合案例…

鸿蒙开发:arkTS FolderStack容器组件

ArkTS(也称为Ark TypeScript)是鸿蒙生态的应用开发语言&#xff0c;它在TypeScript(简称TS)的基础上进行了优化和定制&#xff0c;以满足鸿蒙系统的开发需求。今天给大家分享arkTS FolderStack容器组件技术知识&#xff0c;如果有所帮助&#xff0c;大家点点关注支持一下&#…

SSL/TLS 密码套件漏洞分析以及修复方法

1. 前言 在当今数字化时代&#xff0c;网络安全至关重要。SSL/TLS 协议作为保障网络通信安全的重要手段&#xff0c;广泛应用于各类网络应用中。然而&#xff0c;如同任何技术一样&#xff0c;SSL/TLS 也并非绝对安全&#xff0c;存在着一些可能被攻击者利用的漏洞。本文将深入…

如何加密电脑磁盘?电脑本地磁盘加密方法介绍

随着信息技术的不断发展&#xff0c;电脑磁盘加密已经成为保护个人隐私和数据安全的重要手段。本文将介绍几种常见的电脑本地磁盘加密方法&#xff0c;帮助用户保护自己的数据安全。 文件夹只读加密专家 文件夹只读加密专家不仅可以加密电脑中的文件夹&#xff0c;还可以加密保…

已解决Navicat 选择Mysql表 报错unkonow internal error: Access violation - no RTTI data

已解决Navicat 选择Mysql表 报错unkonow internal error&#xff1a; Access violation - no RTTI data 报错信息截图&#xff1a; 使用Navicat Premium15 选择sql server表时 出现大量弹窗报错&#xff0c;导致sql文件执行不了&#xff0c;右键数据库执行外部文件也失败了。弹…

【机器学习】揭秘XGboost:高效梯度提升算法的实践与应用

目录 &#x1f354; XGBoost 原理 1.1 目标函数确定和树的复杂度介绍 1.2 XGBoost目标函数的推导 1.3 泰勒公式展开 1.4 化简目标函数 1.5 问题再次转换 1.6 对叶子结点求导 1.7 XGBoost的回归树构建方法 &#x1f354; XGBoost API 2.1 通用参数 2.2 Booster 参数 …

基于vue框架的的高校学习资源共享系统5ym3y(程序+源码+数据库+调试部署+开发环境)系统界面在最后面。

系统程序文件列表 项目功能&#xff1a;学生,学校信息,课程分类,班课信息,班课申请,学习资源,班课评价,班课投诉,投诉学生,教师,班级 开题报告内容 基于Vue框架的高校学习资源共享系统开题报告 一、项目背景与意义 随着信息技术的飞速发展和教育改革的深入推进&#xff0c;…

Hadoop生态圈框架部署(二)- 配置IP地址映射为主机名及免密登录

文章目录 前言一、配置IP地址映射为主机名1. 虚拟机hadoop1配置主机名与 IP 地址的映射关系2. 虚拟机hadoop2配置主机名与 IP 地址的映射关系3. 虚拟机hadoop3配置主机名与 IP 地址的映射关系 二、配置免密登录1. 配置虚拟机hadoop1免密登录到hadoop1、hadoop2和hadoop32. 配置…

基于JSP的篮球系列网上商城系统【附源码】

基于JSP的篮球系列网上商城系统 效果如下&#xff1a; 系统首页界面 商品信息界面 购物车界面 购物车界面 管理员登录界面 管理员功能界面 用户注册界面 我的收藏界面 研究背景 21世纪&#xff0c;我国早在上世纪就已普及互联网信息&#xff0c;互联网对人们生活中带来了无限…

力扣题86~90

题86&#xff08;中等&#xff09;&#xff1a; python代码 # Definition for singly-linked list. # class ListNode: # def __init__(self, val0, nextNone): # self.val val # self.next next class Solution:def partition(self, head: Optional[Li…

Python小白学习教程从入门到入坑------第十八课 异常模块与包【上】(语法基础)

一、异常 在Python中&#xff0c;异常&#xff08;Exception&#xff09;是一种用于处理在程序运行时可能发生的错误情况的机制 异常允许程序在检测到错误时不是简单地崩溃&#xff0c;而是能够优雅地处理这些错误&#xff0c;可能包括记录错误信息、清理资源、或者向用户提…

5G NR:BWP入门

简介 5G NR 系统带宽比4G LTE 大了很多&#xff0c;4G LTE 最大支持带宽为20MHz&#xff0c; 而5G NR 的FR1 最大支持带宽为100MHz&#xff0c; FR2 最大支持带宽为 400MHz。 带宽越大&#xff0c;意味了终端功耗越多。为了减少终端的功耗&#xff0c;5G NR 引入了BWP(Band Wid…

哪款宠物空气净化器能吸毛还低噪?希喂、范罗士真实测评

作为一个养宠清洁博主&#xff0c;这些年为了让家里更干净&#xff0c;让猫在家里更舒服&#xff0c;我也测了不少的清洁家电&#xff0c;其中包括洗地机、吸尘器、空气净化器以及扫地机器人等&#xff0c;其中宠物空气净化器的表现也算十分优异。 它可以快速去除空气中的浮毛…

【ComfyUI】手动安装部署ComfyUI的运行环境

如果不喜欢已有的一键启动包&#xff0c;我们可以手动的安装和部署ComfyUI的运行环境&#xff0c;相比一键安装包&#xff0c;自己部署ComfyUI 环境具有相当大的灵活性&#xff0c;其实部署ComfyUI 环境非常简单&#xff0c;不像网上说的那么复杂。下面我们就按照顺序给大家分享…

【JavaEE】【多线程】定时器

目录 一、定时器简介1.1 Timer类1.2 使用案例 二、实现简易定时器2.1 MyTimerTask类2.2 实现schedule方法2.3 构造方法2.4 总代码2.5 测试 一、定时器简介 定时器&#xff1a;就相当于一个闹钟&#xff0c;当我们定的时间到了&#xff0c;那么就执行一些逻辑。 1.1 Timer类 …

Http 状态码 301 Permanent Rediret 302 Temporary Redirect、 重定向 重写

HTTP状态码301和302是什么&#xff1f; 1、HTTP状态码301 HTTP状态码301表示永久性转移&#xff08;Permanent Redirect&#xff09;&#xff0c;这意味着请求的资源已经被分配了一个新的URI&#xff0c;以后的引用应该使用资源现在所指的URI。 HTTP 301状态码表示请求的资源…