当前位置: 首页 > news >正文

【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渲染案例&#xff08;离线渲染一个三角面&#xff0c;然后渲染到一个占满屏幕的矩阵上&#xff09; 离线渲染如何需要开启深度测试的话&#xff0c;需要额外操作&#xff0c;这里不展开 <!DOCTYPE html> <html lang"en"><head><meta ch…...

Unity面板介绍_层级面板(23.1.1)

一、Inspector(检视面板) 显示当前选定游戏对象附加的组件及其属性信息。为重要游戏物体选择图标 二、面板详情...

详解Nginx 配置

一、Nginx 介绍 Nginx 是一款轻量级的 Web 服务器 / 反向代理服务器及电子邮件&#xff08;IMAP/POP3&#xff09;代理服务器。它由俄罗斯的程序设计师 Igor Sysoev 所开发&#xff0c;自 2004 年发布以来&#xff0c;凭借其高性能、低内存消耗、高并发处理能力等特点&#xf…...

数据库系统概念

1. 绪论 数据库的基本概念: 数据(data): 数据库中存储的基本对象, 可以是文字, 声音, 图片, 视频等。 数据库(DB): 概括来说就是永久存储, 有组织, 可共享的大量数据的集合。 数据库管理系统(DBMS): 和操作系统一样是计算机基础软件, 主要有数据定义语言(DDL, 对数据对象的组…...

51单片机学习之旅——定时器

打开软件 1与其它等于其它&#xff0c;0与其它等于0 1或其它等于1&#xff0c;0或其它等于其它 TMODTMOD&0xF0;//0xF01111 0000进行与操作&#xff0c;高四位保持&#xff0c;低四位清零&#xff0c;高四位定时器1&#xff0c;低四位定时器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的校园消费点评管理系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏&#xff1a;…...

【小沐学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 是一个轻量级但功能强大的源代码编辑器&#xff0c;可在桌面上…...

《操作系统 - 清华大学》8 -4:进程管理:进程控制结构

深度剖析进程控制块&#xff1a;操作系统进程管理的核心关键 在操作系统的复杂体系中&#xff0c;进程控制块&#xff08;PCB&#xff09;是实现高效进程管理的关键所在。接下来&#xff0c;将从多个维度深入剖析进程控制块&#xff0c;帮助更好地理解其在操作系统中的重要作用…...

RPC 框架项目剖析

RPC 框架项目剖析 说明 本文用于梳理一个 rpc项目的实现细节&#xff0c;此项目基于cpp语言 大概三千行左右&#xff0c;用于学习目的。 项目链接&#xff1a;rpc项目 项目底层类 1.抽象消息类 描述&#xff1a; 各种消息的基类 属性&#xff1a; 消息id&#xff0c;消息类型…...

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编码&#xff0c;即在文件系统上&#xff0c;文件的编码格式为ascii编码&#xff0c;在编辑器&#xff08;idea/pycharm&#xff09;中&#xff0c;其展现结果为配置的编码格式&#xff0c;仅展现方便阅读 使用UTF-8并勾选自动转换ASCII编码结果&#x…...

js数据类型检测

JavaScript的数据类型检测 typeof操作符 适用场景 基本数据类型快速判断&#xff1a;适用于快速判断变量是否为number、string、boolean、undefined、function等基本数据类型。比如在函数参数检查中&#xff0c;若要求传入数字参数&#xff0c;可用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. 问题背景 在项目开发中&#xff0c;我们需要实现一个复杂的分页查询功能&#xff0c;涉及大量 IP 地址数据的处理和多表关联。在我接手这个项目的时候,代码是这样的 要知道代码里面的 ipsList 数据可能几万条甚至更多,这样拼接的sql,必然是要内存溢出的,一味地扩大jvm参数不…...

基于 Python 的项目管理系统开发

基于 Python 的项目管理系统开发 一、引言 在当今快节奏的工作环境中&#xff0c;有效的项目管理对于项目的成功至关重要。借助信息技术手段开发项目管理系统&#xff0c;能够显著提升项目管理的效率和质量。Python 作为一种功能强大、易于学习且具有丰富库支持的编程语言&…...

java面试场景问题

还在补充&#xff0c;这几天工作忙&#xff0c;闲了会把答案附上去&#xff0c;也欢迎各位大佬评论区讨论 1.不用分布式锁如何防重复提交 方法 1&#xff1a;基于唯一请求 ID&#xff08;幂等 Token&#xff09; 思路&#xff1a;前端生成 一个唯一的 requestId&#xff08;…...

JS宏实例:数据透视工具的制作(四)

上一节中&#xff0c;我们完成了核心的计算代码部分&#xff0c;本节中将完善事件代码 一、创建所有需求的事件函数 1、窗体初始化 // 窗体初始化 function pivotForm_Initialize(){} function typeSet_Initialize(){} function valueSet_Initialize(){} function allCol…...

5. Go 方法(结构体的方法成员)

Go语言没有传统的 class &#xff0c;为了让函数和结构体能够关联&#xff0c;Go引入了“方法”的概念。 当普通函数添加了接收者&#xff08;receiver&#xff09;后&#xff0c;就变成了方法。 一、函数和方法示例 // 普通函数 func Check(s string) string {return s }//…...

day52 ResNet18 CBAM

在深度学习的旅程中&#xff0c;我们不断探索如何提升模型的性能。今天&#xff0c;我将分享我在 ResNet18 模型中插入 CBAM&#xff08;Convolutional Block Attention Module&#xff09;模块&#xff0c;并采用分阶段微调策略的实践过程。通过这个过程&#xff0c;我不仅提升…...

Python如何给视频添加音频和字幕

在Python中&#xff0c;给视频添加音频和字幕可以使用电影文件处理库MoviePy和字幕处理库Subtitles。下面将详细介绍如何使用这些库来实现视频的音频和字幕添加&#xff0c;包括必要的代码示例和详细解释。 环境准备 在开始之前&#xff0c;需要安装以下Python库&#xff1a;…...

涂鸦T5AI手搓语音、emoji、otto机器人从入门到实战

“&#x1f916;手搓TuyaAI语音指令 &#x1f60d;秒变表情包大师&#xff0c;让萌系Otto机器人&#x1f525;玩出智能新花样&#xff01;开整&#xff01;” &#x1f916; Otto机器人 → 直接点明主体 手搓TuyaAI语音 → 强调 自主编程/自定义 语音控制&#xff08;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 限制绕过方案&#xff1a;Java 字节码技术实战分享&#xff08;仅供学习&#xff09; 一、Aspose.PDF 简介二、说明&#xff08;⚠️仅供学习与研究使用&#xff09;三、技术流程总览四、准备工作1. 下载 Jar 包2. Maven 项目依赖配置 五、字节码修改实现代码&#…...

VM虚拟机网络配置(ubuntu24桥接模式):配置静态IP

编辑-虚拟网络编辑器-更改设置 选择桥接模式&#xff0c;然后找到相应的网卡&#xff08;可以查看自己本机的网络连接&#xff09; windows连接的网络点击查看属性 编辑虚拟机设置更改网络配置&#xff0c;选择刚才配置的桥接模式 静态ip设置&#xff1a; 我用的ubuntu24桌…...

MinIO Docker 部署:仅开放一个端口

MinIO Docker 部署:仅开放一个端口 在实际的服务器部署中,出于安全和管理的考虑,我们可能只能开放一个端口。MinIO 是一个高性能的对象存储服务,支持 Docker 部署,但默认情况下它需要两个端口:一个是 API 端口(用于存储和访问数据),另一个是控制台端口(用于管理界面…...

从面试角度回答Android中ContentProvider启动原理

Android中ContentProvider原理的面试角度解析&#xff0c;分为​​已启动​​和​​未启动​​两种场景&#xff1a; 一、ContentProvider已启动的情况 1. ​​核心流程​​ ​​触发条件​​&#xff1a;当其他组件&#xff08;如Activity、Service&#xff09;通过ContentR…...

6个月Python学习计划 Day 16 - 面向对象编程(OOP)基础

第三周 Day 3 &#x1f3af; 今日目标 理解类&#xff08;class&#xff09;和对象&#xff08;object&#xff09;的关系学会定义类的属性、方法和构造函数&#xff08;init&#xff09;掌握对象的创建与使用初识封装、继承和多态的基本概念&#xff08;预告&#xff09; &a…...

Python常用模块:time、os、shutil与flask初探

一、Flask初探 & PyCharm终端配置 目的: 快速搭建小型Web服务器以提供数据。 工具: 第三方Web框架 Flask (需 pip install flask 安装)。 安装 Flask: 建议: 使用 PyCharm 内置的 Terminal (模拟命令行) 进行安装,避免频繁切换。 PyCharm Terminal 配置建议: 打开 Py…...