VisionPro开发 - PBR基本概念


首页:漫游Apple Vision Pro

Code Repo: github.com/xuchi16/vis...

Project Path: github.com/xuchi16/vis...


本文主要包含以下内容:

  • PBR 的基本概念
  • Metallic, roughness 和 opacity 的改变对材质的影响

目标及设计

PBR(Physically based renderring)通过模拟真实世界中光线和材质的相互作用进行物体渲染。它有两种工作流用于定义材料表现:

  • Metallic Roughness Workflow
  • Specular-Glossiness Workflow

两者贴图参数有所区别,但效果相同。从下图可以发现,它们均包含了 6 种贴图,其中有 3 个是相同的(Ambient Occlusion, Normal 和 Height),而另外 3 个有所区别:

  • Metallic Roughness Workflow 使用 baseColor、metallic 和 roughness 贴图来表示材质的颜色、金属度和粗糙度

  • Specular-Glossiness Workflow 则使用 diffuse、glossiness 和 specular 贴图来表示材质的颜色、光泽度和镜面反射率

Apple 推荐了三种 Renderer:RealityKit,SceneKit 和 Storm,均支持 Metallic Roughness Workflow,后续也只详述该工作流。

Metallic Roughness Workflow

Metallic Roughness Workflow 工作流的着色器以金属、粗糙度和基础颜色值作为其核心输入。包含如下 6 种贴图

  • Base Color:提供颜色信息
  • Roughness:提供材料的粗糙程度,浅色表示粗糙,深色表示光滑,可以用来表示镜面上的指纹、桌上的杯子水渍等
  • Metallic:提供对应位置材质是否是金属,如果是金属则为白色,如果不是金属则为黑色
  • Ambient Occlusion:用于表示环境光遮蔽
  • Normal:法线贴图,引擎会根据法线决定光的反射方向
  • Height:表示材质表面的深浅

Metallic 值:0-1 之间,越接近 1,金属度越高

Roughness 值:0-1 之间,越接近 1,粗糙度越高

PBR 的 3 个主要理论

  • 微平面理论:物体表面从微观上看总是粗糙的
  • 能量守恒:出射光线能量不能超过入射光线能量
  • 菲涅尔反射:入射角越大,反射率越高

    • 入射角在 0°到 45°时反射率较低
    • 45°到 75°时反射率逐渐升高
    • 75°到 90°之间时反射率快速趋近于 100%

PBR 光照

Lighting = Ambient + Diffuse + Specular + Emissive

最终颜色 = 环境光 + 漫反射 + 高光反射 + 自发光

双向反射分布函数 BRDF: Bidirectional Reflectance Distribution Function

第一项表示的是物体自发光,后续积分项表示了其他光线的反射情况,其中 BRDF 决定了不同光线的反射方式。不同的光照采用不同的 BRDF 模型,如:

  • Lambertian BRDF:常用于计算漫反射 Diffuse

  • Cook-Torrance BRDF: 常用于计算高光反射 Specular

另外在 PBR 中,环境光通常用 IBL(Image Based Lighting)来计算,RealityKit 也支持 IBL 光照。IBL 的核心概念是生成一张环境贴图,其中包含了场景中的光照信息,在渲染时候引擎根据相机位置从贴图中获取到每个像素的光照信息,再结合物体材质属性,计算出场景中各个像素的光照。

示例基本实现

选定基准位置,在 3 个方向上分别对 roughness,metallic 和 opacity 进行改变即可。

  • x 轴方向:roughness 改变
  • y 轴方向:metallic 改变
  • z 轴方向:opacity 改变
swift 复制代码
private let radius: Float = 0.08
private let interval: Float = 0.2
private let initPosition = SIMD3<Float>(x: 0, y: 0.4, z: -3)
private let matrixSize = 5
    
for roughness in 0...matrixSize {
    for metallic in 0...matrixSize {
        for opacity in 0...matrixSize {
            let r = Float(roughness)
            let m = Float(metallic)
            let o = Float(opacity)
            let xOffset = interval * r
            let yOffset = interval * m
            let zOffset = interval * o
            let position = SIMD3<Float>(x: initPosition.x + xOffset, 
                y: initPosition.y + yOffset, z: initPosition.z + zOffset)
            
            var material = PhysicallyBasedMaterial()
            material.baseColor = PhysicallyBasedMaterial.BaseColor(tint:.orange)
            material.roughness = PhysicallyBasedMaterial.Roughness(floatLiteral: 0.2 * r)
            material.metallic = PhysicallyBasedMaterial.Metallic(floatLiteral: 0.2 * m)
            material.blending = .transparent(opacity: .init(floatLiteral: 0.2 * o))
            
            let sphere = ModelEntity(
                mesh: .generateSphere(radius: radius),
                materials: [material],
                collisionShape: .generateSphere(radius: radius),
                mass: 0.0
            )
            sphere.components.set(InputTargetComponent(allowedInputTypes: .indirect))
            sphere.position = position
            outerEntity.addChild(sphere)
        }
    }
}

最终效果

参考

developer.apple.com/documentati...

developer.apple.com/documentati...

developer.apple.com/documentati...

help.sketchfab.com/hc/en-us/ar...

www.bilibili.com/video/BV1CC...

www.youtube.com/watch?v=_Zb...

相关推荐
逐·風2 小时前
unity关于自定义渲染、内存管理、性能调优、复杂物理模拟、并行计算以及插件开发
前端·unity·c#
Devil枫2 小时前
Vue 3 单元测试与E2E测试
前端·vue.js·单元测试
尚梦3 小时前
uni-app 封装刘海状态栏(适用小程序, h5, 头条小程序)
前端·小程序·uni-app
GIS程序媛—椰子3 小时前
【Vue 全家桶】6、vue-router 路由(更新中)
前端·vue.js
前端青山4 小时前
Node.js-增强 API 安全性和性能优化
开发语言·前端·javascript·性能优化·前端框架·node.js
毕业设计制作和分享4 小时前
ssm《数据库系统原理》课程平台的设计与实现+vue
前端·数据库·vue.js·oracle·mybatis
2401_865854886 小时前
iOS应用想要下载到手机上只能苹果签名吗?
后端·ios·iphone
清灵xmf6 小时前
在 Vue 中实现与优化轮询技术
前端·javascript·vue·轮询
大佩梨6 小时前
VUE+Vite之环境文件配置及使用环境变量
前端
GDAL6 小时前
npm入门教程1:npm简介
前端·npm·node.js