大多数浏览器和
Developer App 均支持流媒体播放。
-
探索使用 EDR 的 HDR 渲染
EDR 是 Apple 的高动态范围表示和渲染管线。探索如何在应用中使用 EDR 渲染 HDR 内容,并发挥 HDR 显示的动态范围功能,包括 Apple 的内部显示和 Pro Display XDR。我们将展示游戏和专业 app 开发者如何利用 macOS 上的原生 EDR API 进行更多控制,并提供确定使用 HDR 的适当时机、应用色调映射以及交付 HDR 内容的最佳实践。
资源
- Edit and play back HDR video with AVFoundation
- Editing and Playing HDR Video
- Export HDR media in your app using AVFoundation
- Metal
- Metal Shading Language Specification
- Processing HDR Images with Metal
相关视频
WWDC23
WWDC22
Tech Talks
- 探索参考模式
- 发现 A14 仿生芯片的 Metal 增强功能
- 在你的 app 中支持 Apple Pro Display XDR
- A13 仿生芯片的 Metal 增强功能
- 制作 4K 和 HDR HLS 视频流
- 针对 Apple TV 4K 更新您的 App
- HDR 视频简介
WWDC20
WWDC19
-
下载
你好 我是肯格林鲍姆 来自显示与色彩技术团队 感谢你参加这场 “以EDR进行高动态范围渲染”讲座 我很期待与你分享这项技术 我先大致介绍今天的内容 还有这场讲座的适用对象 我们会先解释EDR的真正涵义 介绍如何用四个步骤 在现有的应用程序中添加EDR 使原有EDR API 更有渲染控制力 最后也会探讨各种EDR相关的 最佳体验
首先 何谓EDR? EDR这个缩写 大家可能不太熟悉
全称是“扩展动态范围”
我们用“EDR”来 同时指称HDR成像 以及我们在平台使用的 HDR渲染技术
这其实类似于颜色管理 或许你对这个更加熟悉 许多类型的应用程序开发者 会对这个话题产生兴趣 首先 有些开发者 可能对计算机图形技术有兴趣 还有高动态范围显示 特别是全新的XDR显示技术 这是Apple近几年推出的技术
其他像是硬核游戏开发者 想打造特别写实 并且刺激的体验 释放渲染引擎中可能早就存在的 光影细节 严格来说 还有专业应用程序开发者 他们可能想以 工作室级别的参考源响应 呈现HDR视频及静态图像
最后是一些应用程序的开发者 虽然他们并不特别针对图像 仍想将HDR静态图像 跟视频内容导入生态系统 HDR的可能性 将通过EDR技术来实现 接下来也会提到 我们超乎想象的显示能力 早已展示于用户手中 生态系统中精美的HDR内容 包括用户拍摄、观看及下载的内容 还有App Store提供的游戏和专业版 HDR应用程序 EDR是一种自适应技术 稍后也会提到 EDR不仅能将HDR内容 映射到各种功能的显示器上 也支持更广泛的 观看条件 你是否注意过画面显示 在明暗环境会有极大差异? 在室内看见的明亮鲜艳色彩 在室外可能因为低动态范围 显得暗淡模糊 显示器并没有改变 在特定亮度设定下 光线永远是一样的 改变的是环境 我们的视觉也会迅速调整 以适应环境 在昏暗环境中 我们的视觉会适应显示内容 也就是主要的光线来源 但在明亮的环境中 用户的视觉主要会适应环境 而非较暗的显示画面 所以内容才会显得暗淡又模糊 影响深色及阴影细节
所以EDR 还有基础环境适应技术 能够适应各种显示参数 例如白点及黑点 还有基准白亮度和动态范围 也就是所谓的“EDR余量” 并使显示器符合用户适应的视觉 EDR的适应力能带来诸多好处 或许最令人讶异的是 能让EDR打造真正的HDR效果 就算是普通的 标准动态范围显示器也可以
也就是在昏暗环境 观看这些显示器时 使用相应的较暗亮度设置 EDR的动态效果 同样能使HDR能力依情况优化 应用在明亮的HDR显示器上 使HDR内容在昏暗的参考环境下 显得明亮动人 在较亮的环境中 动态范围虽减少 却能达到最佳效果 同时能保留阴影细节 例如这张图上的色块 我们多年来推出的装置 多数都支持EDR渲染技术 我们用EDR余量来表示HDR能力 也就是最亮的EDR像素 渲染到显示器上时 能比传统最大SDR白再亮多少倍 EDR余量根据显示能力而有所不同 其他参数也有影响 包括当前亮度调节设置
在一般的背光显示器 包括最新款的Mac和iPad 可提供高达两倍的SDR效果 搭载XDR显示器的iPhone 则提供高达八倍SDR效果的EDR余量 最新iPad Pro的 Liquid视网膜XDR显示器 拥有惊人的16倍SDR效果 一般的HDR 10外接显示器 大约有五倍的SDR效果 可通过Mac、iPad和AppleTV播放 至于Pro Display XDR 渲染程度令人瞠目结舌 具有高达四百倍的SDR效果 只要在默认的XDR预设值 并将亮度设置为最小值的四尼特 不仅许多用户已经 持有HDR显示器 HDR内容也逐渐成为主流 除了商业性的HDR内容 用户也开始 通过自己的iPhone或其他装置 拍摄HDR静态或视频内容 分享到生态系统 许多很棒的应用程序 也已经开始使用EDR 支持EDR技术的顶尖游戏包括 《博德之门3》 《神界:原罪2》 还有《古墓丽影:暗影》 越来越多AppleTV服务 开始提供HDR内容 包括TV应用程序、网飞及YouTube 也有越来越多专业应用程序 开始采用HDR技术 不仅投入更多 也增加平台上开发的 HDR内容 例如Affinity Photo DaVinci Resolve Cinema 4D Final Cut Pro Nuke Pixelmator Pro 这些只是其中一部分 我们将这项技术命名为“EDR” 部分原因是要与“HDR”做区分 因为这个名词 对不同人来说有不同涵义 很多人听到高动态范围 会想到明亮的显示画面 能够生成深黑色 从制作观点来看 会想到内容格式 包括HDR10或杜比视界 就技术层面而言 则是指PQ或HLQ等传递函数 或许在艺术层面 HDR甚至能代表超现实 强调色彩的色调映射 以明亮强光 以及昏暗阴影细节为SDR 把这种SDR色调映射视作RIT的 超高动态范围exr格式图文件 在这张色调图中 发光的灯泡 还有阴影细节一览无遗 不过却失去HDR图像 原先的大幅度动态范围 EDR并非将HDR 转换为强调色彩的SDR 保存所有细节却失去本意 而是进行真正的高动态范围渲染
RIT团队将这18张 数码单镜反光相机的 曝光照合并 形成他们的HDR图像 动态范围高达500,000比1 EDR完全以浮点呈现 图像的主体 也就是这支小台灯 像素质低于基准白的1.0 细节也更加明亮 例如灯泡的发光球体 代表数值接近五百 比灯座亮了五百倍 使用EDR能使基准白 与系统所有要素之间形成映射 包括内容的基准白 还有显示器的基准白 再到用户适应后的视觉 这种映射相当重要 为EDR带来诸多好处 包括使HDR和SDR内容 能同时并存 让HDR显示器的动态范围 在各种环境皆能达到最佳曝光 甚至能让传统SDR显示器 渲染出真正的HDR 同时又能将EDR 尽可能渲染至最佳动态范围 举例来说 在Pro Display XDR上 当亮度调节设置为最大的五百尼特 EDR值可高达3.2 并且毫无过曝 元素越明亮 例如灯头部位 EDR值相对就会越高 将使显示器维持在1600尼特的高峰 若将显示器的亮度设置 调整为最小的四尼特 在昏暗至全黑的环境下 无论是通过亮度自动调节 还是手动调节亮度设置 可渲染高达四百的EDR值 使这张出色的图像 达到最大动态范围 图像中最亮的元素 虽然仍根据显示器 渲染为1600尼特的最大亮度 却能清楚看出灯泡的轮廓 其他细节也同样变得清晰 例如比色检验表上 被照亮的颜色 由于用户的视觉适应了图像中的 四尼特基准白 图像中最亮的元素也能够清楚渲染 变得比灯座亮四百倍
来看看EDR的 浮点HDR成像 跟渲染管线有何关联
既然是浮点 EDR能呈现人眼可接收的所有颜色 正如这张填满色彩的 色度图 同样地 EDR也能呈现 完整渲染状态下会伤害肉眼的亮度 因此EDR成像不会过时 刚才也有提到 EDR不只是一种成像 也是一种HDR渲染管线 EDR是一种能扩展 颜色管理的技术 由Apple所开创 也已经发布许久 例如加速图形处理器颜色管理视频 早在MacOS 10.4 Tiger就发布了 概念类似于同时显示 普通的广色域媒体内容 EDR能使HDR和SDR资源 和谐共存于屏幕中 同时又能得到适当渲染 展示在不同的装置上 除此之外 这也代表开发者能继续使用 现有的SDR资源 并适时加上EDR的协助 来看看EDR呈现的HDR像素值 在视觉上有何效果
EDR是一种浮点表示法 EDR值0.0代表黑色 1.0代表SDR最大值 也称为“基准白”或“UI白” 因此0.0至1.0之间的EDR值 也代表SDR范围 这一点并无改变 这些数值代表图像的主体 在渲染时绝对不会过曝 EDR值若高于1.0 代表数值超过SDR亮度 例如强光和发光表面 这些数值可能使画面极度明亮 虽然也能够成像 渲染时可能出现过曝 EDR是用于驱动显示器 无论显示器 是传统的纯粹功率响应 还是较新的HDR传递函数 来看看Pro Display XDR 以PQ为基底的默认XDR预设值 0.0 EDR通过零尼特的PQ代码 将显示器驱动为零尼特 1.0的EDR值被称为“基准白” 固定由显示器的亮度调节设置 或是自动调节来缩放 XDR预设值的基准白亮度范围 通常介于四至五百尼特之间 来看看这个示例 将数值设定为最大的五百尼特 无论亮度设置为多少 白色峰值在这个预设值内 永远是1600尼特 所以EDR的最大值 也就是最亮的可渲染数值为3.2 只要用1600尼特的白色峰值 除以五百尼特的基准白就能计算出来 因此可以说是有3.2倍的SDR余量 因为这台显示器可渲染的最亮数值 比基准白亮3.2倍 总结来说 只要将Pro Display XDR 设置为默认的XDR预设值 并将显示器亮度 也就是“基准白” 设置为五百尼特 当EDR值介于0.0至3.2 会被显示器渲染为零至1600尼特 EDR 1.0则显示为五百尼特 数值若超越EDR最大值的3.2 会过曝为白色峰值 也就是1600尼特 惊人的是 虽然显示器亮度 降低至最少的四尼特 可渲染的EDR值却高达四百 进而在真实的动态范围内 呈现极致明亮的细节 现在我们已经 大致了解EDR的运作方式 接着就来探讨 如何在应用程序中添加EDR 通过四个步骤 可将EDR添加至多数应用程序 这些步骤都很直截明了 但效果可能并不明显 可能不会得到明确的EDR效果 除非你完整套用所有步骤
首先要求使用EDR功能 将属性添加至适当的框架 层级或主体 接着在缓冲区 层级或应用程序上 连结扩展范围的色域 颜色管理系统 会使EDR值大于1.0的内容过曝 代表没有指定的扩展范围色域 要注意 颜色管理系统 可能只会在 来源及目标色域不符时生效 所以过曝效果可能会不稳定 或是依据内容而变动
第三步是选择一个像素缓冲格式 要能呈现1.0以上的数值 通常会以浮点形式呈现 最后一步 应用程序生成的像素 必须超越SDR 0.0至1的范围 并且有出现发光元素 许多开发者可能想在 现有的应用程序中添加EDR支持效果 想开始使用EDR 最简单的方法 或许就是用HDR视频或静态图像内容
取代现有的SDR内容 再按照方才列出的四个步骤操作 有些应用程序 例如此电邮应用程序 可能只有出现HDR内容时 才会选择性启用EDR AVFoundation的AVPlayer界面 支持越来越多HDR视频格式 例如杜比视界 HDR 10和HLG AVPlayer会自动将适用的格式 渲染为EDR watchOS以外的所有平台皆适用 目前以AVPlayer为基础的应用程序 无须更动就能通过EDR 渲染支持的HDR视频格式 来看看EDR适用的AVPlayer代码示例 同样先用AVPlayer的playerWithURL 建立一个AVPlayer实例 不过我们的示例有指定HDR视频内容 接着用playerLayerWithPlayer 将播放器加入层级 最后将控制器指定为播放器 并要求播放器开始播放 AVFoundation会自动执行 指定动作 将HDR媒体渲染成EDR 并根据内容类型启用和停用EDR 要回放HDR视频则相当简单 接着来谈谈HDR静态图像渲染 ImageIO支持大量HDR图像格式 能轻松解码像素 使其复原成 浮点缓冲的EDR ImageIO在所有平台皆适用 但目前只能用macOS 将解码数值渲染为EDR 接下来会展示 如何将ImageIO为基础的资源 融入应用程序 并以CAMetalLayer来示范 现在来谈谈原生EDR API 先前也提过 原生EDR API 是为了游戏及专业版应用程序所打造 这些开发者可能会想渲染定制内容 并且对HDR媒体的渲染方式 掌握更多控制权 这个API目前适用于macOS 管道包括CAMetalLayer 还有NSOpenGLView 我们用CAMetalLayer来示范 这是首选的原生EDR框架 首先来看看四个步骤 当中的前三步 主动加入EDR 设置扩展范围色域 并选择FP16像素缓冲格式 首先选择加入EDR 将metalLayer的 wantsExtendedDynamicRangeContent 这个属性设置为“yes” 接着将metalLayer的色域 设定成扩展范围色域 例如ExtendedLinearDisplayP3 第三步是将metalLayer的像素格式 调整为浮点格式 例如RGBA16Float 再来看看加入EDR的第四步 也就是实际生成EDR像素 在这个示例中 我们用ImageIO 导入HDR静态图像内容 并将成果渲染为EDR纹理 这比较复杂 所以我们一步一步来说明 先从HDR内容建立CGImage 将解码图像拉进浮点位图 建立浮点纹理 将EDR位图导入纹理中 最后将纹理渲染成 EDR可用的metal管线 首先建立CGImage 从HDRimageURL的指定来源着手 方法包括 CGImageSourceCreateWithURL 还有 CGImageSourceCreateImageAtlndex 接着用CGBitmapContextCreate 建立CGContext 并使用先前 在metalLayer上设置的色域 再将EDR图像 用CGContextDrawImage 拉入浮点内容
现在再来建立 RGBA16Float类型的浮点纹理 方法是用newTextureWithDescriptor 利用CGBitmapContextGetData 导入EDR图像数据 并用replaceRegion进入EDR纹理 现在开发者终于准备就绪 能将EDR纹理 渲染成EDR可用的Metal管线 并享受卓越的成果 有些人仍偏好使用 OpenGL为基础的应用程序 我们会用NSOpenGLView 探讨如何启用EDR 方法和刚才展示的步骤差不多 采用EDR也让我们有机会 彻底掌握颜色管理 但这场讲座并不会谈到这一点 我们会谈到以下几个步骤 选择加入EDR 选择浮点像素缓冲格式 将EDR及内容拉进NSOpenGLView 不需要设置扩展范围色域 因为NSOpenGLView 没有色彩自动管理功能 首先加入EDR 方法是将NSOpenGLView的 “wantsExtendedDynamicRange OpenGLSurface”属性 设置为“yes” 第二步是将像素缓冲格式 设置为NSOpenGLPFAColorFloat 加上ColorSize 64 最后再将EDR数值拉进OpenGLView 启用应用程序 并享受成果 我们已经看完如何在现有的应用程序 启用基本EDR支持服务 接着就来深入谈谈 应用程序启用EDR后的 各种最佳用法 先前提到加入EDR的第四步 是设置扩展范围色域 截至目前的示例 我们都特别设置在 适当的扩展范围色域 但有许多应用程序无法精准设置色域 只能用该框架提供的 默认色域 这经常与显示器 或组成空间相应 由于不是扩展范围 除非采取特殊手段 否则会破坏EDR 我们来谈谈 如何将现有的色域提升至扩展范围 首先是取得现有的色域 在这个例子中 来源是你的浏览窗口 第二步是将色域提升为扩展范围 方法是输入 “CGcolorspaceCreateExtended” 最后一步是指派新生成的 扩展范围色域 到适当的窗口、缓冲区或层级 让无法精准设置色域的应用程序 能够使用EDR 接着我们来探讨 生成EDR内容的最佳做法 我们已经提过 数值超越1.0的EDR内容 但尚未真正合成这个内容 或是从HDR来源进行转换 在生成EDR内容时务必小心 因为有可能出现 可怕的“荧光兔症候群” 内容可能发出怪异的多彩荧光 使精心编排的内容相对变得暗淡 前面也强调过 高于EDR 1.0的像素 只会将强光和发光表面 进行编码 这代表我们不应该 将SDR内容扩展为HDR SDR内容本身与HDR兼容 只要介于原生的0.0至1.0之间 这样能使SDR基准白 与HDR内容相符 当HDR内容编排得太亮 本来应该更暗的元素或阴影 若超越EDR 1.0 跟编排得当的内容相比 就会显得很不自然 用户的视觉可能会开始适应 这种过亮的内容 使其他内容相较之下变得很暗 请参考这个例子 女孩拿着一张18%灰色色卡 这是摄影师和动画师调整曝光的工具 女孩是这张相片的主体 因此摄影师或动画师 会设置曝光 让她等于或低于基准白 才不会出现过曝 用户界面的多数选项 也都不该超过EDR 1.0 不过也有一些例外 包括EDR取色器 或是暂时缩放的用户界面 发出亮光来吸引注意 太阳或云朵等发光表面 还有一些极亮的强光 例如光滑表面的阳光反射 有可能比基准白要亮许多 因此可能超过EDR 1.0 一个场景内最亮的元素 早就因SDR编码形成过曝 SDR内容才能以 0.0到1.0的EDR值正确呈现 有些工作流程会要求将HDR格式 特别转换成EDR 先前也提过 ImageIO能将HDR内容解码为EDR 不需要做进一步的转换 打个比方 HLG被解码为0.0到12.0的EDR范围 而EDR 1.0代表基准白 ImageIO会将其他HDR静态图像格式 解码为各自的特定范围 而EDR 1.0永远代表 来源的基准白 AVFoundation目前无法解码HDR格式 将HDR10转换为EDR 所以必须搭配 EDR渲染来使用 转换方法很简单 包含两个步骤 首先用逆传递函数 转换成线性光源 接着依照媒介的基准白做切割 例如PQ内容为一百尼特 基准白就会映射为EDR值1.0 而PQ最大值一万尼特 则会映射为一百的EDR值 从这张图来看 跟许多相片一样 无论是数位或传统摄影 天空都会过曝成白色 只要介于基准白 也就是1.0的EDR值 EDR就不会使其产生过曝 也就是图像的主体 EDR会使高于基准白的数值过曝 也就是超过当前的EDR最大值 所以无法在当前的系统显示器 还有显示器设置中进行渲染 这些高于基准白的数值 都在强光或发光表面 例如云、天空和太阳 这些图上看不见的东西 即使过曝 通常也没关系 不过并非所有情况都可接受 明亮细节出现过曝 举例来说 这张图像中被阳光照射的飞机 飞过高空云层 有看到蓝色的“HDR11”标志吗? 这组数字 还有下方机身都被照亮 渲染程度可能都超过基准白 所以可能出现过曝 端看显示器的效能 以及当前EDR最大值 如果这组数字 是电影或游戏中的关键剧情要素 就可以使用动态色调映射 借此避免或管理过曝问题 让这组数字清晰可见 来看看应用程序的发展有多成熟 能跟上当前的EDR最大数值 并相应地调整渲染内容 应用程序可以通过接收 NSScreen通知 调整场景主体的亮度 改变场景的曝光度 套用光华效果 甚至是进行柔化处理 确保不会丧失重要细节 目前在NSScreen界面 仅可取得一种动态EDR数值 就是maximumExtendedDynamic RangeColorComponentValue 代表当前可渲染的 最大线性EDR数值 先前也说过 EDR值若超过EDR最大值 便会过曝为EDR最大值 EDR最大值可能出现动态变化 因为这跟其特质有关 例如显示器的亮度或是原彩 后者能随时间自动改变 NSScreen可取得的 另外两个固定的EDR值 不会随时间而改变 对比先前提到的数值 maximumPotentialExtendedDynamic RangeColorComponentValue 不会有改变 最大的EDR线性像素值 可渲染于显示器上 并且不会出现过曝 前提是显示器的亮度 还有其他功能都设置为正常数值 最大的潜在EDR可用于指引决定 例如判断该内容 是否适用SDR或HDR版本 甚至决定 是否有必要启用EDR 请记住名称内有“潜在”两字 当前的可渲染最大值 也就是EDR最大值 有可能低于这个数值 恢复1.0是为了显示器或显示预设值 并非为了支持EDR 最后一项固定数值是 maximumReferenceExtendedDynamic RangeColorComponentValue 对专业版应用程序的开发者最有意思 这些人很重视达到参照标准的 最高精准度 它提供的EDR最大值 能保证渲染后也不会失真 在特定显示器上 也不会过曝或出现色调映射 在不支持参照渲染的显示器上 数值会归零 现在来看看 用NSScreen读取的EDR数值代码示例 这里能看到两个固定EDR值 maxPotential和maxReference EDR值可能因显示器而有所不同 所以务必在 开启应用程序的屏幕上操作 此示例中 我们使用与窗口相连的 NSScreen 应用程序想跟上EDR动态变化 可以接收 “NSWindowDidChangeScreen”通知 接着在收到屏幕变动事件时 请求当前EDR参数 可能会依据当前的 EDR余量信息更改渲染内容 为了完整说明色调映射 我们简短介绍一下 CAMetalLayer的色调映射 适用对象是部分专业版应用程序 可将HLG或HDR10等HDR视频 编写及渲染为 依项目而定的HDR控制参数 系统应用程序 还有先前提过 使用AVPlayer的应用程序 都使用CAMetalLayer色调映射器 提供特定媒体的 光纤对光纤传递函数 并以柔化处理 原本无法渲染的HDR数值 CAMetalLayer色调映射器 可通过“CAEDRMetadata” 属性来启用 在macOS上即可取得 这项示例展示了 启用系统色调映射器的方法 只要设置应用程序中 CAMetalLayer的EDRMetadata属性 有许多EDRMetadata构造函数 可供使用 不仅特定于HDR视频标准 也能掌握提供的信息 这里有一组HLGMetadata构造函数 无须参数 接着是其中一组HDR10构造函数 这里会用到三组参数 最小Explicit和maximunLuminance 两者皆为尼特 再加上opticalOutputScale 通常会设置为 HDR10的一百尼特基准白 建构完毕后 设置应用程序中的 CAMetalLayer结果主体 让该层级渲染的所有内容 都能由系统色调映射器 根据提供的元数据来处理 跟自适应色调映射密切相关的是 应用程序可能会想 跟上当前可渲染的最亮度白 我们已经知道如何从NSScreen 取得当前EDR最大值 但EDR余量是线性数值 而像素通常都以非线性编码 在最后这个示例中 我们会将EDR最大值 转换成应用程序中可能的非线性色域 首先通过 CGColorSpaceCreateWithName 创建线性EDR最大值 也就是想渲染的白色像素 接着将线性EDR最大值像素 转换成应用程序的色域 方法是CGColorCreateCopy ByMatchingToColorSpace 得出的颜色便可用于 所有适用EDR的应用程序 我们还剩下最后一个主题 那就是EDR的功率及性能影响 就像所有的CG渲染 评估EDR对功率及性能的影响 是很复杂的一件事 经常需要特定的硬件体系结构 以及指定装置的显示技术 虽然本讲座不会详谈这些 还是有些值得考虑的重点 例如生成更亮的像素常消耗更多功率 搭配EDR使用的浮点缓冲区可能变大 因此需要的带宽 可能多于定点缓冲区 原先用到的数量 这也进而导致更多功率的消耗 就算启用 CAEDRMetadata为底的色调映射 也会牵涉到额外的通行处理 因此增加延迟和带宽 EDR和许多功能一样 并非百利而无一害 应该谨慎使用 最好的做法就是 在同时拥有HDR内容 以及潜在EDR余量时启用EDR 若非如此则停用EDR 同样在选择要开启或流入 HDR或SDR版本内容时 要看EDR潜在余量 甚至是当前EDR最大值余量 是否远超出1.0 更简单的做法是 当用户能看出差异 才启用EDR 我们在短短的时间内 已经谈到许多EDR的信息 希望你和我一样对EDR感到兴奋 且等不及将它加入你的应用程序 总结来说 EDR适用于macOS iOS、iPadOS和tvOS装置 EDR扩展了你已经在使用的颜色管理 还有SDR成像技术 应用程序能轻松加入EDR EDR能与业界HDR标准兼容 并提供非模型的自适应体验 在各种装置及环境皆适用 请参考其他讲座及资源 了解更多信息 包括HDR视频回放 Apple Pro Display XDR 还有EDR的metal渲染 感谢收看 希望你在接下来的WWDC玩得愉快 [音乐]
-
-
16:00 - AVPlayer automatically uses EDR with HDR content
// Instantiate AVPlayer with HDR Video Content VPLayer* player = [AVPLayer playerWithURL:HDRVideoURL]; AVPlayerLayer* playerLayer = [AVPlayerLayer playerLayerWithPlayer:player]; // Play HDR Video via EDR AVPlayerViewController* controller = [[AVPlayerViewController alloc] init]; controller.player = player; [player play];
-
17:52 - EDR with CAMetalLayer 1
// Opt-in to EDR metalLayer.wantsExtendedDynamicRangeContent = YES; // Set extended-range colorspace metalLayer.colorspace = CGColorSpaceCreateWithName(kCGColorSpaceExtendedLinearDisplayP3); // Select FP16 pixel buffer format metalLayer.pixelFormat = MTLPixelFormatRGBA16Float;
-
18:53 - EDR with CAMetalLayer 2
// Create CGImage from HDR Image CGImageSourceRef isr = CGImageSourceCreateWithURL((CFURLRef)HDRimageURL, NULL); CGImageRef img = CGImageSourceCreateImageAtIndex(isr, 0, NULL); // Draw into floating point bitmap context size_t width = CGImageGetWidth(img); size_t height = CGImageGetHeight(img); CGBitmapInfo info = kCGBitmapByteOrder16Host | kCGImageAlphaPremultipliedLast | kCGBitmapFloatComponents; CGContextRef ctx = CGBitmapContextCreate(NULL, width, height, 16, 0, metalLayer.colorspace, info); CGContextDrawImage(ctx, CGRectMake(0, 0, width, height), img); // Create floating point texture MTLTextureDescriptor* desc = [[MTLTextureDescriptor alloc] init]; desc.pixelFormat = MTLPixelFormatRGBA16Float; desc.textureType = MTLTextureType2D; id<MTLTexture> tex = [metalLayer.device newTextureWithDescriptor:desc]; // Load EDR bitmap into texture const void* data = CGBitmapContextGetData(ctx); [tex replaceRegion:MTLRegionMake2D(0, 0, width, height) mipmapLevel:0 withBytes:data bytesPerRow:CGBitmapContextGetBytesPerRow(ctx)]; // Draw with the texture in your EDR enabled metal pipeline
-
20:30 - EDR with NSOpenGLView
// Opt-in to EDR - (void) viewWillMoveToWindow:(nullable NSWindow *)newWindow { self.wantsExtendedDynamicRangeOpenGLSurface = YES; } // Select OpenGL float pixel buffer format NSOpenGLPixelFormatAttribute attribs[] = { NSOpenGLPFADoubleBuffer, NSOpenGLPFAMultiSample, NSOpenGLPFAColorFloat, NSOpenGLPFAColorSize, 64, NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion4_1Core, 0}; NSOpenGLPixelFormat* pf = [[NSOpenGLPixelFormat alloc] initWithAttributes:attribs]; // Draw EDR content into NSOpenGLView
-
21:46 - EDR with NSOpenGLView
// Get existing colorspace from the window CGColorSpaceRef color_space = [view.window.colorSpace CGColorSpace]; // Promote the colorspace to extended-range CGColorSpaceRef color_space_extended = CGColorSpaceCreateExtended(color_space); // Apply the extended-range colorspace to your app NSColorSpace* extended_ns_color_space = [[NSColorSpace alloc] initWithCGColorSpace:color_space_extended]; view.window.colorSpace = extended_ns_color_space; CGColorSpaceRelease(color_space_extended);
-
29:00 - EDR display change notifications via NSScreen
// Read static values NSScreen* screen = window.screen; double maxPotentialEDR = screen.maximumPotentialExtendedDynamicRangeColorComponentValue; double maxReferenceEDR = screen.maximumReferenceExtendedDynamicRangeColorComponentValue; // Register for dynamic EDR notifications NSNotificationCenter* notification = [NSNotificationCenter defaultCenter]; [notification addObserver:self selector:@selector(screenChangedEvent:) name:NSApplicationDidChangeScreenParametersNotification object:nil]; // Query for latest values - (void)screenChangedEvent:(NSNotification *)notification { double maxEDR = screen.maximumExtendedDynamicRangeColorComponentValue; }
-
30:28 - CAEDRMetadata tone-mapper
// HLG CAEDRMetadata* edrMetaData = [CAEDRMetadata HLGMetadata]; // HDR10 CAEDRMetadata* edrMetaData = [CAEDRMetadata HDR10MetadataWithMinLuminance:minLuminance maxLuminance:maxContentMasteringDisplayBrightness opticalOutputScale:outputScale]; // Set on CAMetalLayer metalLayer.EDRMetadata = edrMetaData;
-
31:35 - Computing your app’s brightest pixel
// Create the linear pixel we want to render double EDRmaxComponents[4] = {EDRmax, EDRmax, EDRmax, 1.0}; CGColorSpaceRef linearColorSpace = CGColorSpaceCreateWithName(kCGColorSpaceExtendedLinearDisplayP3); CGColorRef EDRmaxColorLinear = CGColorCreate(linearColorSpace, EDRmaxComponents); // Convert from linear to application’s colorspace CGColorSpaceRef winColorSpace = [self.window.colorSpace CGColorSpace]; CGColorRef EDRmaxColor = CGColorCreateCopyByMatchingToColorSpace(winColorSpace, kCGRenderingIntentDefault, EDRmaxColorLinear, NULL);
-
-
正在查找特定内容?在上方输入一个主题,就能直接跳转到相应的精彩内容。
提交你查询的内容时出现错误。请检查互联网连接,然后再试一次。