Quantcast
Channel: 英特尔开发人员专区文章
Viewing all 583 articles
Browse latest View live

如何使用 Unreal Engine* 构建自定义音频编辑器,在虚拟现实中实现音效空间化

$
0
0

woman in a virtual environment

概述

Epic Games 的 Unreal Engine*拥有一个强大的虚拟现实 (VR) 编辑器选项,但是该选项不具备在虚拟现实中编辑与放置音效的能力。调整音效后,必须不断重启编辑器,才能测试虚拟现实中的音效,这是件非常麻烦的事。因此,我们决定创建一款音效编辑器,以支持游戏开发人员与音效设计师在虚拟现实中快速放置、编辑与测试空间化音效。This will prevent the user from having to constantly enter and exit the editor.

woman in a virtual environment

系统要求

  • Unreal Engine 4.18.1 或更高版本
  • Visual Studio* 2017
  • HTC Vive*

您将学到的知识

  • 动作控制器交互
  • 如何创建一个自定义 C++ 类
  • VR UI
  • 保存编辑器修改
  • 音效空间化参数

下面,我们将从头到尾逐步介绍如何创建这款面向 Unreal Engine 的自定义音频编辑器工具:

项目链接下载

开始前,您需要做几件事。下载并解压项目文件夹。您还需要确保已安装 Unreal Engine 4.18.1 或更高版本。

下载并解压文件夹后,右击 Intel_VR_Audio_Tools.uproject 并选择“生成 Visual Studio 项目文件”(Generate Visual Studio project files)。完成后,打开项目。将出现“缺少 Intel_VR_Audio_Tools 模块”的弹出消息。单击“是”开始重新创建;应该耗时不到 20 秒。鉴于您动态查找添加至项目的 .wav 文件的方式,这是必要的,我们将在自定义 C++ 类章节中予以介绍。

设置虚拟现实播放器

我们首先从 Unreal 虚拟现实模板开始,选择 MotionControllerPawn 作为我们的 pawn,它的动作控制已设置,并支持通过远距传动移动。

动作控制器交互

动作控制器与 3D 小部件交互前,需要将 WidgetInteraction 组件添加至 VirtualRealityBP 文件夹中的 BP_MotionController。我们还需要为音效选择器小部件添加一个名为 soundScene 的场景组件。

widget, motion controller options screenshot

右触发器被启动时,Press 和 Release Pointer key 连接调用的事件。我们需要增加 MotionControllerPawn,它也位于 VirtualRealityBP 文件夹中。

screenshot of widget interaction with right controller

自定义 C++ 类

制作教程时,了解音效的名称和位置以及动态更新小部件以匹配所有文件是一个难以解决的问题,因此,需要重建项目。幸运的是,Unreal Engine 为我们提供了一些帮助。

IntelSoundComponent 是一个可以添加至任意蓝图的 C++ 类,用于动态定位与加载 .wav 文件至 USoundWave,Unreal 也是通过这种方式加载音效文件。

首先,右击内容浏览器并创建一个名为 IntelSoundComponent 的新 C++ 类。该操作创建了一个 IntelSoundComponent.cpp 文件和 IntelSoundComponent.h 文件。

接下来,我们添加定位与管理文件所需的 include。

在 IntelSoundComponent.cpp 中添加了 Paths.h, FileManager.h 和 Runtime/Engine/Classes/Sound/SoundWave.h(因为某些原因,SoundWave.h 前面的部分必不可少)两种 Include。

#include "IntelSoundComponent.h"
#include "Paths.h"
#include "FileManager.h"
#include "Runtime/Engine/Classes/Sound/SoundWave.h"

bool exists;
FString dir, soundDir;
TArray<FString> soundFiles;

// Sets default values for this component's properties
UIntelSoundComponent::UIntelSoundComponent()
{
	// Set this component to be initialized when the game starts, and to be ticked every frame.  You can turn these features
	// off to improve performance if you don't need them.
	PrimaryComponentTick.bCanEverTick = true;

	//Empty soundFiles TArray.Easiest way if new wave files are added.
	soundFiles.Empty();

	//the way Unreal Engine calls the project's root directory
	dir = FPaths::ProjectDir();

	//Combining Root with the folder location for the sounds.
	//This could probably be an external folder if needed with the help of ( IPlatformFile& PlatformFile = FPlatformFileManager::Get().GetPlatformFile(); )
	soundDir = dir + "Content/Sounds";

	//UE4 returns a bool if the directory exists or not.
	exists = FPaths::DirectoryExists(soundDir);

}

代码块。IntelSoundComponent.cpp

现在,我们创建了一个名为 exists 的 bool、两个名为 dir 和 SoundDir 的 FString 变量和一个名为 soundFiles 的 FString TArray。由于 soundFiles 是一个 TArray,我们可以通过调用 soundFiles.Empty() 来清空 TArray。我们相信如果添加了新波形文件,这也是最快的方法。然后,我们将 FString dir 设置为 FPaths::ProjectDir();(提供了项目的根位置)。接下来,我们将 FString soundDir 设置为 dir + "Content/Sounds”,因为它是我们放置 .wav 文件的文件夹。FPaths 可以通过其他方法来检查目录是否存在,因此,我们将 bool 设置为 exists = FPaths::DirectoryExists(soundDir);。

// Called when the game starts
void UIntelSoundComponent::BeginPlay()
{
	Super::BeginPlay();

	//UE4 way of managing files
	IFileManager &fileManager = IFileManager::Get();

	//UE_LOG(LogTemp, Warning, TEXT("%s"), &fileManager);


	if (exists == true){

		//Extensions to sound files.Was using .wav, but .uasset seems to work when there is and isn't an editor.
		FString ext = "/*.wav";
		FString ext2 = "/*.uasset";

		//path = FPaths::ProjectDir() + Content/Sounds + /*.uasset
		FString path = soundDir + ext2;

		//This finds file in the given array, with the given path
		//the true bool is saying to look for files while false bool is saying to not look for directories
		fileManager.FindFiles(soundFiles, *path, true, false);

代码块。IntelSoundComponent.cpp

在 BeginPlay() 上,我们首先使用 IFileManager &fileManager = IFileManager::Get(); 对 IFileManager 进行实例化。我们的目标是调试与测试 .wav 文件是否能被 fileManager.FindFiles 发现,后者搜索 .uassets,而不是我们之前使用的 .wav 文件,因为 .uassets 在共享项目时更可靠。

//Setting soundFileArray to soundFiles to pass into blueprint.
void UIntelSoundComponent::soundArray(TArray<FString> &soundFileArray) {

	soundFileArray = soundFiles;

}

//loading a wav file as a USoundWave so Unreal can set the sound chosen with LoadObject<USoundWave> for blueprint
USoundWave* UIntelSoundComponent::setWavToSoundWave(const FString &fileName) {

	USoundWave* swRef;
	FString name = fileName;

	swRef = LoadObject<USoundWave>(nullptr, *name);

	return swRef;

}

代码块。IntelSoundComponent.cpp

最后,我们在 .cpp 中创建了显示为蓝图节点的两个函数。它们是 SoundArray(将 soundFiles TArray 传输至蓝图)和 setWavToSoundWave(我们花了一些时间才弄清楚,因为我们需要找到一个动态引用 .wav 文件的方法,这个方法必须为 Unreal 所理解,它是一个 USoundWave)。为了解决该问题,我们发现了 LoadObject。如果条件允许的话,该函数在运行时将对象加载至我们设置的任何类型。对我们而言,它是 LoadObject(nullptr, *name);—*name 是虚拟现实玩家选择的音效。

我们在 IntelSoundComponent.h 中创建了两个 UFUNCTION,以调用 .cpp 蓝图中的两个函数。

#include "CoreMinimal.h"
#include "Components/SceneComponent.h"
#include "Runtime/Engine/Classes/Sound/SoundWave.h"
#include "IntelSoundComponent.generated.h"



UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) )
class INTEL_VR_AUDIO_TOOLS_API UIntelSoundComponent : public USceneComponent
{
	GENERATED_BODY()


public:
	// Sets default values for this component's properties
	UIntelSoundComponent();

	//Blueprint function to expose soundFiles into blueprint.
	UFUNCTION(BlueprintCallable, Category = IntelAudio)
		void soundArray(TArray<FString> &soundFileArray);

	//Blueprint function passing a wav converted in USoundwave into blueprint.
	UFUNCTION(Category = IntelAudio, BlueprintCallable)
		USoundWave* setWavToSoundWave(const FString &fileName);

代码块。IntelSoundComponent.h

向蓝图展示音效文件的蓝图函数。

screenshot of sound array widget

传输 .wav 文件的蓝图函数在 USoundWave 中被转换为蓝图。

screenshot of sound widget

设置 UI

我们需要设置 3 个 UMG 小部件。

screenshot of multiple widget set up

我们创建了用于管理这些 UMG 小部件的蓝图。

screenshot of multiple blue prints to manage umg widgets

我们为该项目配备了若干个小部件。选择音效后,AudioParamsSliderWidget 小部件将弹出。soundButtonWidgetBP 只是面向 Content/Sound 文件夹中音效的按钮部件。我们将 soundSelectorWidgetBP 小部件放在关卡中,具体方法创建一个名为 IntelSoundWidgetBP 的 actorBP,并使其获取来自 SoundArray C++ 节点的音效,然后使用 soundButtonWidgetBP 来填充 soundSelectorWidgetBP。(我们可以动态地完成,但是每次开始播放时,我们都会获得新生成的 actor 的引用。)这一切都发生在 IntelSoundManagerBP 中,我们从一开始也把它放在关卡中。

screenshot of sound widget
IntelSoundManagerBP

我们从上图中获取了 FString 的 soundFiles TArray,与此同时,分割.wav 的名称(音效名称)。我们将该字符串发送至 IntelSoundWidget 的字符串列,以命名动态填充的按钮。

screenshot of sound widget
IntelSoundWidgetBP

我们在 IntelSoundWidgetBP 中生成 soundUI,

screenshot of sound widget

添加音效,

screenshot of sound widget

如果我们不使用 Set Widget 节点,将生成小部件,但是它在游戏中不可见。

screenshot of sound widget spawned in VR environment

音效参数

玩家从小部件中选择音效后,将生成一个 IntelSoundAudioActorBP actor。我们在 actor 中看到了 AudioParamsSliderWidgetBP,如果单击 Spatialize?,将显示 3 个衰减设置,可以通过小部件对它们进行修改。

screenshot of sound widget - volume settings

screenshot of sound widget - volume settings

声音衰减本质上是指随着玩家的离开,音量减弱的能力。

graph

 

graph

graph

 

graph

显示的 3 个设置为衰减函数、衰减形状和衰减距离。

如果时间充足,可以显示更多设置。Unreal 中存在衰减设置结构的映像。

Unreal* attenuation settings

我们相信我们选择的 3 个设置是最基本、最需要的设置。我们现在正在研究如何在改变设置时显示调试行。我们正在尝试使用衰减设置调试行 Unreal 用例来显示游戏编辑器中的衰减,但是还未找到答案。因此,我们可能得到所选的衰减形状和函数的形状范围,并使用 Unreal 内置绘制调试行节点。

退出时保存

当我们退出游戏,生成了音效,移动它们并且运行了音频参数时,我们通过 IntelSoundAudioActorBP,使用 IntelSaveGameBP 保存所有重要的变量。

variables save UI
IntelSaveGameBP

screenshot of sound manager blueprint
IntelSoundManagerBP

screenshot of audio actor blueprint
IntelSoundAudioActorBP

如果一切正常运行,我们应该能够在虚拟现实中编辑文件夹中的任何音效。


2018 第十一届“英特尔杯”全国大学生软件创新大赛获奖作品

$
0
0

 

第十一届"英特尔杯"全国大学生软件创新大赛总决赛合影(点击查看大图

获奖作品展示

•  第十一届英特尔杯全国大学生软件创新大赛 — 特等奖(1名)

Davinci's Brush      同时荣获最具创业潜力奖&最具极客人气奖

团队:Turing      学校:山东大学

Davinci’s Brush 以“人人皆可画”为宗旨, 致力于基于深度学习的图像设计及处理服务。
Davinci’s Brush is based on the principle of “everyone can draw” and is committed to image-based design and processing services using deep learning technology.

Davinci’s Brush-项目开发文档      项目介绍视频

 

•  第十一届英特尔杯全国大学生软件创新大赛 — 一等奖(3名)

WiSmart      同时荣获最具创业潜力奖

团队:WirelessLife     学校:大连理工大学

WiSmart-基于人工智能和WIFI CSI的应用于智能家居的无源感知身份识别系统。
WiSmart:A Deep Learning Oriented Device-free Identity Recognition System via WiFi CSI for Smart Homes.

WiSmart-项目开发文档      项目介绍视频

 

Audink

团队:Seafaring_ChainNode      学校:山东大学

产品结合机械阅读和人工录制的优势,利用人工智能技术,帮助用户轻松打造优质的有声书。
Audink is an audio book service product based on artificial intelligence.

Audink-项目开发文档      项目介绍视频

 

Sketchdict

团队:ALU     学校:大连理工大学

Sketch.dict是一款基于草图识别技术的手绘创作软件,旨在利用深度学习实现手绘文化的复兴。
Sketch.dict is a sketch composing software based on sketch recognition technology.

Sketch.dict-项目开发文档      项目介绍视频

 

•  第十一届英特尔杯全国大学生软件创新大赛 — 二等奖(6名)

Hera      同时荣获最具创业潜力奖

团队:VicGlory     学校:中南大学

Hera 是一款实时提供全面、权威的婚姻纠纷案件解决方案,帮助咨询者维权的智能法律咨询辅助系统。
Hera is an intelligent legal advice support system that provides comprehensive and authoritative solutions to marital disputes in real time and helps consultants safeguard their rights.

Hera-项目开发文档      项目介绍视频

 

基于人工智能的乒乓球发球机器人      同时荣获最具创业潜力奖

团队:ing_master      学校:山东大学

这是一款云时代、人工智能时代的新型发球机。告别单调的训练模式,尽情享受人工智能时代带来的乒乓盛宴吧!
This is a ping pong robot in the AI era.

基于人工智能的乒乓球发球机器人-项目开发文档      项目介绍视频

 

Mashion

团队:kiwi    学校:上海交通大学

Mashion 是一套完整的个人时尚解决方案。在Mashion 中您可以一键解决“穿什么”的苦恼。
Mashion is a complete set of personal fashion solutions. In Mashion, you can solve the problem of "what to wear" with a single button.

Mashion-项目开发文档      项目介绍视频

 

形声

团队:Sirius      学校:中南大学

形声是一款基于深度学习技术通过动作识别为动作视频自动添加匹配的背景音乐的人工智能app。
Phonetic is an artificial intelligence app that automatically adds matching background music(BGM) to motion video through motion recognition based on deep learning technology.

形声-项目开发文档      项目介绍视频

 

微创手术支持系统

团队:Mercury      学校:武汉大学

我们借助互联网技术和人工智能技术,设计和开发了“微创手术支持系统”,它能够实现专家远程手术指导和智能手术预警分析。
An eHealth system for support in invasive diagnosis and treatment is designed and developed to realize remote surgery guidance and intelligent surgery warning using Internet technology(IT) and artificial intelligence(AI).

微创手术支持系统-项目开发文档      项目介绍视频

 

Clothed-partner

团队:四个菜鸡SQUAD    学校:北京理工大学

本团队设计并开发了一套基于深度学习模型的智能衣物搭配系统——Clothes-Partner,旨在为陷入衣物搭配烦恼的人们提供搭配建议。
Our team in order to solve this problem developed a model based on depth study of smart clothing collocation system Clothes-Partner.

Clothed-partner-项目开发文档      项目介绍视频

 

•  第十一届英特尔杯全国大学生软件创新大赛 — 三等奖(10名)

TryCatch

团队:Deep_silent      学校:山东大学

为提高城市监控管理的效率及信息的利用率,在当今算力大大提升,监控摄像普及的背景下,我们设计了这款可用于智能城市监控管理的反扒辅助工具。
We have designed this anti-­rolling aid that can be used for smart city surveillance management.

Trycatch-项目开发文档      项目介绍视频

 

Macdance

团队:蒂花之秀     学校:北京邮电大学

此项目通过用户输入的喜爱的音乐,将音乐通过深度学习训练好的模型来识别,让舞蹈初学者能够更容易、更方便的来根据自己喜欢的音乐来跳一段舞。
It makes it easier and more convenient for dancers to dance a dance according to their favorite music.

Macdance-项目开发文档      项目介绍视频

 

天眼

团队:Drchaser    学校:天津大学

在红黄蓝幼儿园虐童事件曝光后,“如何保障弱势群体的人身安全”这一问题再度被推上风口浪尖。针对这一问题,我们建立的实时的动作识别和异常检测模型。
To solve this problem,we have established real-time motion recognition and anomaly detection models.  

天眼-项目开发文档      项目介绍视频

 

Handwriting Assistant

团队:关中刀客     学校:哈尔滨工业大学

Handwriting assistant是一 款集字迹鉴定、古籍修复残文补全风格模仿等功能为一体的中文字迹风格辅助程序。
Handwriting assistant is Chinese handwriting style auxiliary program with a set of handwriting identification, repair, completion, residual paper imitates the style of functions.

Handwriting assistant-项目开发文档      项目介绍视频

 

贝贝儿童智能机器人

团队:MyRobot     学校:厦门大学

Babebay贝贝儿童智能机器人,是一款适用于 6-12 岁儿童,进行互动陪伴和情绪引导 的“高情商”智能机器人。贝贝独具三大特色功能,情绪识别,情绪记录和情绪引导。
Babebay is an Intelligence Robot which is suitable for 6-12 year-old children.

贝贝儿童智能机器人-项目开发文档      项目介绍视频

 

Face Tracker

团队:追猎者     学校:哈尔滨工业大学

Face Tracker是一款基于用户对人脸的印象生成目标人脸,并协助用户确定该人脸身份的应用。
Face Tracker is an app which can help the user generate someone’s face based on the the user ’s impression of of him/her and determine the the identity of the face.  

Face Tracker-项目开发文档      项目介绍视频

 

抑郁治疗师

团队:Image    学校:重庆大学

本项目旨在通过将深度学习应用到医疗界,解决抑郁症医疗领域中存在的主要问题。
This project aims to solve the major problems in the medical field of depression by applying deep learning to medical treatment.

抑郁治疗师-项目开发文档      项目介绍视频

 

iCuriosity

团队:Inno_Gear     学校:中南大学

iCuriosity是一款将深度学习技术应用于3-6岁幼儿教育领域,帮助孩子探索未知世界的App。其旨在激发孩子的探索学习热情、为语言学习奠基、降低幼教成本、促进亲子交流。
iCuriosity is a App that applies deep learning to preschool educationin 3-6,to help children explore the unknown world.

iCuriosity-项目开发文档      项目介绍视频

 

SG智能储热式电暖

团队:SGLife    学校:北方工业大学

本作品基于Intel/Caffe开发的深度学习技术,设计并制作了一款后台可合理规划储热时间、前端可选择智能供热模式的智能储热电暖设备。
This work is based on deep learning technology developed by Intel/Caffe, and designed and produced an intelligent heat storage and heating device with a back-end heat storage time and a front-end free heating mode. 

SG智能储热式电暖-项目开发文档      项目介绍视频

 

Ai画

团队:ICE   学校:华中科技大学

Ai 画是基于深度学习的儿童早教类app,通过识别绘画内容,即时反馈预测成果,结
合音频和视频辅助学习,提升幼儿认知能力。
It trains children’s cognitive ability byrecognizing drawing content and giving real-time feedback of what is being drawn, assisted withaudio and video contents.

Ai画-项目开发文档      项目介绍视频

 

合并蒙蔽遮挡剔除分层缓冲区,实现更快速的渲染

$
0
0

摘要

动态场景中的高效遮挡剔除可加速渲染,这使其成为游戏和实时图形社区的重要主题。由 J. Hasselgren、M. Andersson 和 T. Akenine-Möller 发表的一篇论文 蒙蔽软件遮挡剔除提出了一种针对支持 SIMD 的 CPU 进行优化的新算法,该算法剔除了传统遮挡剔除算法剔除的 98% 的三角形。尽管这种算法非常高效且准确,适用于许多用例,但仍存在启发法未充分解决的一些问题。在本文中,我们将对 Andersson 等人的先前工作进行补充。通过将场景分割为可以更好地拟合几何图形的局部动态范围并可以同时计算的多个缓冲区,从而解决了许多这些问题。然后,我们增加算法的丢弃启发法,并将部分结果缓冲区合并到一个新的分层深度缓冲区中,在该缓冲区上应用可以可靠地执行准确、高效的遮挡查询。

简介

蒙蔽软件遮挡剔除由英特尔的 J. Hasselgren、M. Andersson 和 T. Akenine-Möller 在 2015 年发明。它专为在适合游戏和实时图形社区的动态场景中进行高效遮挡剔除而设计。Andersson、Hasselgren 和 Akenine-Möller 在 2016 年随后提出的蒙蔽软件遮挡剔除算法的优势在于,它剔除了传统遮挡剔除算法所剔除的 98% 的三角形,同时比以前的工作快得多。此外,它仍可以充分利用 单指令多数据 (SIMD)指令集,与基于图形处理单元 (GPU) 的解决方案不同,它不会在系统中引入任何延迟。这对于游戏引擎开发人员非常重要,因为它可以使 GPU 免于不必要地渲染不可见的几何图形,渲染其他更丰富的游戏视觉效果。

Representation for the Intel castle scene
图 1.左侧:英特尔城堡场景中原始蒙蔽遮挡层次深度表示的可视化,黑暗离得更远;保守合并错误用红色突出显示。中间:城堡场景的游戏内视图,包括网格的边界框。右侧:使用两个单独分层缓冲区的合并来显示城堡场景的蒙蔽遮挡分层深度表示,准确性大幅提升。

该算法的更新版本 [HAAM16] 受到四片段合并 [FBH∗10] 的启发,该算法精度较低但性能较高,也被添加到蒙蔽遮挡库中。如果传入数据由前到后大致排序,则此方法效果最佳,这也可通过减少深度缓冲区中的透支来提高效率。

Typical workflow for Masked Occlusion Culling
图 2.典型的蒙蔽遮挡剔除工作流程。

图 2 显示了将蒙蔽遮挡剔除集成到游戏引擎中的典型工作流程。这个工作流程反映了传统的图形管道,并且已经被开发人员以这种格式使用,包括 Booming Games*Conqueror's Blade*,效果不错。

Masked Occlusion Culling buffer
图 3.Conqueror's Blade*的典型蒙蔽遮挡剔除缓冲区

然而,一些游戏工作负载显示,蒙蔽遮挡剔除效果较差的一个领域是在渲染具有明显深度重叠的超大网格时,因为重叠使得无法进行精确排序。经证明,这个问题在更新的 [HAMM16] 算法中特别突出。具体而言,在为广阔的环境渲染混合的前景资产和地形补丁时,问题就会显现出来。单个地形修补程序覆盖的深度范围很广,无法按照最佳顺序相对于前景遮挡物进行排序。这些间断是创建蒙蔽软件遮挡 HiZ 缓冲区时固有的,因为在建造缓冲区时用于丢弃图层的当前启发法不具备关于未来几何图形的足够上下文来保留最重要的数据。如果没有传入几何图形的完整上下文,启发法在深度选择过程中必须采取保守的方法,这会增加以后可见的遮挡查询的数量。这又意味着 GPU 不得不渲染最终被 GPU 剔除的几何图形,并且决不会对整个场景做出贡献。

为了解决这个问题,我们 [作者 Leigh Davies 和 Filip Strugar] 添加了将多个蒙蔽遮挡层次深度缓冲区合并到蒙蔽软件遮挡库中的功能。这允许开发人员利用分组场景几何图形和计算每个子组部分结果缓冲区的策略。选择子组是因为它们更紧密的深度值动态范围和以及几何分类行为。前景对象的子组和另一个地形对象的子组是常见情形。此类子组的部分遮挡结果稍后会合并到单个分层深度缓冲区中。部分缓冲区的这种合并使用现有丢弃启发法扩展来组合图层。

先前工作

蒙蔽软件遮挡光栅化算法与任何标准的两级分级光栅器相似 [MM00]。光栅化管道的一般流程如图 4 所示:

Masked Occlusion Rasterization Pipeline
图 4.蒙蔽遮挡光栅化管道,用于英特尔® 高级矢量扩展指令集 2(英特尔® AVX2)

三角形设置和图块遍历代码都经过高度优化,可高效使用 SIMD,可并行处理的三角形和像素的数量也不相同,具体取决于使用的 SIMD 的类型。蒙蔽遮挡剔除算法不同于标准软件光栅器有两个例外,下面将对其进行介绍。首先,它能够使用三角形边缘高效地并行计算整个图块的覆盖单元,而不是一次处理扫描线。

triangle rasterized on an Intel A V X 2 capable processor
图 5.在支持英特尔® AVX2 的处理器上进行光栅化的示例三角形。我们遍历三角形边界框所叠加的所有 32 x 8 像素单元,并使用简单的位操作和移位计算 256 位覆盖单元。

由于英特尔 AVX2 支持 32 位精度的 8 宽 SIMD,因此我们使用 32 x 8 作为图块大小,如图 5 所示(英特尔® SIMD 流指令扩展 2(英特尔® SSE2/英特尔 SSE4.1/英特尔® 高级矢量扩展指令集 512(英特尔® AVX-512)的图块大小将不同)。这使得算法可以非常高效地并行计算 256 像素的覆盖范围。

第二个区别是分层深度缓存表示,它将深度和覆盖数据分开,不需要存储全分辨率深度缓存。蒙蔽软件遮挡光栅化算法使用成本较低的混编重新安排遮罩,以便每个 SIMD 通道映射到更合适的 8 x 4 图块。对于每个 8 x 4 单位,分层深度缓冲区会存储两个浮点深度值 Zmax0和 Zmax1,以及一个表示每个像素与哪个深度值相关联的 32 位遮罩。在图 6 中可以找到由两个使用蒙蔽遮挡算法的三角形填充的图块的示例。

Tile fully covered by a blue and yellow polygon
图 6.在本例中,8 x 4 像素图块首先被一个蓝色多边形完全覆盖,随后被一个黄色三角形部分覆盖。左侧:我们在屏幕空间中看到的 HiZ 表示,其中每个样本属于 Zmax0或 Zmax1。右侧:沿着深度轴 (z),我们看到黄色三角形比蓝色多边形更接近。所有黄色样品(左)与 Zmax1(工作层)相关联,而所有蓝色样品与 Zmax 0 (参考层)相关联。

单层深度缓冲区的限制

鉴于我们每个图块只存储两个深度值,我们需要一种在每次三角形被光栅化(部分覆盖图块)时保守地更新表示的方法。参见图 7 中的伪代码,我们首先将 Zmax0分配为参考图层,该参考图层代表在图块中可见的最远距离,并且 Zmax <1> 值作为部分由三角形数据覆盖的工作层。

确定三角形覆盖范围后,我们将工作层更新为 Zmax1 = max (Zmax1, Zmaxtri),其中 Zmaxtri是图块边界内三角形的最大深度,并合并遮罩。当组合遮罩已满时覆盖图块,我们可以覆盖参考图层并清除工作层。

function updateHiZBuffer(tile, tri)
// Discard working layer heuristic
dist1t = tile.zMax1 - tri.zMax
dist01 = tile.zMax0 - tile.zMax1
if (dist1t > dist01)
tile.zMax1 = 0
tile.mask = 0

图 7.更新图块伪代码。

除了上面的规则之外,我们还需要一个启发法来决定何时放弃工作层。如图 8 所示,如果数据没有以完美的前后顺序进行提交,这有助于防止缓冲区中现有数据的轮廓通过更接近相机的遮光板泄漏。如上面的 updateHiZBuffer() 函数所示,如果到三角形的距离大于工作层和参考层之间的距离,我们会丢弃工作层。

蒙蔽遮挡更新程序旨在保证 Zmax0≥ Zmax1,所以我们可以使用带符号的距离来进行更快速的测试,因为如果当前三角形距离较远,我们不希望丢弃工作层。基本原理是深度较大的不连续性表示正在渲染一个新对象,并且连续的三角形最终将覆盖整个图块。如果工作层没有被覆盖,算法仍然需要保守地表示深度缓冲区。

Hierarchical depth buffer
图 8.顶部:分层深度缓冲区的两个可视化。生成左侧图像时不使用启发法来丢弃图层。请注意,背景物体的轮廓通过遮光板泄漏,在浅灰色的前景物体上显示为较暗的灰色轮廓。右图使用我们的简单图层丢弃启发法,保留了传统深度缓冲区几乎所有的遮挡精度。底部:我们的丢弃启发法应用于图 2 中的样本图块。根据我们的启发法,黑色三角形会丢弃当前工作层,并覆盖 Z1最大值。基本原理是深度较大的不连续性表示正在渲染一个新对象,并且连续的三角形最终将覆盖整个图块。

参考图 9,由于用于丢弃工作层的启发法未被触发,因为参考层在工作层后面很远,所以剩余的轮廓边缘通过遮光板发生了泄漏。在问题情况下,参考图层包含清除值,导致深度值的动态范围很宽。工作层用来自工作层和新三角形的最保守值进行更新。尽管连续的三角形最终覆盖整个图块,并且工作层可能使用了来自传入三角形的更近的 Zmax 值。

Single hierarchical depth buffer
图 9.仅使用单个分层深度缓冲区,在排序良好的场景中轮廓渗出。

去除地形上的轮廓渗出

图 9 显示了高分辨率轮廓渗出的最终效果。当靠近观察者的物体在包含远处物体和清晰颜色的图块中进行渲染时,将出现最突出的轮廓渗出情况。这是由于需要在图块层中保留最保守的值,且没有以后还可以渲染哪些内容的上下文。一个潜在解决方案是,仅在添加了新网格的全部数据时才将数据合并到一个图块中,但这需要能够在分层深度缓冲区中存储更多图层。

解决轮廓渗出问题的另一种方法是将地形和前景对象渲染到自己的分层深度缓冲区中,然后单独渲染它们。这可大幅减少分层深度缓冲区中的间断。前景物体几乎没有渗出,因为粗糙的前后排序足以确保三角形按照最适合掩蔽遮挡丢弃算法的顺序呈现。由于单个网格内的三角形的内部排序,地形存在一些渗出问题,但是这些更加局部化。图 10 显示了分离的分层深度缓冲区。这只剩下合并地形网格和现有前景对象的问题,以生成可用于剔除的最终分层深度缓冲区。

Castle scene with terrain and foreground objects
图 10.城堡场景与地形和前景对象在单独的缓冲区中。

合并缓冲区

添加到掩蔽遮挡 API 的新合并功能就是这样的,用第二个分层深度缓冲区,将数据合并到第一个深度缓冲区中。合并算法在相同的 8 x 4 图块基础上运行,使用与用于光栅化的合并启发法相同的 SIMD 指令,从而允许并行处理多个子图块。合并代码已针对原始合并算法 [AHAM15] 和更新版本 [HAAM16] 实施。合并算法的流程如下所述:

1.使用参考 + 工作层计算图块的保守深度值。对于 HAAM16 来说很简单,因为这是参考层,对于 AHAM1 稍微复杂一些。

New Reference Layer = _mm256_max_ps(Valid Reference A[0], Valid Reference B[0]);

2.比较缓冲区 A 层与新参考层的运行情况。遮掩未通过深度测试的所有图块 -用深度测试的结果更新新参考图层

3.将缓冲区 B 的工作层视为传入三角形。将缓冲区 B 层的运行情况与新的参考层进行比较 遮掩未通过深度测试的所有图块。如果传入的三角形比新工作层更接近观察者,则使用距离启发法丢弃第 1 层。使用传入三角形覆盖更新新遮罩。

计算 zMin[1] 的新值这是四项成果之一:

zMin[1] = min(zMin[1], zTriv)
zMin[1] = zTriv
zMin[1] = FLT_MAX
未更改

取决于图层是更新、丢弃、完全覆盖还是未更新。如果图块完全覆盖,将 zMin[1] 传送回 zMin[0],并更新遮罩。

在实践中,我们发现对于像城堡这样的场景,我们只需要使用两层;只需稍作修改,代码就可以组合多个缓冲区。最终的合并缓冲区如图 11 所示。原始轮廓问题已经完全解决。

Final hierarchical depth buffer
图 11.从合并的前景和地形缓冲区创建的最终分层深度缓冲区的可视化表示。

缓冲区的合并不能解决单个缓冲区的渗出问题,例如地形方面的内部问题。但它确实可以确保它们在被另一组几何体中的数据覆盖时不会向前传播。在城堡中,它们被前景物体覆盖。

表 1 显示了不同分辨率下合并算法的性能;性能与分辨率成正比,而用于合并 HI-Z 数据的代码使用与其余 MOC 算法相同的一组 SIMD 指令。这里提供的数据是使用英特尔 AVX2 生成的,因此可并行处理 8 个子图块,但这可以通过英特尔 AVX-512 扩展到最多 16 个子图块。

表 1.相对于分辨率的合并成本;性能在英特尔® 酷睿™ i7-6950X 处理器上测量得出。

 地形光栅化时间 (ms)前景光栅化时间 (ms)总光栅化时间 (ms)合并时间 (ms)合并所用的时间百分比
640 x 4000.190.6520.8420.0080.9%
1280 x 8000.260.7721.0680.0272.5%
1920 x 10800.310.8341.1440.0514.4%

合并功能会跳过不需要合并的图块,因为只有一个缓冲区在图块中具有有效数据作为优化。尽管有固定的数据集遍历成本来检查这一点,但掩蔽遮挡层次深度缓冲区的低内存占用空间是合并性能的主要原因。在 1920 x 1080 分辨率下,屏幕由 64800 (8 x 4) 个子图块组成,每个子图块只需要 12 个字节的存储。合并函数只需读取 760 Kb,而传统的 32 位深度缓冲区则超过 8.1 MB。另外,通过使用英特尔 AVX2,我们可以并行处理八个子图块。表 1 中的时间表示单线程性能。合并线程化方面的实验表明,由于受到内存限制,所获得的优势不多。在每秒运行速度为 60 帧的 PC 图块上,一个 1080p 缓冲区可以并入单个内核上一帧的 0.5%。

使用缓冲区合并来并行化分层深度缓冲区创建

掩蔽遮挡库已经提供了一种用于并行创建分层深度缓冲区的方法。通过使用图块渲染系统(即传入网格发送到作业系统且并行渲染),几何变换阶段产生的三角形输出存储在代表屏幕空间图块的分箱列表中,然后由每个线程的作业系统进行处理,从而对一个屏幕空间图块的几何图形进行光栅化处理。分层深度缓冲区的合并提供了一种替代方法,适用于更粗的粒度,并且不需要将几何图形存储在临时结构中。典型设置如图 12 所示。任务系统最初调度两个遮光板渲染任务,并创建一个在两个渲染任务都完成时进行触发的合并任务。

Potential multithreading setup
图 12.用于蒙蔽遮挡剔除的潜在多线程设置。

合并任务完成后,渲染应用的实际遮挡查询可以根据需要在任意数量的线程上发布。理论上,前景遮挡物渲染任务可以进一步细分。如果它们之间的工作量非常不均匀,如果每个附加任务的成本是一个额外的合并任务,并且合并功能可以进一步修改以管理多个缓冲区(如果需要),这可能是有利的。以这种方式进行线程化的一个额外好处是可以移除所需内存并节省相关带宽,无需写出变换和光栅化过程之间的几何图形。总体而言,这种将场景分割成两个或多个蒙蔽遮挡剔除缓冲区并使用独立线程处理它们的方法支持功能性线程模式,这种模式适用于不支持英特尔拼贴算法所需的细粒度任务系统的引擎。

结论

我们对蒙蔽软件遮挡剔除的扩展为您提供了一种灵活的解决方案,可以在不影响原始蒙蔽遮挡算法性能的情况下,为无法充分预分类的场景提高深度缓冲区的最终精度。我们方法中的合并时间与分辨率呈线性关系,并且与场景中的几何复杂度无关。在测试案例中,我们的方法仅占剔除系统所需总时间的一小部分。最终优势在于,我们的部分结果分组可以实现新的线程级并行机会。这些改进可提供强大、快速且准确的基于 CPU 的几何图形剔除。整体而言,这些改进大大降低了游戏引擎采用蒙蔽软件遮挡剔除的门槛,可释放 GPU 渲染资源,从而提供更丰富的游戏体验。

参考

[AHAM15] M. Andersson、J. Hasselgren、T. Akenine-Möller:图形硬件的蒙蔽深度剔除。ACM 图形交易,34,6 (2015),188:1–188:9.2, 4, 5, 8

[FBH∗10] K. Fatahalian、S. Boulos、J. Hegarty、K. Akeley、W. R. Mark、H. Moreton、P. Hanrahan:使用四片段合并减少 GPU 上的阴影。ACM 图形交易,29,4 (2010),67:1–67:8.4

[HAAM16] M. Andersson、J. Hasselgren、T. Akenine-Möller:蒙蔽软件遮挡剔除

[MM00] J. Mccormack、R. Mcnamara:在图形硬件中使用半平面边缘函数进行图块多边形遍历 (2000),pp.15– 21.2

Viewing all 583 articles
Browse latest View live