【WebGL】fbo双pass案例
双pass渲染案例(离线渲染一个三角面,然后渲染到一个占满屏幕的矩阵上)
离线渲染如何需要开启深度测试的话,需要额外操作,这里不展开
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>WebGL 2 Offline Rendering and Texture Display</title>
</head><body><canvas id="glCanvas" width="800" height="600"></canvas><script>// 将 WebGL 初始化和渲染逻辑封装到一个函数中function initWebGL() {// 获取 canvas 元素const canvas = document.getElementById('glCanvas');// 获取 WebGL 2 上下文const gl = canvas.getContext('webgl2');// 如果无法获取 WebGL 2 上下文,给出提示并结束函数if (!gl) {alert('无法初始化 WebGL 2,你的浏览器可能不支持。');return;}// 离线渲染的着色器代码const offlineVertexShaderSource = `#version 300 esin vec2 a_position;void main() {gl_Position = vec4(a_position, 0.0, 1.0);}`;const offlineFragmentShaderSource = `#version 300 esprecision mediump float;out vec4 fragColor;void main() {fragColor = vec4(1.0, 0.0, 0.0, 1.0);}`;// 最终渲染到屏幕的着色器代码const finalVertexShaderSource = `#version 300 esin vec2 a_position;in vec2 a_texCoord;out vec2 v_texCoord;void main() {gl_Position = vec4(a_position, 0.0, 1.0);v_texCoord = a_texCoord;}`;const finalFragmentShaderSource = `#version 300 esprecision mediump float;in vec2 v_texCoord;uniform sampler2D u_texture;out vec4 fragColor;void main() {fragColor = texture(u_texture, v_texCoord);}`;// 创建着色器函数function createShader(gl, type, source) {const shader = gl.createShader(type);gl.shaderSource(shader, source);gl.compileShader(shader);const success = gl.getShaderParameter(shader, gl.COMPILE_STATUS);if (success) {return shader;}console.log(gl.getShaderInfoLog(shader));gl.deleteShader(shader);}// 创建着色器程序函数function createProgram(gl, vertexShader, fragmentShader) {const program = gl.createProgram();gl.attachShader(program, vertexShader);gl.attachShader(program, fragmentShader);gl.linkProgram(program);const success = gl.getProgramParameter(program, gl.LINK_STATUS);if (success) {return program;}console.log(gl.getProgramInfoLog(program));gl.deleteProgram(program);}// 创建离线渲染的着色器程序const offlineVertexShader = createShader(gl, gl.VERTEX_SHADER, offlineVertexShaderSource);const offlineFragmentShader = createShader(gl, gl.FRAGMENT_SHADER, offlineFragmentShaderSource);const offlineProgram = createProgram(gl, offlineVertexShader, offlineFragmentShader);// 创建最终渲染的着色器程序const finalVertexShader = createShader(gl, gl.VERTEX_SHADER, finalVertexShaderSource);const finalFragmentShader = createShader(gl, gl.FRAGMENT_SHADER, finalFragmentShaderSource);const finalProgram = createProgram(gl, finalVertexShader, finalFragmentShader);// 离线渲染的顶点数据const offlinePositions = [-0.5, -0.5,0.5, -0.5,0.0, 0.5];// 创建离线渲染的顶点缓冲区const offlinePositionBuffer = gl.createBuffer();gl.bindBuffer(gl.ARRAY_BUFFER, offlinePositionBuffer);gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(offlinePositions), gl.STATIC_DRAW);// 获取离线渲染的顶点属性位置const offlinePositionAttributeLocation = gl.getAttribLocation(offlineProgram, 'a_position');gl.enableVertexAttribArray(offlinePositionAttributeLocation);gl.vertexAttribPointer(offlinePositionAttributeLocation, 2, gl.FLOAT, false, 0, 0);// 创建帧缓冲区对象(FBO)const framebuffer = gl.createFramebuffer();gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);// 创建纹理对象const texture = gl.createTexture();gl.bindTexture(gl.TEXTURE_2D, texture);gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, canvas.width, canvas.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_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.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);// 检查帧缓冲区是否完整if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) !== gl.FRAMEBUFFER_COMPLETE) {console.error('帧缓冲区不完整');}// 离线渲染gl.useProgram(offlineProgram);gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);gl.viewport(0, 0, canvas.width, canvas.height);gl.clearColor(0.0, 0.0, 0.0, 1.0);gl.clear(gl.COLOR_BUFFER_BIT);gl.drawArrays(gl.TRIANGLES, 0, 3);// 最终渲染到屏幕的顶点数据和纹理坐标const finalPositions = [-1.0, -1.0,1.0, -1.0,-1.0, 1.0,-1.0, 1.0,1.0, -1.0,1.0, 1.0];const finalTexCoords = [0.0, 0.0,1.0, 0.0,0.0, 1.0,0.0, 1.0,1.0, 0.0,1.0, 1.0];// 创建最终渲染的顶点缓冲区和纹理坐标缓冲区const finalPositionBuffer = gl.createBuffer();gl.bindBuffer(gl.ARRAY_BUFFER, finalPositionBuffer);gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(finalPositions), gl.STATIC_DRAW);const finalTexCoordBuffer = gl.createBuffer();gl.bindBuffer(gl.ARRAY_BUFFER, finalTexCoordBuffer);gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(finalTexCoords), gl.STATIC_DRAW);// 获取最终渲染的顶点属性位置和纹理坐标属性位置const finalPositionAttributeLocation = gl.getAttribLocation(finalProgram, 'a_position');gl.enableVertexAttribArray(finalPositionAttributeLocation);gl.vertexAttribPointer(finalPositionAttributeLocation, 2, gl.FLOAT, false, 0, 0);const finalTexCoordAttributeLocation = gl.getAttribLocation(finalProgram, 'a_texCoord');gl.enableVertexAttribArray(finalTexCoordAttributeLocation);gl.vertexAttribPointer(finalTexCoordAttributeLocation, 2, gl.FLOAT, false, 0, 0);// 获取最终渲染的纹理采样器位置const textureUniformLocation = gl.getUniformLocation(finalProgram, 'u_texture');// 最终渲染到屏幕gl.useProgram(finalProgram);gl.bindFramebuffer(gl.FRAMEBUFFER, null);gl.viewport(0, 0, canvas.width, canvas.height);gl.clearColor(0.0, 0.0, 0.0, 1.0);gl.clear(gl.COLOR_BUFFER_BIT);gl.activeTexture(gl.TEXTURE0);gl.bindTexture(gl.TEXTURE_2D, texture);gl.uniform1i(textureUniformLocation, 0);gl.drawArrays(gl.TRIANGLES, 0, 6);}// 调用封装好的函数来初始化和渲染 WebGLinitWebGL();</script>
</body></html>
相关文章:
【WebGL】fbo双pass案例
双pass渲染案例(离线渲染一个三角面,然后渲染到一个占满屏幕的矩阵上) 离线渲染如何需要开启深度测试的话,需要额外操作,这里不展开 <!DOCTYPE html> <html lang"en"><head><meta ch…...
Unity面板介绍_层级面板(23.1.1)
一、Inspector(检视面板) 显示当前选定游戏对象附加的组件及其属性信息。为重要游戏物体选择图标 二、面板详情...
详解Nginx 配置
一、Nginx 介绍 Nginx 是一款轻量级的 Web 服务器 / 反向代理服务器及电子邮件(IMAP/POP3)代理服务器。它由俄罗斯的程序设计师 Igor Sysoev 所开发,自 2004 年发布以来,凭借其高性能、低内存消耗、高并发处理能力等特点…...
数据库系统概念
1. 绪论 数据库的基本概念: 数据(data): 数据库中存储的基本对象, 可以是文字, 声音, 图片, 视频等。 数据库(DB): 概括来说就是永久存储, 有组织, 可共享的大量数据的集合。 数据库管理系统(DBMS): 和操作系统一样是计算机基础软件, 主要有数据定义语言(DDL, 对数据对象的组…...
51单片机学习之旅——定时器
打开软件 1与其它等于其它,0与其它等于0 1或其它等于1,0或其它等于其它 TMODTMOD&0xF0;//0xF01111 0000进行与操作,高四位保持,低四位清零,高四位定时器1,低四位定时器0 TMODTMOD|0x01;//0x010000 0…...
一台服务器将docker image打包去另一天服务器安装这个镜像
一台服务器将docker image打到去另一天服务器安装这个镜像 1. 打包2.另一台服务器执行 1. 打包 docker save -o nebula-graph-studio.tar harbor1.vm.example.lan/dockerio/vesoft/nebula-graph-studioxxx.tar 是打包好的文件 后面的是 docker image 2.另一台服务器执行 docke…...
QT串口通信之二,实现单个温湿度传感器数据的采集(采用Qt-modbus实现)
接上 QT串口通信之一,实现单个温湿度传感器数据的采集 上述文章中用QSerialPort实现了温湿度传感器的采集,实际上比较麻烦的,因为需要自定义解析帧, 接下来,用Qt-modbus-封装度更高的协议,来实现温湿度的采集; #include "MainWindow.h" #include "ui_M…...
基于SpringBoot的校园消费点评管理系统
作者:计算机学姐 开发技术:SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等,“文末源码”。 专栏推荐:前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏:…...
【小沐学Java】VSCode搭建Java开发环境
文章目录 1、简介2、安装VSCode2.1 简介2.2 安装 3、安装Java SDK3.1 简介3.2 安装3.3 配置 4、安装插件Java Extension Pack4.1 简介4.2 安装4.3 配置 结语 1、简介 2、安装VSCode 2.1 简介 Visual Studio Code 是一个轻量级但功能强大的源代码编辑器,可在桌面上…...
《操作系统 - 清华大学》8 -4:进程管理:进程控制结构
深度剖析进程控制块:操作系统进程管理的核心关键 在操作系统的复杂体系中,进程控制块(PCB)是实现高效进程管理的关键所在。接下来,将从多个维度深入剖析进程控制块,帮助更好地理解其在操作系统中的重要作用…...
RPC 框架项目剖析
RPC 框架项目剖析 说明 本文用于梳理一个 rpc项目的实现细节,此项目基于cpp语言 大概三千行左右,用于学习目的。 项目链接:rpc项目 项目底层类 1.抽象消息类 描述: 各种消息的基类 属性: 消息id,消息类型…...
C++ Boost面试题大全及参考答案
目录 boost::thread_group 如何实现批量线程管理? 解释 boost::asio 中 proactor 模式的设计原理 使用 boost::atomic 实现无锁环形缓冲区 boost::mutex 与 std::mutex 在异常安全上的差异 如何用 boost::condition_variable 实现生产者 - 消费者模型 当 boost::shared_p…...
关于Transparent native-to-ascii conversion
1、功能 自动转换ASCII编码,即在文件系统上,文件的编码格式为ascii编码,在编辑器(idea/pycharm)中,其展现结果为配置的编码格式,仅展现方便阅读 使用UTF-8并勾选自动转换ASCII编码结果&#x…...
js数据类型检测
JavaScript的数据类型检测 typeof操作符 适用场景 基本数据类型快速判断:适用于快速判断变量是否为number、string、boolean、undefined、function等基本数据类型。比如在函数参数检查中,若要求传入数字参数,可用typeof来初步判断。函数类型…...
go 模块管理
go version 查看版本 go version go1.21.12 windows/amd64 需要保证:go的版本升级为1.11以上,go mod依赖的最底版本 go env 查看go的环境变量 go env 开启go mod # 标识开启go的模块管理 set GO111MODULE=on GO111MODULE有三个值:off, on和auto(默认值)。 GO111M…...
记一次复杂分页查询的优化历程:从临时表到普通表的架构演进
1. 问题背景 在项目开发中,我们需要实现一个复杂的分页查询功能,涉及大量 IP 地址数据的处理和多表关联。在我接手这个项目的时候,代码是这样的 要知道代码里面的 ipsList 数据可能几万条甚至更多,这样拼接的sql,必然是要内存溢出的,一味地扩大jvm参数不…...
基于 Python 的项目管理系统开发
基于 Python 的项目管理系统开发 一、引言 在当今快节奏的工作环境中,有效的项目管理对于项目的成功至关重要。借助信息技术手段开发项目管理系统,能够显著提升项目管理的效率和质量。Python 作为一种功能强大、易于学习且具有丰富库支持的编程语言&…...
java面试场景问题
还在补充,这几天工作忙,闲了会把答案附上去,也欢迎各位大佬评论区讨论 1.不用分布式锁如何防重复提交 方法 1:基于唯一请求 ID(幂等 Token) 思路:前端生成 一个唯一的 requestId(…...
JS宏实例:数据透视工具的制作(四)
上一节中,我们完成了核心的计算代码部分,本节中将完善事件代码 一、创建所有需求的事件函数 1、窗体初始化 // 窗体初始化 function pivotForm_Initialize(){} function typeSet_Initialize(){} function valueSet_Initialize(){} function allCol…...
5. Go 方法(结构体的方法成员)
Go语言没有传统的 class ,为了让函数和结构体能够关联,Go引入了“方法”的概念。 当普通函数添加了接收者(receiver)后,就变成了方法。 一、函数和方法示例 // 普通函数 func Check(s string) string {return s }//…...
day52 ResNet18 CBAM
在深度学习的旅程中,我们不断探索如何提升模型的性能。今天,我将分享我在 ResNet18 模型中插入 CBAM(Convolutional Block Attention Module)模块,并采用分阶段微调策略的实践过程。通过这个过程,我不仅提升…...
Python如何给视频添加音频和字幕
在Python中,给视频添加音频和字幕可以使用电影文件处理库MoviePy和字幕处理库Subtitles。下面将详细介绍如何使用这些库来实现视频的音频和字幕添加,包括必要的代码示例和详细解释。 环境准备 在开始之前,需要安装以下Python库:…...
涂鸦T5AI手搓语音、emoji、otto机器人从入门到实战
“🤖手搓TuyaAI语音指令 😍秒变表情包大师,让萌系Otto机器人🔥玩出智能新花样!开整!” 🤖 Otto机器人 → 直接点明主体 手搓TuyaAI语音 → 强调 自主编程/自定义 语音控制(TuyaAI…...
rnn判断string中第一次出现a的下标
# coding:utf8 import torch import torch.nn as nn import numpy as np import random import json""" 基于pytorch的网络编写 实现一个RNN网络完成多分类任务 判断字符 a 第一次出现在字符串中的位置 """class TorchModel(nn.Module):def __in…...
Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习)
Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习) 一、Aspose.PDF 简介二、说明(⚠️仅供学习与研究使用)三、技术流程总览四、准备工作1. 下载 Jar 包2. Maven 项目依赖配置 五、字节码修改实现代码&#…...
VM虚拟机网络配置(ubuntu24桥接模式):配置静态IP
编辑-虚拟网络编辑器-更改设置 选择桥接模式,然后找到相应的网卡(可以查看自己本机的网络连接) windows连接的网络点击查看属性 编辑虚拟机设置更改网络配置,选择刚才配置的桥接模式 静态ip设置: 我用的ubuntu24桌…...
MinIO Docker 部署:仅开放一个端口
MinIO Docker 部署:仅开放一个端口 在实际的服务器部署中,出于安全和管理的考虑,我们可能只能开放一个端口。MinIO 是一个高性能的对象存储服务,支持 Docker 部署,但默认情况下它需要两个端口:一个是 API 端口(用于存储和访问数据),另一个是控制台端口(用于管理界面…...
从面试角度回答Android中ContentProvider启动原理
Android中ContentProvider原理的面试角度解析,分为已启动和未启动两种场景: 一、ContentProvider已启动的情况 1. 核心流程 触发条件:当其他组件(如Activity、Service)通过ContentR…...
6个月Python学习计划 Day 16 - 面向对象编程(OOP)基础
第三周 Day 3 🎯 今日目标 理解类(class)和对象(object)的关系学会定义类的属性、方法和构造函数(init)掌握对象的创建与使用初识封装、继承和多态的基本概念(预告) &a…...
Python常用模块:time、os、shutil与flask初探
一、Flask初探 & PyCharm终端配置 目的: 快速搭建小型Web服务器以提供数据。 工具: 第三方Web框架 Flask (需 pip install flask 安装)。 安装 Flask: 建议: 使用 PyCharm 内置的 Terminal (模拟命令行) 进行安装,避免频繁切换。 PyCharm Terminal 配置建议: 打开 Py…...
