OpenGL - PBR
PBR
,或者用更通俗一些的称呼是指基于物理的渲染(Physically Based Rendering)
,它指的是一些在不同程度上都基于与现实世界的物理原理更相符的基本理论所构成的渲染技术的集合。正因为基于物理的渲染目的便是为了使用一种更符合物理学规律的方式来模拟光线,看起来要更真实一些。
到微观尺度之后任何平面都可以用被称为微平面(Microfacets)
的细小镜面来进行描绘。根据平面粗糙程度的不同,这些细小镜面的取向排列可以相当不一致,微平面的取向方向与中间向量的方向越是一致,镜面反射的效果就越是强烈越是锐利。然后再加上一个介于0到1之间的粗糙度参数,这样我们就能概略的估算微平面的取向情况了:
反射光与折射光它们二者之间是互斥的关系。无论何种光线,其被材质表面所反射的能量将无法再被材质吸收。因此,诸如折射光这样的余下的进入表面之中的能量正好就是我们计算完反射之后余下的能量。
float kS = calculateSpecularComponent(...); // 反射/镜面 部分
float kD = 1.0 - ks; // 折射/漫反射 部分
基于物理的渲染所坚定的遵循的是一种被称为反射率方程(The Reflectance Equation)
的渲染方程的特化版本。
Lo
表示了从ωo
方向上观察,光线投射到点p
上反射出来的辐照度,即所有投射到点p
上的光线的总和。
fr
被称为BRDF
,或者双向反射分布函数(Bidirectional Reflective Distribution Function)
,它的作用是基于表面材质属性来对入射辐射率进行缩放或者加权。
三个函数分别为法线分布函数(Normal Distribution Function)
,菲涅尔方程(Fresnel Rquation)
和几何函数(Geometry Function)
:
- 法线分布函数:估算在受到表面粗糙度的影响下,取向方向与中间向量一致的微平面的数量。这是用来估算微平面的主要函数。
- 几何函数:描述了微平面自成阴影的属性。当一个平面相对比较粗糙的时候,平面表面上的微平面有可能挡住其他的微平面从而减少表面所反射的光线。
- 菲涅尔方程:菲涅尔方程描述的是在不同的表面角下表面所反射的光线所占的比率。
在下面你可以看到在一个PBR渲染管线当中经常会碰到的纹理列表,还有将它们输入PBR渲染器所能得到的相应的视觉输出:
- 反照率:
反照率(Albedo)
纹理为每一个金属的纹素(Texel)(
纹理像素)指定表面颜色或者基础反射率。这和我们之前使用过的漫反射纹理相当类似,不同的是所有光照信息都是由一个纹理中提取的。漫反射纹理的图像当中常常包含一些细小的阴影或者深色的裂纹,而反照率纹理中是不会有这些东西的。它应该只包含表面的颜色(或者折射吸收系数)。 - 法线:法线贴图纹理和我们之前在法线贴图教程中所使用的贴图是完全一样的。法线贴图使我们可以逐片段的指定独特的法线,来为表面制造出起伏不平的假象。
- 金属度:
金属(Metallic)
贴图逐个纹素的指定该纹素是不是金属质地的。根据PBR
引擎设置的不同,美术师们既可以将金属度编写为灰度值又可以编写为1或0这样的二元值。 - 粗糙度:
粗糙度(Roughness)
贴图可以以纹素为单位指定某个表面有多粗糙。采样得来的粗糙度数值会影响一个表面的微平面统计学上的取向度。一个比较粗糙的表面会得到更宽阔更模糊的镜面反射(高光),而一个比较光滑的表面则会得到集中而清晰的镜面反射。某些PBR引擎预设采用的是对某些美术师来说更加直观的光滑度(Smoothness)
贴图而非粗糙度贴图,不过这些数值在采样之时就马上用(1.0 – 光滑度)转换成了粗糙度。 - AO:
环境光遮蔽(Ambient Occlusion)
贴图或者说AO贴图为表面和周围潜在的几何图形指定了一个额外的阴影因子。比如如果我们有一个砖块表面,反照率纹理上的砖块裂缝部分应该没有任何阴影信息。然而AO
贴图则会把那些光线较难逃逸出来的暗色边缘指定出来。在光照的结尾阶段引入环境遮蔽可以明显的提升你场景的视觉效果。网格/表面的环境遮蔽贴图要么通过手动生成,要么由3D建模软件自动生成。
#version 330 core
out vec4 FragColor;
in vec2 TexCoords;
in vec3 WorldPos;
in vec3 Normal;// material parameters
uniform vec3 albedo;
uniform float metallic;
uniform float roughness;
uniform float ao;// lights
uniform vec3 lightPositions[4];
uniform vec3 lightColors[4];uniform vec3 camPos;const float PI = 3.14159265359;float DistributionGGX(vec3 N, vec3 H, float roughness);
float GeometrySchlickGGX(float NdotV, float roughness);
float GeometrySmith(vec3 N, vec3 V, vec3 L, float roughness);
vec3 fresnelSchlickRoughness(float cosTheta, vec3 F0, float roughness);void main()
{ vec3 N = normalize(Normal);vec3 V = normalize(camPos - WorldPos);vec3 F0 = vec3(0.04); F0 = mix(F0, albedo, metallic);// reflectance equationvec3 Lo = vec3(0.0);for(int i = 0; i < 4; ++i) {// calculate per-light radiancevec3 L = normalize(lightPositions[i] - WorldPos);vec3 H = normalize(V + L);float distance = length(lightPositions[i] - WorldPos);float attenuation = 1.0 / (distance * distance);vec3 radiance = lightColors[i] * attenuation; // cook-torrance brdffloat NDF = DistributionGGX(N, H, roughness); float G = GeometrySmith(N, V, L, roughness); vec3 F = fresnelSchlick(max(dot(H, V), 0.0), F0); vec3 kS = F;vec3 kD = vec3(1.0) - kS;kD *= 1.0 - metallic; vec3 nominator = NDF * G * F;float denominator = 4.0 * max(dot(N, V), 0.0) * max(dot(N, L), 0.0) + 0.001; vec3 specular = nominator / denominator;// add to outgoing radiance Lofloat NdotL = max(dot(N, L), 0.0); Lo += (kD * albedo / PI + specular) * radiance * NdotL; } vec3 ambient = vec3(0.03) * albedo * ao;vec3 color = ambient + Lo;color = color / (color + vec3(1.0));color = pow(color, vec3(1.0/2.2)); FragColor = vec4(color, 1.0);
}
OpenGL - PBR相关推荐
- 图形学基础 | 基于物理的渲染理论(PBR)
转载自: https://learnopengl.com/PBR/Theory Learn OpenGL PBR Theory PBR 基于物理的渲染(Physically Based Renderi ...
- OpenGL 基于PBR的specular textured 镜面纹理的实例
OpenGL 基于PBR的specular textured 镜面纹理 先上图,再解答. 完整主要的源代码 源代码剖析 先上图,再解答. 完整主要的源代码 #include <glad/glad ...
- OpenGL基于PBR的irradiance辐照度的实例
OpenGL 基于PBR的irradiance辐照度 先上图,再解答. 完整主要的源代码 源代码剖析 先上图,再解答. 完整主要的源代码 #include <glad/glad.h> #i ...
- OpenGL基于PBR的图像的光照IBL的实例
OpenGL 基于PBR的图像的光照IBL 先上图,再解答. 完整主要的源代码 源代码剖析 先上图,再解答. 完整主要的源代码 #include <glad/glad.h> #includ ...
- Learn OpenGL 笔记7.1 PBR Theory(physically based rendering基于物理的渲染 理论)
PBR,或更通常称为基于物理的渲染,是一组渲染技术,它们或多或少基于与物理世界更接近的相同基础理论.由于基于物理的渲染旨在以物理上合理的方式模拟光线,因此与我们的原始光照算法(如 Phong 和 Bl ...
- OpenGL学习笔记一之PBR篇一 理论
转载自 https://learnopengl-cn.github.io/07%20PBR/01%20Theory/ 本节暂未进行完全的重写,错误可能会很多.如果可能的话,请对照原文进行阅读.如果有报 ...
- OPENGL实时PBR路径追踪实现代码
这里写自定义目录标题 这个是CPU实现的 实现步骤, 1.把光栅化的图片做第一帧 提取出来然后和光线追踪混合显示在屏幕 未实现 2.正题 用24分辨率进行光线追踪 可以大概得出屏幕显示的模型,这样就可 ...
- opengl 贴图坐标控制_材质贴图正确打开方式
哈喽,各位观众朋友们好鸭~欢迎来到讲道理画图的地方,我是黄玮宁. 最近呀经常有小伙伴来问我那些不同通道的材质贴图该怎么用,而且频率不是一般的高,所以我觉得有必要来说说这些通道贴图的用法了. 视频版(B ...
- OpenGL 镜面反射 IBL
OpenGL镜面反射 IBL 镜面反射 IBL简介 蒙特卡洛积分和重要性采样 低差异序列 GGX 重要性采样 捕获预过滤 mipmap 级别 预过滤卷积的伪像 高粗糙度的立方体贴图接缝 预过滤卷积的亮 ...
- OpenGL 漫反射辐照度 Diffuse irradiance
OpenGL 漫反射辐照度 Diffuse irradiance 漫反射辐照度 Diffuse irradiance简介 PBR 和 HDR HDR 和 stb_image.h 立方体贴图的卷积 PB ...
最新文章
- 【强烈推荐】国土档案管理信息系统产品使用说明书系列目录【附下载地址】...
- SCCM2012R2之二安装SQL Server
- ASP.NET 2.0的编译模型
- linux 网络错误 TCP: too many orphaned sockets 解决方法
- SmartMesh WireLess HART 资料总结
- endnote如何导入txt文件_EndNote导入万方文献的方法 | 科研动力
- iso 绝对pe_通用PE工具箱 V5.0(WIN7PE内核)U盘ISO硬盘完美三合一版
- 第一阶段✦第一章☞信息化知识
- 韦伯-费纳希定律,前景理论及其在数据科学中的应用
- 2.Python-简单数据类型
- 宁以pass-by-reference-to-const替换pass-by-value——effective c++学习笔记
- Java框架tk_TKmybatis的框架介绍和原理分析及Mybatis新特性
- 激活Finalshell
- 关于XML解析报错问题(LF、CRLF)
- 第3题:设计一个模拟电信计费程序
- A survey of community search over big graphs
- 【linux】循序渐进学运维-基础篇-kill命令
- vs2017 资源试图加载失败
- Android 圆形头像显示
- PhotoShop学习笔记(一)