WebGL颜色与纹理

WEBGL中的着色器变量包括以下种类:

  • 属性变量(Attribute Variables):这些变量用于接收从应用程序中传递的顶点数据,比如顶点位置和颜色,是只读的不可修改。
  • 统一变量(Uniform Variables):这些变量是着色器中的全局变量,用于接收从应用程序中传递的值,比如投影矩阵,旋转矩阵等。
  • 纹理坐标变量(Texture Coordinate Variables):这些变量用于指定在纹理图像中采样的位置。
  • 法线向量变量(Normal Vector Variables):这些变量用于计算光照效果,用于标识几何体表面的法向量。
  • 输出变量(Output Variables):这些变量用于将着色器的输出传递给渲染管线的下一阶段,比如像素着色器的颜色值。

一、varying变量

1.varying变量定义

在WebGL中,varying变量是在顶点着色器和片元着色器之间传递数据的一种特殊类型的变量。它们被用于在顶点着色器和片元着色器之间传递信息,以便在渲染过程中进行插值。在顶点着色器中,varying变量的值被计算并传递到片元着色器中,然后在片元着色器中进行插值,然后被用来确定要绘制的像素的颜色。

Varying变量通常被用于将光照和纹理坐标等信息从顶点着色器传递到片元着色器中。由于它们是在渲染过程中插值的,所以它们可以用来创建平滑的过渡,使得渲染出来的图像更加真实和细腻。

例如,如果你想在三角形中使用纹理映射,那么你需要将纹理坐标从顶点着色器传递到片元着色器中。你可以通过定义一个varying变量来传递这个纹理坐标,然后在片元着色器中使用它来获取纹理的颜色,从而创建一个真实的纹理映射效果。

2.varying执行流程

在WebGL中,varying变量用于在顶点着色器和片元着色器之间传递数据。它们的执行原理如下:

  1. 在顶点着色器中声明一个varying变量,并对其进行赋值。
  2. 这个varying变量的值会被传递到片元着色器中。
  3. 在片元着色器中,可以通过读取这个varying变量的值来进行后续的计算。
  4. 由于每个像素都会执行片元着色器,因此varying变量的值也会被相应地插值,以便在不同像素之间进行平滑的过渡。
  5. 最终的像素颜色将由片元着色器中的计算结果和其他因素(如光照)共同决定。

varying变量的执行原理是通过在顶点着色器和片元着色器之间传递数据,使得像素颜色可以根据这些数据进行计算。
在这里插入图片描述

3.使用varying绘制彩色三角形

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>varying变量</title><script src="../../lib/index.js"></script><style>* {margin: 0;padding: 0;}canvas {margin: 50px auto 0;display: block;background: yellow;}</style>
</head>
<body><canvas id="canvas" width="400" height="400">此浏览器不支持webGL</canvas>
</body>
</html><script>const ctx = document.getElementById('canvas')const gl = ctx.getContext('webgl');//着色器//创建着色器源码const VERTEX_SHADER_SOURCE = `attribute vec4 aPosition;//需要同时在顶点和片元着色器中声明,将数据从顶点着色器传递到片元着色器varying vec4 vColor;void main(){vColor = aPosition;//要绘制的坐标gl_Position = aPosition;//要绘制的大小(着色器变量使用的是浮点型)gl_PointSize = 10.0;}`; //顶点着色器const FRAGMENT_SHADER_SOURCE = `precision lowp float;varying vec4 vColor;void main(){//要绘制的颜色gl_FragColor = vColor;}`; //片元着色器const program =  initShader(gl,VERTEX_SHADER_SOURCE,FRAGMENT_SHADER_SOURCE)const aPosition = gl.getAttribLocation(program, 'aPosition')const points = new Float32Array([-0.5,-0.5,0.5,-0.5,0.0,0.5,])const buffer = gl.createBuffer();gl.bindBuffer(gl.ARRAY_BUFFER,buffer);gl.bufferData(gl.ARRAY_BUFFER,points,gl.STATIC_DRAW)gl.vertexAttribPointer(aPosition,2,gl.FLOAT,false,0,0);gl.enableVertexAttribArray(aPosition)gl.drawArrays(gl.TRIANGLES,0,3)</script>

在这里插入图片描述

二、使用纹理渲染图片背景

1.创建纹理对象

纹理对象主要用于存储纹理图像数据。

const texture = gl.createTexture();

同时也可以通过gl.deleteTexture(texture)来删除纹理对象。

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>渲染图片背景</title><script src="../../lib/index.js"></script><style>* {margin: 0;padding: 0;}canvas {margin: 50px auto 0;display: block;background: yellow;}</style>
</head>
<body><canvas id="canvas" width="400" height="400">此浏览器不支持webGL</canvas>
</body>
</html><script>const ctx = document.getElementById('canvas')const gl = ctx.getContext('webgl');//着色器//创建着色器源码const VERTEX_SHADER_SOURCE = `attribute vec4 aPosition;attribute vec4 aTex;varying vec2 vTex;void main(){//要绘制的坐标gl_Position = aPosition;vTex = vec2(aTex.x,aTex.y);}`; //顶点着色器const FRAGMENT_SHADER_SOURCE = `precision lowp float;uniform sampler2D uSampler;//纹理坐标varying vec2 vTex;void main(){//要绘制的颜色gl_FragColor = texture2D(uSampler,vTex);}`; //片元着色器const program =  initShader(gl,VERTEX_SHADER_SOURCE,FRAGMENT_SHADER_SOURCE)const aPosition = gl.getAttribLocation(program, 'aPosition')const aTex = gl.getAttribLocation(program, 'aTex')const uSampler = gl.getUniformLocation(program, 'uSampler')const points = new Float32Array([-0.5,0.5,0.0,1.0,-0.5,-0.5,0.0,0.0,0.5,0.5,1.0,1.0,0.5,-0.5,1.0,0.0,])const buffer = gl.createBuffer();const BYTES = points.BYTES_PER_ELEMENT;gl.bindBuffer(gl.ARRAY_BUFFER,buffer);gl.bufferData(gl.ARRAY_BUFFER,points,gl.STATIC_DRAW)gl.vertexAttribPointer(aPosition,2,gl.FLOAT,false,BYTES*4,0);gl.vertexAttribPointer(aTex,2,gl.FLOAT,false,BYTES*4,BYTES*2);gl.enableVertexAttribArray(aPosition)gl.enableVertexAttribArray(aTex)const img = new Image();img.onload = function(){console.log("加载图片",img)//创建纹理图像存储纹理数据const texture = gl.createTexture();//翻转 图片 Y轴gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL,1)//开启一个纹理单元gl.activeTexture(gl.TEXTURE0);//绑定纹理对象gl.bindTexture(type,texture)/*type有两种类型gl.TEXTURE_2D:二维纹理gl.TEXTURE_CUBE_MAP:立方体纹理*/gl.bindTexture(gl.TEXTURE_2D,texture);//处理放大缩小的逻辑gl.texParamteri(type,pname,param)/*type 同上pname:gl.TEXTURE_MAG_FILTER 放大gl.TEXTURE_MIN_FILTER 缩小gl.TEXTURE_WRAP_S 横向(水平填充)gl.TEXTURE_WRAP_T 纵向(垂直填充)param:设置给放大和缩小的有 gl.NEAREST 使用像素颜色值gl.LINEAR 使用四周的加权平均值设置给填充的有  gl.REPEAT 平铺重复gl.MIRRORED_REPEAT 镜像对称 gl.CLAMP_TO_EDGE 边缘延伸                */gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MAG_FILTER,gl.LINEAR);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MIN_FILTER,gl.LINEAR);//水平垂直的填充模式gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_WRAP_S,gl.CLAMP_TO_EDGE);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_WRAP_T,gl.CLAMP_TO_EDGE);//配置纹理图集gl.texImage2D(type,level,internalformat,format,dataType,image)/*internalformat:图像的内部格式 gl.RGB, gl.RGBA,gl.ALPHA,gl.LUMINANCE(使用物体表面的红绿蓝分量的加权平均值来计算),gl.LUMINANCE_ALPHAformat:纹理的内部格式,必须和internalformat相同dataType: 纹理的数据类型 gl.UNSIGNED_BYTE,gl.UNSIGNED_SHORT_5_6_5,gl.UNSIGNED_SHORT_4_4_4_4,gl.UNSIGNED_SHORT_5_5_5_1,*/gl.texImage2D(gl.TEXTURE_2D,0,gl.RGB,gl.RGB,gl.UNSIGNED_BYTE,img);gl.uniform1i(uSampler,0)gl.drawArrays(gl.TRIANGLE_STRIP,0,4)}img.src = "../../picture/test.jpg";</script>

在这里插入图片描述

三、使用多重纹理

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>使用多重纹理</title><script src="../../lib/index.js"></script><style>* {margin: 0;padding: 0;}canvas {margin: 50px auto 0;display: block;background: yellow;}</style>
</head>
<body><canvas id="canvas" width="400" height="400">此浏览器不支持webGL</canvas>
</body>
</html><script>const ctx = document.getElementById('canvas')const gl = ctx.getContext('webgl');//着色器//创建着色器源码const VERTEX_SHADER_SOURCE = `attribute vec4 aPosition;attribute vec4 aTex;varying vec2 vTex;void main(){//要绘制的坐标gl_Position = aPosition;vTex = vec2(aTex.x,aTex.y);}`; //顶点着色器const FRAGMENT_SHADER_SOURCE = `precision lowp float;uniform sampler2D uSampler1;uniform sampler2D uSampler2;//纹理坐标varying vec2 vTex;void main(){vec4 c1 = texture2D(uSampler1,vTex);vec4 c2 = texture2D(uSampler2,vTex);gl_FragColor = c1*c2;}`; //片元着色器const program =  initShader(gl,VERTEX_SHADER_SOURCE,FRAGMENT_SHADER_SOURCE)const aPosition = gl.getAttribLocation(program, 'aPosition')const aTex = gl.getAttribLocation(program, 'aTex')const uSampler1 = gl.getUniformLocation(program, 'uSampler1')const uSampler2 = gl.getUniformLocation(program, 'uSampler2')const points = new Float32Array([-0.5,0.5,0.0,1.0,-0.5,-0.5,0.0,0.0,0.5,0.5,1.0,1.0,0.5,-0.5,1.0,0.0,])const buffer = gl.createBuffer();const BYTES = points.BYTES_PER_ELEMENT;gl.bindBuffer(gl.ARRAY_BUFFER,buffer);gl.bufferData(gl.ARRAY_BUFFER,points,gl.STATIC_DRAW)gl.vertexAttribPointer(aPosition,2,gl.FLOAT,false,BYTES*4,0);gl.vertexAttribPointer(aTex,2,gl.FLOAT,false,BYTES*4,BYTES*2);gl.enableVertexAttribArray(aPosition)gl.enableVertexAttribArray(aTex)Promise.all([getImage(gl,"../../picture/test.jpg",uSampler1,0),getImage(gl,"../../picture/test2.jpeg",uSampler2,1)]).then(()=>{gl.drawArrays(gl.TRIANGLE_STRIP,0,4)})</script>

要叠加的图片
请添加图片描述

在这里插入图片描述

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

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

相关文章

小红书自动化写文以及发文机器人

&#x1f4aa;&#x1f3fb; 1. Python基础专栏&#xff0c;基础知识一网打尽&#xff0c;9.9元买不了吃亏&#xff0c;买不了上当。 Python从入门到精通 &#x1f601; 2. 毕业设计专栏&#xff0c;毕业季咱们不慌忙&#xff0c;几百款毕业设计等你选。 ❤️ 3. Python爬虫专栏…

Pinia:Vue.js 状态管理的新选择

目录 1.前言 2.Pinia 的核心概念 3.安装 Pinia 4.创建和使用 Store 5.为什么选择 Pinia&#xff1f; 6.结论 1.前言 在 Vue.js 的生态系统中&#xff0c;状态管理是一个核心概念&#xff0c;尤其是对于复杂的单页应用&#xff08;SPA&#xff09;。随着 Vue 3 的推出&…

解决前端下载特殊文件404问题(以Kestrel 服务器为例)

在某些情况下前端需要将服务器上的静态文件下载到本地&#xff0c;对于大部分文件通过HTTP Get方法就可以直接下载&#xff0c;但是有些特殊的静态文件&#xff08;例如.py文件&#xff0c;.cs文件等&#xff09;我们下载时会返回404找不到文件&#xff0c;下面我们以Kestrel 服…

[数据集][目标检测]红外微小目标无人机直升机飞机飞鸟检测数据集VOC+YOLO格式7559张4类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;7559 标注数量(xml文件个数)&#xff1a;7559 标注数量(txt文件个数)&#xff1a;7559 标注…

Vue主题色实现

主题色实现 情境 配置平台支持多个主题色的选择&#xff0c;用户可通过在配置平台选择项目主题色。前端项目在骨架屏加载页面获取配置信息&#xff0c;设置项目主题色&#xff0c;实现同个项目不同主题色渲染的需求 实现 1.定义主题色变量 不同主题色根据不同js文件划分定…

Java ETL - Apache Beam 简介

基本介绍 Apache Beam是一个用于大数据处理的开源统一编程模型。它允许用户编写一次代码&#xff0c;然后在多个批处理和流处理引擎上运行&#xff0c;如Apache Flink、Apache Spark和Google Cloud Dataflow等。Apache Beam提供了一种简单且高效的方式来实现数据处理管道&…

使用python操作数据库

文章目录 一、问题背景二、安装python三、代码示例四、总结 一、问题背景 在日常开发过程中&#xff0c;随着项目进展和业务功能的迭代&#xff0c;我们需要对数据库的表结构进行修改&#xff0c;向部分表中追加字段&#xff0c;并对追加后的字段进行数据填充。但是如果需要追加…

C++ STL之队列queue和双端队列deque

一. 概述 1.1 queue std::queue 是 C STL 中的一个容器适配器&#xff0c;用于实现先进先出&#xff08;FIFO&#xff0c;First In First Out&#xff09;的数据结构&#xff0c;它允许在一端添加元素&#xff08;称为队尾&#xff09;&#xff0c;并在另一端移除元素&#x…

《算法笔记》例题解析 第3章入门模拟--4日期处理(9题)2021-03-03

日期 题目描述 Time Limit: 1000 ms Memory Limit: 256 mb 今天是2012年4月12日星期四&#xff0c;编写程序&#xff0c;输入今天开始到12月31日之间的任意日期&#xff0c;输出那一天是星期几。例如输入“5&#xff08;回车&#xff09;20&#xff08;回车&#xff09;”&am…

DETR论文翻译与理解

DETR&#xff08;Detection with transformer&#xff09; DETR&#xff1a;End to End Object Detection with Transformer 论文链接&#xff1a;2005.12872 (arxiv.org) 参考视频&#xff1a;https://www.bilibili.com/video/BV1GB4y1X72R/?spm_id_from333.788&vd_…

C++学习笔记(37)

302、makefile 在实际开发中&#xff0c;项目的源代码文件比较多&#xff0c;按类型、功能、模块分别存放在不同的目录和文件中&#xff0c;哪 些文件需要先编译&#xff0c;那些文件后编译&#xff0c;那些文件需要重新编译&#xff0c;还有更多更复杂的操作。 make 是一个强大…

mysql性能优化- 数据库配置优化

MySQL 性能优化 - 数据库配置优化 MySQL 是一个广泛使用的关系型数据库管理系统&#xff0c;但随着数据量的增长和访问频率的提高&#xff0c;其性能可能会成为瓶颈。为了保持高效的性能&#xff0c;除了应用层的查询优化和索引优化之外&#xff0c;数据库配置优化 也是非常重…

硬件工程师笔试面试——开关

目录 11、开关 11.1 基础 开关原理图 开关实物图 11.1.1 概念 11.1.2 常见的开关类型及其应用 11.2 相关问题 11.2.1 开关的工作原理是什么? 11.2.2 在设计一个电子系统时,如何选择最适合的开关类型? 11.2.3 不同类型的开关在实际应用中有哪些优势和局限性? 11.…

爵士编曲:爵士鼓编写 爵士鼓笔记 底鼓和军鼓 闭镲和开镲 嗵鼓

底鼓和军鼓 底鼓通常是动的音色&#xff0c;军鼓通常是大的音色。 “动”和“大”构成基础节奏。“动大”听着不够有连接性&#xff0c;所以可以加入镲片&#xff01; 开镲 直接鼓棒敲击是开镲音色 闭镲 当脚踩下踏板&#xff0c;2个镲片合并&#xff0c;然后用鼓棒敲击&am…

C++ Linux IPC进程通信-消息队列MQ

原文链接&#xff1a;C Linux IPC进程通信-消息队列MQ 消息队列库<sys/msg.h> 相比于共享内存和管道,消息队列能够实现指定的消息格式和排序,能实现更复杂的通信 库函数 // 创建消息队列 int msgget(key_t, key, int msgflg); return ID(成功) -1(错误)key为一个标记…

java(3)数组的定义与使用

目录 1.前言 2.正文 2.1数组的概念 2.2数组的创建与初始化 2.2.1数组的创建 2.2.1数组的静态初始化 2.2.2数组的动态初始化 2.3数组是引用类型 2.3.1引用类型与基本类型区别 2.3.2认识NULL 2.4二维数组 2.5数组的基本运用 2.5.1数组的遍历 2.5.2数组转字符串 2.…

面向对象程序设计——set容器の简析

1.set的介绍 • 序列式容器和关联式容器 • 我们已经接触过STL中的部分容器如&#xff1a;string、vector、list、deque、array、forward_list等&#xff0c;这些容器统称为序列式容器&#xff0c;因为逻辑结构为线性序列的数据结构&#xff0c;两个位置存储的值之间⼀般没有紧…

图片马赛克处理(Java)

1.需求 给图片的指定区域打码给整张图片打码马赛克方格取色支持中心点取色和随机取色马赛克支持灰度处理 2.源码 package com.visy.utils;import javax.imageio.ImageIO; import java.awt.*; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOE…

screen使用——关机时在服务器上跑代码

一、连接服务器 原理:通过 SSH(Secure Shell)协议建立本地与远程服务器的安全连接通道,使得可以在本地操作服务器。 操作:使用 VSCode 或 cmd 的 ssh 连接到服务器,这里我选择cmd。 检查是否安装 OpenSSH 在 Windows 10 及以上版本中,系统可能已经自带 OpenSSH 客户端…

(k8s)Kubernetes部署Promehteus

转载&#xff1a;Kubernetes&#xff08;k8s&#xff09;部署Promehteus 一、概述 在1.8版本以后heapster由metrics-server替代&#xff1b;从k8s的v1.11版本开始已经全面转向以Prometheus为核心的新监控体系架构&#xff1b;kube-prometheus 中包含了 prometheus 监控所用到的…