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

预过滤环境光贴图制作教程:第三阶段 - GGX 分布预过滤

核心目标

GGX 分布是 PBR 中模拟粗糙表面高光反射的主流模型,其核心是通过统计分布描述微表面的朝向概率。本阶段的目标是:

  1. 基于第一阶段生成的环境图集,预计算 6 个级别的 GGX 过滤结果(对应不同粗糙度);
  2. 使用蒙特卡洛采样(Monte Carlo Sampling)加速 GGX 卷积计算;
  3. 将预过滤结果存储在环境图集的指定区域,与 Stage 1 的基础数据形成完整的环境数据集合。

这些预计算数据将使实时渲染时无需动态计算复杂的 GGX 卷积,只需直接采样即可获得符合物理规律的高光反射颜色。

准备工作

  • 前置条件:已完成 Stage 1,获得包含基础环境数据的envAtlas
  • 输入资源:sourceCube(原始立方体贴图)、envAtlas(待写入预过滤结果的图集);
  • 工具依赖:Three.js 环境(rendererscenecamera)、样本生成工具(SampleGenerator);
  • 理论基础:了解 GGX 分布模型、蒙特卡洛采样、PBR 高光反射原理。

GGX 分布与预过滤原理

在 PBR 中,表面的高光反射效果由微表面分布函数(NDF) 决定,GGX 是其中应用最广泛的模型,其分布函数为:

对于环境光反射,需要对整个环境贴图按 GGX 分布进行卷积(加权平均),得到该粗糙度下的 “模糊” 环境贴图。由于实时计算这一卷积成本极高,我们通过预计算(离线完成)并存储结果,实时渲染时直接采样,大幅提升性能。

实现步骤详解

步骤 1:明确图集存储区域

预过滤结果将存储在envAtlas的另一部分区域,与上阶段的基础数据分区存放。以 512x512 图集为例,布局如下:

级别(i) 对应粗糙度 图集内位置(x,y) 分辨率(宽 x 高) specularPower(高光强度)
1 (0, 256*s) 256x128 512
2 中低 (0, 256s + 128s) 128x64 128
3 (0, 256s + 128s + 64*s) 64x32 32
4 中高 ... 32x16 8
5 ... 16x8 2
6 极高 ... 8x4 1

  • 级别递增对应粗糙度递增(specularPower递减);
  • 分辨率随级别递增减半(与 Stage 1 逻辑一致,粗糙度越高,所需细节越少)。

步骤 2:顶点着色器(UV 坐标处理)

与 Stage 1 类似,顶点着色器负责传递调整后的 UV 坐标,支持接缝处理:

uniform vec4 uvMod;  // UV调整参数:(scaleU, scaleV, offsetU, offsetV)
varying vec2 vUv;    // 传递给片段着色器的UVvoid main() {// 标准顶点变换:投影到裁剪空间gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);// 计算UV:扩展范围以包含接缝像素vUv = (position.xy * 0.5 + 0.5) * uvMod.xy + uvMod.zw;
}

  • 复用 Stage 1 的 UV 扩展逻辑,通过uvMod确保渲染内容包含接缝像素,避免边缘采样误差。

步骤 3:片段着色器(GGX 预过滤核心逻辑)

片段着色器是本阶段的核心,实现基于蒙特卡洛采样的 GGX 卷积计算,包含样本解码、方向转换、立方体贴图采样等关键步骤。

3.1 基础变量与常量
precision highp float;
varying vec2 vUv;                  // 顶点传递的UV
uniform samplerCube sourceCube;    // 原始立方体贴图
uniform sampler2D samplesTex;      // 预生成的GGX样本纹理
uniform vec2 samplesTexInverseSize;// 样本纹理尺寸的倒数(用于计算UV)
uniform vec4 params;               // [_, specularPower, 接缝缩放系数, _]
const float PI = 3.141592653589793;
const int NUM_SAMPLES = 1024;      // 每个像素的采样数量(平衡质量与性能)
3.2 RGBP 编码(复用 Stage 1 逻辑)

预过滤结果仍采用 RGBP 编码存储,确保 HDR 数据高效压缩:

vec4 encodeRGBP(vec3 source) {vec3 gamma = pow(source, vec3(0.5));  // gamma校正(平方根)float maxVal = min(8.0, max(1.0, max(gamma.x, max(gamma.y, gamma.z))));  // 限制最大范围float v = 1.0 - ((maxVal - 1.0) / 7.0);  // 编码缩放因子v = ceil(v * 255.0) / 255.0;  // 确保8位精度存储return vec4(gamma / (-v * 7.0 + 8.0), v);  // 缩放颜色并返回
}
3.3 方向计算与接缝处理(复用与扩展)

与 Stage 1 相同,需将等矩形 UV 转换为三维方向向量,并处理立方体贴图接缝:

// 球坐标转三维方向向量
vec3 fromSpherical(vec2 uv) {return vec3(cos(uv.y) * sin(uv.x),  // x分量sin(uv.y),              // y分量cos(uv.y) * cos(uv.x)   // z分量);
}// 从等矩形UV计算方向向量(指向环境中的采样点)
vec3 getDirectionEquirect() {// 转换UV范围至球坐标:U→[-π,π],V→[π/2,-π/2](翻转V轴)vec2 spherical = (vec2(vUv.x, 1.0 - vUv.y) * 2.0 - 1.0) * vec2(PI, PI * 0.5);return fromSpherical(spherical);
}// 调整方向向量以减轻立方体贴图接缝
vec3 modifySeams(vec3 dir, float scale
http://www.dtcms.com/a/304208.html

相关文章:

  • Python爬虫实践:高效下载XKCD漫画全集
  • Vue3数组去重方法总结
  • 数据赋能(342)——技术平台——容错性
  • oneapi本地部署接口测试(curl命令方式+postman方式)
  • git中多仓库工作的常用命令
  • C 语言第 12 天学习笔记:函数进阶应用与变量特性解析
  • Accessibility Insights for Windows 使用教程
  • 【Nginx】Nginx进阶指南:解锁代理与负载均衡的多样玩法
  • Apache Ignite 的分布式锁Distributed Locks的介绍
  • VLA--Gemini Robotics On-Device: 将AI带到本地机器人设备上
  • SQL 怎么学?
  • 小程序发票合并功能升级!发票夹直接选,操作更便捷
  • Kafka——消费者组重平衡全流程解析
  • idea运行tomcat日志乱码问题
  • Vue El 基础
  • 考古学家 - 华为OD统一考试(JavaScript 题解)
  • npm : 无法加载文件 D:\Nodejs\node_global\npm.ps1,因为在此系统上禁止运行脚本
  • 复现cacti的RCE(CVE-2022-46169)
  • EM储能网关ZWS智慧储能云应用(17) — 动环监控
  • 鲸鱼小说分销系统v1.0.0公测版更新发布-完成了小说整体基础以及完整分销和数据看板
  • 应广MTP单片机在线烧录技巧
  • 嵌入式学习日志————TIM定时中断之定时器定时中断
  • git使用lfs解决大文件上传限制
  • 【PHP】Swoole:CentOS安装Composer+Hyperf
  • 【C++算法】76.优先级队列_前 K 个高频单词
  • 引领新一代 Web3 金融类应用开发,全景式探析 Injective 生态
  • 乳腺癌病理知识
  • 网络安全的变革:深入洞察 Web3 与传统网络模型
  • 黑客哲学之学习笔记系列(一)
  • 随机森林算法原理及优缺点