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...

相关推荐
咔叽布吉10 分钟前
【前端学习笔记】ES6 新特性
前端·笔记·学习
推开世界的门43 分钟前
web 中 canvas 污染 以及解决方案
前端
星离~1 小时前
css—轮播图实现
前端·css
龙雨LongYu121 小时前
vue3+ts 我写了一个跟swagger.yml生成请求和响应实体(接口)
前端·vue.js·typescript
Stanford_11062 小时前
关于IDE的相关知识之一【使用技巧】
前端·ide·windows·微信小程序·微信公众平台·twitter·微信开放平台
_志哥_2 小时前
web开发环境下启动HTTPS服务访问
前端·javascript·https
爱健身的小刘同学2 小时前
安装 electron 依赖报错
前端·javascript·electron
耶啵奶膘2 小时前
uniapp+vue2+uview2.0导航栏组件二次封装
前端·javascript·uni-app
布兰妮甜2 小时前
如何使用 Tailwind CSS 构建响应式网站:详细指南
前端·css·tailwind css
MavenTalk2 小时前
前端技术选型之uniapp
android·前端·flutter·ios·uni-app·前端开发