PBR相关基础知识

news2024/12/27 11:33:02

文章目录

      • **核心理念**
      • **关键组件与参数**
      • **工作流程**
      • **优势**
      • **挑战与注意事项**
      • 实例展示

基于物理的渲染(Physically Based Rendering, PBR)是一种现代计算机图形学技术,它致力于通过模拟真实世界中光与物质相互作用的物理规律来生成高度逼真、一致且可预测的图像。PBR方法广泛应用于游戏开发、电影制作、建筑设计可视化等对视觉真实感有高要求的领域。以下是一些PBR相关基础知识的要点:

核心理念

  1. 物理真实性:PBR基于对光在不同材质表面行为的精确物理模型,如反射、折射、吸收、散射等现象。这些模型确保无论场景光照条件如何变化,材质的外观表现始终符合实际物理规则。

关键组件与参数

  1. 材质属性

    • Base Color/Albedo:表示材质在理想漫反射照明下的颜色,对于非金属材料,它是表面固有的颜色;对于金属材料,它代表金属的颜色或合金成分。
    • Metallic:用于区分金属和非金属材质。值为1表示纯金属,值为0表示绝缘体或非金属。
    • Roughness/Glossiness:控制表面微观粗糙度,影响反射光的散射程度。粗糙表面会产生模糊、分散的高光,而光滑表面则产生清晰、集中的高光。
    • Specular(在某些工作流中):用于定义材质的镜面反射强度和颜色,但在基于金属的工作流中通常由Metallic和Base Color共同决定。
    • Normal Map:存储表面法线信息,模拟微表面细节,如凹凸、划痕等。
    • Ambient Occlusion (AO):表示物体表面各点受到周围环境遮挡的程度,增加阴影和深度感。
    • Emissive:模拟材质自身发光或光源效果。
  2. 光照模型

    • Microfacet BRDFs(双向反射分布函数):如Cook-Torrance模型,描述光如何在微观粗糙表面上反射和散射。这些模型通常包括一个 diffuse(漫反射)分量和一个 specular(镜面反射)分量。
    • Image-Based Lighting (IBL):使用环境贴图来模拟全局光照效果,包括间接反射、天空光照等。

工作流程

  1. 纹理打包:PBR材质通常使用纹理贴图来存储上述各项属性。纹理打包工具帮助艺术家将多个属性合并到一张或几张贴图中(如Metallic-Roughness、Albedo、Normal等),以优化内存使用和渲染效率。

  2. 材质编辑器:如Unity的Shader Graph或Unreal Engine的Material Editor,提供了直观的界面来调整PBR材质属性,连接纹理,并实时预览渲染结果。

优势

  1. 一致性与可预测性:由于基于物理规则,PBR材质在不同光照条件、视角和距离下表现一致,无需针对特定场景手动调整。

  2. 跨平台与跨引擎兼容性:标准化的PBR工作流程使得材质能在多种渲染引擎和平台上保持相似的外观。

  3. 艺术创作效率:艺术家可以专注于材质的真实质感而非光照特定情况下的表现,减少反复调整工作。

挑战与注意事项

  1. 准确的输入数据:高质量的纹理贴图和恰当的参数设置对于实现真实感至关重要。例如,Base Color贴图应使用sRGB色彩空间,Roughness值应适当压缩以避免过亮或过暗区域。

  2. 性能与优化:虽然PBR能提升视觉质量,但可能增加渲染负担。合理使用LOD(Level of Detail)、纹理压缩、烘焙技术等手段有助于平衡画质与性能。

综上所述,PBR基础知识涵盖了从物理原理、材质属性、光照模型到工作流程、优势与挑战等多个方面。理解和掌握这些知识对于在3D建模、游戏开发、影视制作等领域实现高质量、逼真的视觉效果至关重要。

实例展示

在实际编程中,实现基于物理的渲染(PBR)通常涉及编写或使用复杂的图形渲染管线和着色器代码。由于这一主题的复杂性和篇幅限制,这里无法提供完整的PBR渲染器代码实例。不过,我可以给出一个简化的片段,展示在使用OpenGL和GLSL(OpenGL Shading Language)时,如何编写一个基本的PBR顶点着色器(Vertex Shader)和片段着色器(Fragment Shader)。

请注意,这只是一个非常基础的例子,仅用于演示PBR相关概念在实际代码中的体现。实际应用中,PBR着色器会包含更多细节处理(如光照探头、Irradiance环境贴图、Pre-filtered Mipmapped Radiance Environment Maps等),并且需要配合完整的3D渲染框架和光照系统。

// 顶点着色器(Vertex Shader)

#version 330 core

layout (location = 0) in vec3 a_Position;
layout (location = 1) in vec3 a_Normal;
layout (location = 2) in vec2 a_TexCoord;

out VS_OUT {
    vec3 FragPos; // 片段位置(世界空间)
    vec3 Normal;  // 法线向量(世界空间)
    vec2 TexCoord;
} vs_out;

uniform mat4 u_ModelMatrix;
uniform mat4 u_ViewMatrix;
uniform mat4 u_ProjectionMatrix;
uniform mat3 u_NormalMatrix; // 从模型空间到世界空间的法线变换矩阵

void main()
{
    gl_Position = u_ProjectionMatrix * u_ViewMatrix * u_ModelMatrix * vec4(a_Position, 1.0);
    vs_out.FragPos = vec3(u_ModelMatrix * vec4(a_Position, 1.0));
    vs_out.Normal = normalize(u_NormalMatrix * a_Normal);
    vs_out.TexCoord = a_TexCoord;
}

// 片段着色器(Fragment Shader)

#version 330 core

in VS_OUT {
    vec3 FragPos;
    vec3 Normal;
    vec2 TexCoord;
} fs_in;

out vec4 FragColor;

struct Material {
    sampler2D albedoMap;  // 基色贴图
    sampler2D normalMap;  // 法线贴图
    sampler2D roughnessMap; // 粗糙度贴图
    sampler2D metallicMap; // 金属度贴图
};

uniform Material u_Material;
uniform samplerCube u_IrradianceMap; // 环境辐射贴图
uniform samplerCube u_PrefilterMap;  // 预过滤环境贴图
uniform sampler2D u_BRDFLUT;        // BRDF查找表

uniform vec3 u_CameraPos; // 摄像机位置(世界空间)

vec3 FresnelSchlick(float cosTheta, vec3 F0)
{
    return F0 + (1.0 - F0) * pow(1.0 - cosTheta, 5.0);
}

vec3 CookTorrance(vec3 N, vec3 V, vec3 L, vec3 H, float roughness, float metallic, vec3 albedo)
{
    // 微平面法线分布函数(NDF)
    float alpha = roughness * roughness;
    float a = pow(alpha, 2);
    float D = a / (PI * pow((dot(N, H) * dot(N, H)) * (a - 1) + 1, 2));

    // 观察方向与半程向量之间的Fresnel项
    vec3 F = FresnelSchlick(max(dot(H, V), 0.0), mix(vec3(0.04), albedo, metallic));

    // 几何衰减因子(G)
    float k = (roughness + 1.0) * (roughness + 1.0) / 8.0;
    float G = min(1.0, min((2.0 * dot(N, V) * dot(N, L)) / dot(V, L), (2.0 * dot(N, V) * dot(N, L)) / dot(V, L)) / (k + dot(N, V) * dot(N, L)));

    return D * F * G;
}

void main()
{
    vec3 albedo = texture(u_Material.albedoMap, fs_in.TexCoord).rgb;
    vec3 normal = normalize(texture(u_Material.normalMap, fs_in.TexCoord).rgb * 2.0 - 1.0); // 从切线空间转换回世界空间
    float roughness = texture(u_Material.roughnessMap, fs_in.TexCoord).r;
    float metallic = texture(u_Material.metallicMap, fs_in.TexCoord).r;

    vec3 N = normalize(fs_in.Normal);
    vec3 V = normalize(u_CameraPos - fs_in.FragPos);
    vec3 R = reflect(-V, N);

    // 环境光照(IBL部分)
    vec3 F0 = vec3(0.04); // 对于非金属
    F0 = mix(F0, albedo, metallic); // 对于金属
    vec3 irradiance = texture(u_IrradianceMap, N).rgb;
    vec3 prefilteredColor = textureLod(u_PrefilterMap, R, roughness * 10.0).rgb; // 使用MipMap LOD
    vec2 envBRDF = texture(u_BRDFLUT, vec2(max(dot(N, V), 0.0), roughness)).rg;
    vec3 ambient = irradiance * albedo + prefilteredColor * (F0 * envBRDF.x + envBRDF.y);

    // 直接光照(简单点光源示例,实际应用中应使用光照探头、光源列表等)
    vec3 lightPos = ...; // 光源位置
    vec3 L = normalize(lightPos - fs_in.FragPos);
    vec3 H = normalize(V + L);
    vec3 directLight = CookTorrance(N, V, L, H, roughness, metallic, albedo) * vec3(1.0, 1.0, 1.0); // 假设白色光源

    FragColor = vec4((directLight + ambient) * albedo, 1.0);
}

这个代码示例展示了如何:

  • 在顶点着色器中计算顶点的世界空间位置、法线向量以及纹理坐标。
  • 在片段着色器中采样材质属性(基色、法线、粗糙度、金属度)。
  • 使用Cook-Torrance BRDF模型计算直接光照贡献。
  • 实现基于图像的光照(IBL)部分,包括环境辐射贴图、预过滤环境贴图和BRDF查找表(LUT)的使用。

实际项目中,您还需要编写对应的C++(或其他语言)代码来设置 uniforms(如模型、视图、投影矩阵、光照位置等),并正确绑定和传递纹理数据。此外,还需要实现光照探头系统、环境贴图的生成(如生成Irradiance Map、Prefiltered Map和BRDF LUT)等高级功能。这些内容超出了本示例的范围,但可以通过查阅相关的图形学教程、文档或开源项目来学习和实现。

😍😍 大量H5小游戏、微信小游戏、抖音小游戏源码😍😍
😍😍试玩地址: https://www.bojiogame.sg😍😍
😍看上哪一款,需要源码的csdn私信我😍

————————————————

​最后我们放松一下眼睛
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

JAVA学习笔记30(线程)

1.线程 1.线程的概念 1.线程是由进程创建的,是进程的一个实体 2.一个进程可以拥有多个线程 2.并发 ​ *同一时刻,多个任务交替执行,造成一种"貌似同时"的错觉,单核cpu实现的多任务就是并发 3.并行 ​ *同一时刻&…

Python的round与Excel的round不一样?

Python四舍五入怎么做 round()奇进偶舍round函数既不是“四舍五入”的原则,也不是“四舍六入无成双”的原则。 decimal round() 偶然发现python的round函数和excel的round函数对某些数据的处理结果不一致。有看到博主提到是奇进偶舍的方法,但经过验证和…

elementUi 日期选择器 组件禁止手输

添加:editable"false" <el-date-pickerv-model"formInline.EndTime"type"datetime"placeholder"选择结束时间"format"YYYY-MM-DD HH:mm:ss"value-format"YYYY-MM-DD HH:mm:ss":editable"false">&…

0 transformers入门,HuggingFace!

目录 1 了解 2 文本分类 1 了解 1 依赖安装 !pip install transformers -i https://pypi.tuna.tsinghua.edu.cn/simple some-package 2 了解transformers 能做什么 from transformers.pipelines import SUPPORTED_TASKS SUPPORTED_TASKS.items()2 文本分类 我没外网所以…

[2024更新]如何从Android恢复已删除的相机照片?

相信大家都经历过Android手机误删相机图片的经历。您是否正在寻找一种可行的方法来挽救这些丢失的照片&#xff1f;如果这是你迫切想解决的问题&#xff0c;那么这篇文章绝对可以帮助你。然而&#xff0c;与其考虑如何从Android恢复已删除的相机照片&#xff0c;我们更愿意建议…

3D模型人物换装系统(五 模型核批之后模型uv不正确)模型UV不正确

3D模型人物换装系统&#xff08;五 模型核批之后模型uv不正确&#xff09;模型UV不正确 介绍展示Maya导入查看uvUnity中测试分析没合批为什么没有问题总结 介绍 最近在公司里给公司做模型优化合批的时候发现了模型的uv在合批之后无法正常展示&#xff0c;这里找了很多的原因&a…

【竞技宝】中超:泰山队4比1大胜沧州雄狮,费南多独造三球

泰山队在本轮中超主场跟沧州雄狮相遇,这场比赛开打前球迷都觉得主队不好踢。因为,沧州雄狮是中超大黑马,整体战绩可圈可点。另外,泰山队则是境遇不佳,主帅崔康熙饱受球队伤病不断的困扰。最让山东球迷觉得郁闷的是崔康熙上一轮因质疑马宁吹罚,还直接罚到了看台。这就意味着崔康…

2024.4.21周报

目录 摘要 Abstract 文献阅读&#xff1a;Next Item Recommendation with Self-Attentive Metric Learning 问题及方法 论文贡献 方法论 序列感知的推荐系统 神经注意模型 模型&#xff1a;ATTREC 序列推荐 基于Self-Attention的用户短期兴趣建模 用户长期兴趣建模…

MySQL修改数据表的结构

创建数据库 -- create database 创建的数据库名; create database test; 这里创建了一个名为 test 的数据库 选择需要使用的数据库 -- use 数据库名; use test; 这里使用 test 数据库 创建数据表 -- create table 表名(字段名1 数据类型(长度) 约束,字段名2 数据类型(长…

Centos7 的 Open Stack T 版搭建流程 --- (三)配置消息队列

配置消息队列 文章目录 配置消息队列&#xff08;1&#xff09;安装 RabbitMQ 服务并配置新用户权限controller &#xff08;2&#xff09;如何开启图形化&#xff08;拓展&#xff09; &#xff08;1&#xff09;安装 RabbitMQ 服务并配置新用户权限 controller yum install…

开源事件通知库libevent及网络连接管理模块bufferevent详解

目录 1、libevent介绍 1.1、什么是libevent&#xff1f; 1.2、libevent特点 1.3、网络连接管理模块bufferevent 2、bufferevent有什么用&#xff1f; 3、bufferevent的整体设计与实现细节 3.1、整体概况 3.2、evbuffer与bufferevent 3.3、defer callback 4、bufferev…

LLM学习笔记-2

在未标记数据上进行预训练 本章概要 在上节的笔记中&#xff0c;因为训练出的效果&#xff0c;并不是特别理想&#xff0c;在本节中&#xff0c;会用数据进行训练&#xff0c;使得模型更加的好&#xff1b; 计算文本生成损失 inputs torch.tensor([[16833, 3626, 6100],…

知攻善防应急靶场-Windows(Web1-2-3)

知攻善防应急靶场-Web1 1.要求 2.过程 直接扫网站根目录 发现后门 <?php error_reporting(0); session_start();$key"e45e329feb5d925b"; //该密钥为连接密码32位md5值的前16位&#xff0c;默认连接密码rebeyond$_SESSION[k]$key;session_write_close();$postf…

集成学习-Bagging与随机森林回归

reg_fRFR() reg_tDTR()#实例化决策树 cvKFold(n_splits5,shuffleTrue,random_state1412)#实例化验证方式 result_tcross_validate(reg_t#要进行交叉验证的评估器,X,y,cvcv,scoringneg_mean_squared_error#评估指标,return_train_scoreTrue#是否返回训练分数&#xff0c;后面这几…

vue 脚手架创建

脚手架创建 介绍 脚手架是什么呢&#xff0c;就是vue自动创建脚手架的项目模板&#xff0c;用于搭建项目的整体骨架&#xff0c;就比如后端开发时&#xff0c;咱们可以创建一个空项目&#xff0c;一步步创建为mvc项目&#xff0c;但是vs封装了mvc的框架&#xff0c;我们可以直…

房地产行业与软件行业的可持续发展模式对比

一、什么是可持续发展&#xff1f; 可持续发展是一种注重长远发展的经济增长模式&#xff0c;旨在实现经济、社会和环境的协调发展&#xff0c;而不损害未来世代的需求和权益。其核心思想是在满足当前人类需求的同时&#xff0c;不危及地球生态环境的承载能力&#xff0c;保持资…

03-JAVA设计模式-命令模式

命令模式 什么是命令模式 命令模式&#xff08;Command Pattern&#xff09;是一种行为设计模式&#xff0c;它将请求封装为对象&#xff0c;从而使你可用不同的请求把客户端与请求的处理者解耦,也称动作模式或事物模式。 在命令模式中&#xff0c;命令对象封装了接收者对象…

【每日刷题】Day20

【每日刷题】Day20 &#x1f955;个人主页&#xff1a;开敲&#x1f349; &#x1f525;所属专栏&#xff1a;每日刷题&#x1f34d; &#x1f33c;文章目录&#x1f33c; 1. 面试题 17.04. 消失的数字 - 力扣&#xff08;LeetCode&#xff09; 2. 189. 轮转数组 - 力扣&#…

CCF PTA 2023年5月C++富有的大壮

【问题描述】 给在一个神秘的国度&#xff0c;有一种多拿多得的疯狂游戏&#xff0c;某日大壮去参赛&#xff0c;在规定区域内里面有 N(N≤100) 堆金币&#xff0c;第i堆金币的总重量和总价值分别是mi,vi(1≤ mi,vi≤100)。大壮有一个承重量为T(T≤1000) 的背包&#xff0c;但…

kali没有数字签名

一开始以为是国外源访问缓慢问题&#xff0c;更新国内源后依旧报错 解决方案&#xff1a; 你需要下载apt源对应的签名文件&#xff0c;并使用apt-key命令将其添加到系统中。例如&#xff0c;对于Kali的官方源&#xff0c;你可以使用以下命令下载并安装签名文件&#xff1a; …