用WebGPU实现基于物理的渲染

在这里插入图片描述

推荐:用 NSDT编辑器 快速搭建可编程3D场景

最近,我花了相当多的时间在 WebGPU 中使用 IBL(基于图像的照明)编写 PBR(基于物理的渲染)渲染器。 PBR 本身并没有什么新奇之处。 这是一项自 2014 年以来就存在的技术,所有现代图形引擎都使用它。 但我还没有看到任何在 WebGPU ThreeJS 中执行此操作的教程,其他人已经实现了它,但阅读这些源代码并不容易。

我很想创建一个完整的 PBR 指南,并提供适当的理论解释,但互联网上已经有很多相关材料,我需要花费几个月的时间才能重新创建它。 我决定只写下与目前互联网上可用的内容相比我必须找出的缺失部分。 因此,对于我们为什么要做这个问题,请参考互联网上可用的丰富资源。 我将回答有关 WebGPU 的问题。
在这里插入图片描述

top:金属表面 bottom:介电表面(塑料)

要记住一件事:我不确定自己在做什么。 我对使用 GPU API 有了很好的掌握,但我对 WebGPU 很陌生,也不是计算机图形编程方面的专家,所以我所做的一些事情可能并没有真正意义。 但这似乎有效!

我这里的所有工作都是基于优秀的 Learn OpenGL 教程。 我已经使用兰伯特漫反射、GGX 高光和 Fresnel Schlick 近似实现了基本的 PBR 着色。 我使用预过滤的环境贴图和辐照度贴图实现了 IBL。

1、什么是PBR?

基于物理的渲染(PBR: Physically Based Rendering)是计算机图形学中最现代的渲染方法。 自 2010 年代以来,它一直是一个研究课题,并且自 2010 年代左右开始变得足够有效,可用于实时游戏引擎。 关于它的两本著名出版物是 Brian Karis 的《虚幻引擎 4 中的真实着色》和 Sébastien Lagarde 和 Charles de Rousiers 的《Moving Frostbite to PBR》。

基本思想是使用光的精确物理特性了,这与之前非常粗略的近似不同。 为了实现实时性能,仍然需要近似和缓存大量计算,但结果比以前更加真实。

PBR 将材料分为两类:金属和电介质。 金属是像镜子一样反射光的材料,电介质是像玻璃一样反射光的材料。 不同之处在于,金属具有大量可以移动并反射光的自由电子,而电介质则没有。 最重要的结果是金属具有镜面反射,而电介质则没有。

2、什么是 IBL?

基于图像的照明(IBL: Image Based Lighting)是一种允许使用环境贴图来照亮场景的技术。 它近似于从所有周围反射并来自各个方向的光,以稍微照亮场景。 它经常用作 PBR 的一部分。

3、什么是WebGPU?

简而言之,WebGPU是 WebGL 的继承者。 它反映了计算机图形 API 的演变,并遵循 Vulkan、Metal 和 DirectX 12 的方法及其较低级别和更明确的设计。

如果你对图形 API 的历史感到好奇,并想了解更多 WebGPU 的诞生方式以及其中采取的妥协措施,请查看这篇精彩的文章:我想谈谈 WebGPU。

4、面临的挑战

有几件事对于刚接触 WebGPU 的人来说可能并不明显,对我来说当然也不明显。 当从 OpenGL 翻译代码时,我遇到了以下问题:

  • 解析 HDR 纹理 – 与 WebGPU 无关,但我以前从未这样做过,事实证明确实存在与 WebGPU 相关的问题。
  • 渲染立方体贴图 - 立方体贴图在 WebGL 中有些特定,因此如何在 WebGPU 中执行它们并不简单。
  • 渲染到立方体贴图 - 在 WebGL/OpenGL 中我们将使用帧缓冲区。 相当于什么?
  • 渲染到 mip 级别并读取特定的 mip 级别 - 要么有一个特定的 API,要么我就注定失败(剧透:API 就在那里)。

5、解析 HDR 纹理

为了解析 HDR 纹理,我使用了 Marcin Ignac 的简单但优秀的 parse-hdr 库。 我只需要处理一个问题:我的平台拒绝处理 rgba32float,但parse-hdr库依赖于 Float32Array。

我发现库 @petamoriken/float16 实现了 Float16Array,并且我成功地使用了它。所以我只是修补了parse-hdr库,然后就可以开始了。

6、渲染立方体贴图

我使用了 WebGPU 示例中的 Cubemap。 那里没有什么特别令人惊讶的。

7、渲染到立方体贴图

我忘了是如何找到它的,但诀窍是在创建视图时传递 baseArrayLayer和 arrayLayerCount。

除此之外,它需要与相应的 OpenGL 解决方案类似的数学运算,例如准备 6 个视图矩阵,一个用于立方体贴图的每个面。

const passEncoder = commandEncoder.beginRenderPass({colorAttachments: [{view: cubemapTexture.createView({baseArrayLayer: i,arrayLayerCount: 1,}),loadOp: "load",storeOp: "store",},],// ...
});

8、渲染到 mip 级别

我使用了 WebGPU 基础教程,特别是在 GPU 上生成 mip 的指南。 诀窍是仅指定与之前的 baseMipLevel 和 mipLevelCount 不同的值。

const passEncoder = commandEncoder.beginRenderPass({colorAttachments: [{view: prefilterTexture.createView({baseArrayLayer: i,arrayLayerCount: 1,baseMipLevel: mip,mipLevelCount: 1,}),clearValue: [0.3, 0.3, 0.3, 1],loadOp: "load",storeOp: "store",},],// ...
});

事实证明,可以使用 textureSampleLevel函数读取特定的mip级别。 这是最令人担忧的部分,因为我知道如果它不能直接在 API 中使用,就没有任何办法解决这个问题。 幸运的是,WebGPU 现在是一个成熟且严肃的 API,可以处理类似的事情。

let prefilteredColor = textureSampleLevel(prefilterMap, // textureourSampler, // samplerr, // texture coordinateroughness * MAX_REFLECTION_LOD, // mip level
).rgb;

9、结束语

点击这里查看完整源代码。

关于渲染技术、优化、妥协等还有很多要补充的,但我不是谈论这些的最佳人选。


原文链接:WebGPU物理渲染实现 — BimAnt

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

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

相关文章

GeoServe Web 管理界面 实现远程访问

文章目录 前言1.安装GeoServer2. windows 安装 cpolar3. 创建公网访问地址4. 公网访问Geo Servcer服务5. 固定公网HTTP地址 前言 GeoServer是OGC Web服务器规范的J2EE实现,利用GeoServer可以方便地发布地图数据,允许用户对要素数据进行更新、删除、插入…

tkinter控件样式

文章目录 以按钮为例共有参数动态属性 tkinter系列: GUI初步💎布局💎绑定变量💎绑定事件💎消息框💎文件对话框💎控件样式扫雷小游戏💎强行表白神器 以按钮为例 tkinter对控件的诸…

47、TCP的流量控制

从这一节开始,我们学习通信双方应用进程建立TCP连接之后,数据传输过程中,TCP有哪些机制保证传输可靠性的。本节先学习第一种机制:流量控制。 窗口与流量控制 首先,我们要知道的是:什么是流量控制&#xff…

【GPT引领前沿】GPT4技术与AI绘图

推荐阅读: 1、遥感云大数据在灾害、水体与湿地领域典型案例实践及GPT模型应用 2、GPT模型支持下的Python-GEE遥感云大数据分析、管理与可视化技术 GPT对于每个科研人员已经成为不可或缺的辅助工具,不同的研究领域和项目具有不同的需求。例如在科研编程…

Mybatis的关联关系配置一对一,一对多,多对多的映射关系

目录 关联关系映射 一对一关联: 一对多关联: 多对多关联: 导入数据库表 一对多 一对一 多对多 关联关系映射 关联关系映射在Mybatis中主要通过三种方式实现:一对一关联和一对多关联及多对多关联。 一对一关联:…

RHCA之路---EX280(5)

RHCA之路—EX280(5) 1. 题目 Using the example files from the wordpress directory under http://materials.example.com/exam280/wordpress create a WordPress application in the farm project For permanent storage use the NFS shares /exports/wordpress and /export…

【STM32】学习笔记-PWR(Power Control)电源控制

PWR(Power Control)电源控制 PWR(Power Control)电源控制是一种技术或设备,用于控制电源的开关和输出。它通常用于电源管理和节能,可以通过控制电源的工作状态来延长电子设备的使用寿命,减少能…

QT建立TCP服务器

QT core gui network *************************************************** #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QTcpServer> //服务器头文件 #include <QTcpSocket>//客户端头文件 #include <QList>//存放客户端…

网易低代码引擎Tango正式开源

一、Tango简介 Tango 是一个用于快速构建低代码平台的低代码设计器框架,借助 Tango 只需要数行代码就可以完成一个基本的低代码平台前端系统的搭建。Tango 低代码设计器直接读取前端项目的源代码,并以源代码为中心,执行和渲染前端视图,并为用户提供低代码可视化搭建能力,…

N5235B是德科技网络分析仪50GHz

181/2461/8938对无源元器件和简单的有源器件执行基本分析 适用于对成本非常敏感的应用&#xff0c;可以在高达 50 GHz 的频率范围内精确测量 S 参数 具有出色的性价比&#xff0c;可用于微波器件制造测试 可以配置经济型解决方案&#xff0c;用于信号完整性测量和材料表征 …

Android列表片段

下面创建第二个片段WorkoutFragment&#xff0c;它包含不同训练项目构成的一个列表&#xff0c;用户可以从这个列表中选择训练项目。 列表视图是只包含一个列表的片段 列表片段是一种专门处理列表的片段&#xff0c;它会自动绑定到一个列表视图&#xff0c;所以不需要另外创建…

关于人工智能的担忧

人工智能的快速发展引发了一系列关于其潜在风险和担忧的讨论。以下是一些常见的人们对人工智能的担忧&#xff1a; 失业问题&#xff1a;人工智能的出现可能会导致很多工作岗位的消失&#xff0c;特别是那些需要重复性劳动的工作。人们担心机器取代人类工作将导致大规模失业和社…

String.format() 格式化字符串的方法, 不同占位符表示的含义及使用方式

学习目标&#xff1a; 目标如下&#xff1a; String.format() 格式化字符串的方法&#xff0c; 不同占位符表示的含义及使用方式 学习内容&#xff1a; 内容&#xff1a; 占位符类型 String.format()方法是一种格式化字符串的方法 字符串&#xff1a;一个占位符"%s&q…

Java设计模式:四、行为型模式-08:策略模式

文章目录 一、定义&#xff1a;策略模式二、模拟场景&#xff1a;策略模式三、违背方案&#xff1a;策略模式3.0 引入依赖3.1 工程结构3.2 优惠券折扣计算类3.3 单元测试 四、改善代码&#xff1a;策略模式4.1 工程结构4.2 策略模式结构图4.3 优惠券折扣实现4.3.1 定义优惠券接…

js中如何判断一个变量的数据类型?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐typeof 运算符⭐instanceof 运算符⭐Object.prototype.toString 方法⭐Array.isArray 方法⭐自定义类型检查⭐null 和 undefined 检查⭐ 写在最后 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 记得点击上方或者右侧链接订…

Python综合案例(基本地图使用)

一、基本地图的使用 基本代码&#xff1a; """ 演示地图可视化的基本使用 """ from pyecharts.charts import Map from pyecharts.options import VisualMapOpts# 准备地图对象 map Map() # 准备数据 data [("北京", 99),("…

鸿鹄工程项目管理系统em Spring Cloud+Spring Boot+前后端分离构建工程项目管理系统

Java版工程项目管理系统 Spring CloudSpring BootMybatisVueElementUI前后端分离 功能清单如下&#xff1a; 首页 工作台&#xff1a;待办工作、消息通知、预警信息&#xff0c;点击可进入相应的列表 项目进度图表&#xff1a;选择&#xff08;总体或单个&#xff09;项目显…

static关键字

static 是Java中的一个关键字&#xff0c;它可以用于修饰类的成员变量和方法&#xff0c;具有特殊的含义和用途。下面是关于static关键字的主要用法和含义&#xff1a; 静态变量&#xff08;Static Variables&#xff09;&#xff1a; 静态变量也称为类变量&#xff0c;它们属于…

Qt鼠标点击事件处理:显示鼠标点击位置(完整示例)

Qt 入门实战教程&#xff08;目录&#xff09; 前驱文章&#xff1a; Qt Creator 创建 Qt 默认窗口程序&#xff08;推荐&#xff09; 什么是事件 事件是对各种应用程序需要知道的由应用程序内部或者外部产生的事情或者动作的通称。 事件&#xff08;event&#xff09;驱动…

【Java 基础篇】Java多态:让你的代码更灵活而强大

多态是面向对象编程中的一个重要概念&#xff0c;它允许我们在不同的对象上调用相同的方法&#xff0c;但根据对象的不同&#xff0c;可以产生不同的行为。在 Java 中&#xff0c;多态性是一个强大的特性&#xff0c;它有助于代码的可扩展性和可维护性。本篇博客将深入探讨 Jav…