渲染管线相关
- 为static mesh增加额外pass,看了网上有两种方法:1、自定义proxy,在DrawStaticElements增加meshbatch;2、通过使用BuildFromMeshDescriptions方法,构造static mesh,增加新的几何组(类似于section);
- UE的PrePass,依次把不透明物体和mask物体的深度绘制出来,这样后续的base pass就可以利用early-z技术;
硬件已经支持了EarlyZ,为什么还要PrePass?
因为在某些场合下EarlyZ会失效,包括:
1、在Fragment阶段存在alpha测试,模板测试,可能会终止result的输出;
2、存在clip或者discard,终止result的输出;
3、在Fragment阶段存在深度写入;
以上失效的情况都可能会导致Fragment Shader的无效执行,浪费性能。PrePass的思想就是以低消耗版本的Fragment Shader得到场景深度图,即使该阶段EarlyZ失效也只有非常简单的Shader消耗。对于管线整体而言,虽然增加了一个低消耗的PrePass通道,但却换来了后续BasePass的EarlyZ可以正常生效,从而降低高消耗版本的Fragment Shader的Overdraw,提升整体性能。
GamePlay相关
- 在FPrimitiveSceneProxy子类中可以利用GetActorPosition来获取对应actor的位置;
- 判断一个类是否为某个类的子类
UClass *cl = Player->GetClass();
if (cl->IsChildOf(UWLLocalPlayer::StaticClass()))
{}
- stat fps命令绘制fps计算的地方在CalculateFPSTimings,FEngineLoop::Tick()会调用,绘制的
地方在RenderStatFPS; - config相关
1、默认情况下模块启动的时候,在StartupModule方法里,GConfig已经被初始化,所以这个时候要修改配置文件虽然文件写入成功,但内存中GConfig中的值可能没变化;
- transform,虚幻的变换顺序是scale->rotate->translate;
-
启动界面相关
虚幻启动时候的各种screen顺序:平台相关的splash screen--->custom splash screen--->Early startup screen--->Engine loading screen;后边三个使用方式都是自己定义一个模块,然后该模块要设置好 load phase,并且模块里要有一个继承自FPreLoadScreenBase的类,并设置好其属性;后边两个screen只有当没有start movie或者不支持early playback的时候才会出现;
多线程相关
- UE里有个FReturnGraphTask,可以发配到某个线程,这个会结束线程的while循环;
// named thread process tasks while we wait
TGraphTask<FReturnGraphTask>::CreateTask(&Tasks, CurrentThread).ConstructAndDispatchWhenReady(CurrentThread);
ProcessThreadUntilRequestReturn(CurrentThread);
- TGraphTask<括号里自定义的Task,要实现特定方法>
- FFunctionGraphTask其实是对TGraphTask封装了一下;
FGraphEventRef PrerequisiteTask; // A task to be completed before
FGraphEventRef Task = FFunctionGraphTask::CreateAndDispatchWhenReady( []() {
/* Work on the TaskGraph */
}, TStatId(), PrerequisiteTask, ENamedThreads::AnyThread);
FGraphEventArray TasksList; TasksList.Add(Task);
if (Task->IsComplete()) {
/* On work completed */
}
- UE的TAtomic、FGenericPlatformAtomics及其子类被废弃,用std::atomic替代;
- FScopeLock 和FCriticalSection一样,原理和std::mutex类似,FScopeLock 在离开作用于自动unlock,FCriticalSection需要手动,FCriticalSection好处是能紧紧地包裹需要原子操作的代码段,不需要等离开作用于;
- TQueue没有使用锁,用了两个原子操作和一个内存屏障MemoryBarrier,所以叫lock-free;
- FScopedEvent作用是在离开作用域之后,让当前线程sleep,等待被调用MyEvent->Trigger()才能恢复继续执行;
{
FScopedEvent Event;
DoThreadedWork(Event.Get());
/* Sleep at the closing brace until the other thread calls Event.Trigger(); */
}
调试技巧
-
查看全局变量
1720090505112.png
-
VR渲染模式可以在ini文件中修改几个参数:
在Engne.ini文件增加如下配置:
[SystemSettings]
r.StereoEmulationWidth=512
r.StereoEmulationHeight=288
r.StereoEmulationFOV
矩阵
- 从frustum构造矩阵
FMatrix IDisplayClusterViewport::MakeProjectionMatrix(float l, float r, float t, float b, float n, float f)
{
const float mx = 2.f * n / (r - l);
const float my = 2.f * n / (t - b);
const float ma = -(r + l) / (r - l);
const float mb = -(t + b) / (t - b);
// Support unlimited far plane (f==n)
const float mc = (f == n) ? (1.0f - Z_PRECISION) : (f / (f - n));
const float md = (f == n) ? (-n * (1.0f - Z_PRECISION)) : (-(f * n) / (f - n));
const float me = 1.f;
// Normal LHS
const FMatrix ProjectionMatrix = FMatrix(
FPlane(mx, 0, 0, 0),
FPlane(0, my, 0, 0),
FPlane(ma, mb, mc, me),
FPlane(0, 0, md, 0));
// Invert Z-axis (UE uses Z-inverted LHS)
static const FMatrix flipZ = FMatrix(
FPlane(1, 0, 0, 0),
FPlane(0, 1, 0, 0),
FPlane(0, 0, -1, 0),
FPlane(0, 0, 1, 1));
const FMatrix ResultMatrix(ProjectionMatrix * flipZ);
return ResultMatrix;
}
获取控制台变量值
IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.ShaderPipelines"));
打开一个对话框
FMessageDialog::Open(EAppMsgType::Ok, FText::FromString("hello"));
代理相关
FSimpleMulticastDelegate::FDelegate::CreateRaw(this, &FSlateQuickstartWindowModule::RegisterMenus)
屏幕上显示调试信息
1、GEngine->AddOnScreenDebugMessage:该方法只是生成一份绘制数据(FScreenMessageString),最终是在DrawStatsHUD -> GEngine->DrawOnscreenDebugMessages过程中,调用Canvas->DrawItem绘制;
2、UKismetSystemLibrary::DrawDebugLine:该方法调用了DrawDebugHelpers文件中的方法;DrawDebugHelpers.h文件提供了很多绘制方法,这些方法中的大部分都调用了UWorld中的ULineBatchComponent组件,也有方法比如DrawDebugString调用了AHUD的方法;
3、UKismetSystemLibrary::PrintString:在屏幕上打印文字,调用的其实是GEngine->AddOnScreenDebugMessage方法;
4、利用UDebugDrawService注册绘制的回调;
5、SceneRendering.cpp中DisplayInternals函数输出了一些调试信息,需要用r.DisplayInternals命令开启;
UCanvas和FCanvas:
用法可以参照UKismetRenderingLibrary::DrawMaterialToRenderTarget;
UCanvas封装了一些Draw*方法,可以绘制简单的线、三角、文本等,内部其实调用了FCanvas::DrawItem方法;
FCanvas内部有FRenderTarget属性,也就是说UCanvas绘制的东西都在FRenderTarget属性里;
UCanvas* GetCanvasForRenderingToTarget();
UCanvas* GetCanvasForDrawMaterialToRenderTarget();
stereo layer
- detail里的属性单位都是cm;
- cylinder的Overlay Arc指的是弧长度,不是弧度,单位也是cm
命令行
-game -windowed -ResX=500 -ResY=300: standalone方式启动
-emulatestereo: 在编辑器里用这个参数并以stantalone方式启动,可以开启vr模式
-attachPIX:
Added support for attaching to PIX on startup. You can either pass “-attachPIX” on the command line
or set r.D3D12.AutoAttachPIX=1 in ConsoleVariables.ini. You will still need to manually hit “attach” inside PIX.
ToggleDebugCamera:显示相机调试信息,或者按“;”键;
-vr: 以VR方式运行,必须开启相应的插件,比如steamvr、oculusvr等;
-RenderOffScreen:在代码WindowsD3D12Viewport.cpp:142bNeedSwapChain = !FParse::Param(FCommandLine::Get(), TEXT("RenderOffScreen"));会判断是否为离线渲染,如果是的话就不创建交换链;
- EnableGDT:在控制台输入,开启作弊调试;
- 在控制台输入:RecompileShaders Changed 编译修改过的shader
- Memreport -full 分析内存
- 控制台输入DisableAllScreenMessages可以消除所有屏幕日志;
- 控制台输入VisRT可以看用到的render target
关于.target.cs .build.cs .uproject 关于模块
创建新模块,需要创建代码、.build.cs文件,然后在使用该模块的模块.build.cs里添加依赖,最后还需要在.uproject或者.plugin文件Modules属性中声明。(.target.cs文件不用动)
.target.cs决定程序如何build;[项目名].target.cs编译出exe程序,[项目名]Editor.target.cs编译出dll程序;还有Server/Client等后缀;
.build.cs是模块描述符,描述模块相关,比如添加依赖等;
.uproject文件中Modules属性决定when and how加载模块;
- 一般情况下,只有模块在依赖链里才会被编译,否则就需要加到.target.cs中ExtraModuleNames属性里,这个属性一般用来添加primary game module和一些编辑器模块;
- 关于模块PCH:
private PCH:
在自己模块中定义;
在.build.cs中通过PrivatePCHHeaderFile制定;
无需手动引入,UBT会自动引入;
share PCH:
只有engine module可以定义;
可以让别的模块使用;
PCHUsageMode:
有几个模式是遗留的,一般要求始终使用UseExplicitOrSharedPCHs,表示如果没有指定PrivatePCHHeaderFile,则是share模式,指定了就是private模式;
VS里使用第三方库
1、头文件目录:c/c++ -> General -> Additional Include Directories
2、lib文件目录:Linker -> General -> Additional Library Directories
3、lib文件依赖:Linker -> Input -> Additional Dependencies
插件
panoramic capture 全景图和全景视频捕捉
编译问题
- 如果编译项目的时候发生了unresolved external symbol这样的错误,有可能是项目某个模块文件中引用别的模块的东西,但是没有在该模块.build.cs中加引用,需要在PublicDependencyModuleNames中加入。
- 在项目编辑器导入(Add\Import)-> Add Feature or Content Pack -> Vehicle,需要在项目插件中启用PhysXVehicles,并且如果是c++工程,需要在build.cs文件中添加依赖“PhysXVehicles”;
- setup.bat出现下载错误,去github上下载最新的Engine\Build\Commit.gitdeps.xml文件,覆盖本地;
- 如果发现在编译的时候,发现很多Link错误,无法解析的符号等等,曾经通过一下方法解决了:
1、先看是link哪个dll或者lib时候出的错,找到属于哪个模块;
2、到目录Engine\Intermediate\Build\Win64\x64(源码编译的中间文件都在这里)里寻找到该模块,把所有文件都删除;
3、然后把目录Engine\Binaries\Win64里相应的dll也删除;
- 遇到右键工程文件选择switch unreal engine version的时候,或者无法生成项目文件(generate visual studio project files),没有弹出选择框,而是弹出了系统的选择打开应用的窗口,用了以下办法解决:
1.去注册表搜索switchversion,一般路径为计算机\HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Unreal.ProjectFile\shell\switchversion\command,修改数据为"C:\Program Files (x86)\Epic Games\Launcher\Engine\Binaries\Win64\UnrealVersionSelector.exe" /switchversion "%1"。前边是UnrealVersionSelector.exe的路径,在Launcher安装目录下可以找到。
2.找到位于Engine\Binaries\Win64下的UnrealVersionSelector-Win64-Shipping.exe,双击运行就好了;
- 重新编译插件的命令行:
Engine\Build\BatchFiles\RunUAT.bat BuildPlugin -plugin="插件目录\插件.uplugin" -package="编译结果存放的目录"
- 可以指定使用的windows sdk版本,修改\Engine\Saved\UnrealBuildTool\BuildConfiguration.xml文件,添加如下属性
<Configuration xmlns="https://www.unrealengine.com/BuildConfiguration">
<WindowsPlatform>
<WindowsSdkVersion>10.0.19041.0</WindowsSdkVersion>
</WindowsPlatform>
</Configuration>
-
遇到“Touch dte80a.tlh: Exited with error code 1”的错误,删除Engine\Intermediate\Build\Win64\x64\UnrealEditor\Development\VisualStudioDTE里的obj文件解决了;
-
遇到.net framework not reference的问题,是切换分支导致的,一些文件没有清除掉,用了 git clean -xfd命令好了
-
遇到MSBuild应该使用2022,但是却用了2019,去Rider->Settings->Build,Execution,Deployment->Toolset and Build-> MSBuild version:选择2022的路径;
GameThread和RenderThread同步
-
默认情况下,GameThread最多比RenderThread快1帧,也就是说当GameThread执行完第N帧的逻辑时候,如果RenderThread还没有执行完第N-1帧的逻辑,则GameThread会等待RenderThread,见FEngineLoop::Tick函数后边,FFrameEndSync,这个类用到了FRenderCommandFence。
-
在Render线程中,在FRHICommandList::EndDrawingViewport方法中,利用FRHICommandListExecutor::WaitOnRHIThreadFence方法等待RHI线程;
-
在RHI线程中,方法FD3D12CommandContextBase::RHIEndDrawingViewport中通过WaitForFrameEventCompletion来等待GPU完成绘制;
-
在GameThread中等待RenderThread执行完所有命令的方法(要在GameThread中执行):
FRenderCommandFence Fence;
Fence.BeginFence();
Fence.Wait();
或者直接调用FlushRenderingCommands全局方法;
- 可以从FRHICommandListImmediate::RHIThreadFence方法获取一个FGraphEvent,用作fence;
![](https://img.haomeiwen.com/i6010185/7fa17d4cfcbaa4cc.png)
- GameThreadWaitForTask方法阻塞GameThread;
- game线程最多比render线程提前一帧,见本类第一条描述;在等待的时候根据r.GTSyncType的值决定怎么等待,见FRenderCommandFence::BeginFence,默认是只等待render线程,不等待rhi线程;如果设置为等待rhi线程,则会提交一个命令到rhi线程,该命令在rhi线程执行(Execute)的时候会将一个FTaskEvent进行trigger,来通知game线程;
- WaitForTasksAndDeleteSceneRenderers里会等待每个FViewInfo里的FParallelMeshDrawCommandPass完成任务;
名词
1、阿姆达尔定律
2、Directx12 里的WARP Adapter:如果没有硬件显卡,可以使用WARP Adapter代替硬件显卡;
3、Microsoft Basic Display Adapter:如果硬件显卡没有驱动,或者驱动坏了,则使用Microsoft Basic Display Adapter驱动;
视频播放
- UE里好多视频播放插件,他们的逻辑一般都是创建IMediaPlayerFactory的子类,然后通过方法RegisterPlayerFactory注册到运行时的FMediaModule模块中,运行时会通过该模块访问到其他插件;
- 蓝图创建的media player是UMediaPlayer,通过FMediaPlayerFacade类型的一个属性访问到运行时的FMediaModule模块,然后FMediaModule运行时负责跟其他播放器插件模块打交道;
动画蓝图
- SkeletalMeshComponent属性Animation Mode可选择蓝图或者接选择Animation Asset(Animation Squence);
- AnimGraph 默认是运行在worker线程,可通过Class Setting中Use Multi Threaded Animation Update选项关闭;
- EventGraph处理数据,AnimGraph使用数据产生pose。
- EventGraph运行在主线程,Update Animation函数有个替代版本,可以运行在worker线程, Blueprint Thread Safe Update Animation。
- 将Animation Sequence拖进去蓝图,创建的Node为Sequence Player,可以设置是否loop。
编译 cpu
编译时不要用满所有cpu的核,否则计算机会非常卡,基本无法进行其他工作
在BuildConfiguration.xml中进行配置,将MaxProcessorCount设置成7(我本机是8核cpu)
<?xml version="1.0" encoding="utf-8" ?>
<Configuration xmlns="[https://www.unrealengine.com/BuildConfiguration](https://link.zhihu.com/?target=https%3A//www.unrealengine.com/BuildConfiguration)">
<ParallelExecutor>
<MaxProcessorCount>7</MaxProcessorCount>
</ParallelExecutor>
<BuildConfiguration>
<bAllowXGE>true</bAllowXGE>
</BuildConfiguration>
</Configuration>
注:bAllowXGE表示是否开启IncredBuild
打包
防止被打到pak,参考
[Staging]
+BlacklistConfigFiles = 工程名称/Config/CustomConfig1.ini
+BlacklistConfigFiles = 工程名称/Config/CustomConfig2.ini
安卓打包
- 遇到Could not resolve com.android.tools.build:gradle的问题,更新了JDK版本号了,从8更新到11;
- UE5.1:安装android studio,安装SDK,运行Engine/Extras/SetupAndroid.bat,这个命令行会自动安装NDK。之后需要重启电脑。
JAVA_HOME环境变量应该指向JDK。
JDK包含JRE,JRE包含JVM。 - 从Android Studio启动打包后的工程,运行,出现“Keystore file not set for signing config release”错误,将buildAdditions.gradle中的buildTypes-release删掉。
- Oculus打包,在项目设置-Android SDK-NDK API Level必须设置为android-29
安卓启动相关
- 主要看LaunchAndroid.cpp这个文件。Java侧GameActivity继承于NativeActivity,该activity内部会调用一些方法创建如loadNativeCode、ANativeActivity_onCreate等,最终会走到UE代码LaunchAndroid.cpp中android_main方法,这里设置了事件处理函数。
- 出现错误"ERROR: cmd.exe failed with args /c",去项目设置-平台-安卓,点击
最上端的config - 关于UPL:\Engine\Source\Programs\UnrealBuildTool\System\UnrealPluginLanguage.cs
PICO
PICO XR 和虚幻自带的OpenXR插件冲突;
PICO XR 和PICO for OpenXR插件冲突;
PICO XR 差不多等于 pico + openxr,所以和OpenXR插件冲突;
PICO for OpenXR和OpenXR一起使用;
PICO for OpenXR功能没有PICO XR完整;
纹理、RT相关创建
UTexture2D* FImageUtils::ImportFileAsTexture2D(const FString& Filename);
UTexture2D* UTextureRenderTarget2D::ConstructTexture2D();
UImageWriteBlueprintLibrary::ResolvePixelData()从Texture2D读像素数据;
- UTexture包含FTextureResource,FTextureResource包含FRHITexture。
- FRHITexture2D更新数据两种方式:
1、调用全局方法RHIUpdateTexture2D;
2、调用全局方法RHIUnlockTexture2D;
以上两种方法,内部实现都是从上传堆上分配一个地址,先将数据保存到上传
堆,然后再传入到默认堆。 - IImageWrapper相关的子类处理图片的Encode和Decode;
- FSlateRHIRenderer调用FSlateRHIResourceManager.LoadUsedTextures方法,加载所有编辑器纹理;
- 从图片文件读数据:
TArray<uint8> RawFileData;
// 注意:FFileHelper是位于Core/Misc路径下,不是Editor模块那个。
FFileHelper::LoadFileToArray(RawFileData, FilePath);
再利用IImageWrapper相关类,解压图片数据,然后GetRaw得到原始数据;
- UAsyncTaskDownloadImage可以从网络下载图片生成texture;
- 使用UTexture2DDynamic,要先调用Init方法,然后再将这个texture赋值给材质,这样后续的动态更新texture才会表现到材质上。
- 发现“texture streaming pool over budget”问题的时候,可以通过r.Streaming.PoolSize命令修改pool大小,在DefaultEngine.ini [/Script/Engine.RendererSettings]
- 保存FSceneViewport到图片:
void ASceneCaptureActor::PrepareCapture()
{
// Resize screenshot render target to have the same size as the game viewport. Also
// make sure they have the same data format (pixel format, color space, etc.) if possible
UGameViewportClient* GameViewportClient = GEngine->GameViewport;
UE_LOG(LogStats, Log, TEXT("%d"), GameViewportClient->MaxSplitscreenPlayers);
const FSceneViewport* GameViewport = GEngine->GameViewport->GetGameViewport();
FIntPoint ScreenshotSize = GameViewport->GetSizeXY();
EPixelFormat PixelFormat = PF_A2B10G10R10;
bool bIsSRGB = false;
if (!GameViewport->GetRenderTargetTexture())
{
return;
}
ENQUEUE_RENDER_COMMAND(GetBackbufferFormatCmd)(
[GameViewport, &PixelFormat, &bIsSRGB](FRHICommandListImmediate& RHICmdList)
{
FTexture2DRHIRef Texture2DRHI = GameViewport->GetRenderTargetTexture();
check(Texture2DRHI.IsValid());
FIntRect Rect(0, 0, Texture2DRHI->GetSizeX(), Texture2DRHI->GetSizeY());
TArray<FColor> Data;
RHICmdList.ReadSurfaceData(Texture2DRHI, Rect, Data, FReadSurfaceDataFlags());
IImageWrapperModule& ImageWrapperModule = FModuleManager::GetModuleChecked<IImageWrapperModule>(TEXT("ImageWrapper"));
TSharedPtr<IImageWrapper> ImageWrapper = ImageWrapperModule.CreateImageWrapper(EImageFormat::JPEG);
bool bSuccess = ImageWrapper->SetRaw(Data.GetData(), Data.Num() * sizeof(FColor), Rect.Width(), Rect.Height(), ERGBFormat::BGRA, 8);
if (bSuccess)
{
FString TotalFileName = FPaths::Combine(*FPaths::ProjectDir(), TEXT("test.png"));
UE_LOG(LogStats, Log, TEXT("%s"), *TotalFileName);
FArchive* Ar = IFileManager::Get().CreateFileWriter(*TotalFileName);
const TArray64<uint8>& PNGData = ImageWrapper->GetCompressed(100);
Ar->Serialize(const_cast<uint8*>(PNGData.GetData()), PNGData.Num());
delete Ar;
}
else
{
UE_LOG(LogStats, Error, TEXT("JPEG image wrapper failed to accept frame data"));
}
});
}
vulkan相关
- 启动时候加“PrintVulkanPixelFormatMappings”参数,打印支持的纹理格式;
- adb命令相关:
// 启动游戏
%ANDROID_HOME%\platform-tools\adb.exe shell am start -n com.epicgames.VRStreamPluginDemo/com.epicgames.unreal.SplashActivity
发布自己的引擎(Installed Build)
F:\code\UnrealEngine5.1\UnrealEngine\Engine\Build\BatchFiles\RunUAT.bat BuildGraph -target="Make Installed Build Win64" -script=Engine/Build/InstalledEngineBuild.xml -clean
RunUAT.bat BuildGraph -target="Make Installed Build Win64" -script=Engine/Build/InstalledEngineBuild.xml -set:WithMac=false -set:WithAndroid=false -set:WithIOS=false -set:WithTVOS=false -set:WithLinux=false -set:WithHTML5=false -set:WithSwitch=false -WithDDC=false -set:WithWin32=false -set:WithLumin=false -set:WithPS4=false -set:WithXboxOne=false -set:WithHoloLens=false -set:GameConfigurations=Development
RunUAT.bat BuildGraph -target="Make Installed Build Win64" -script=Engine/Build/InstalledEngineBuild.xml -set:WithWin64=true -set:WithWin32=false -set:WithMac=false -set:WithAndroid=false -set:WithIOS=false -set:WithTVOS=false -set:WithLinux=false -set:WithLinuxAArch64=false -set:WithLumin=false -set:WithLuminMac=false -set:WithHoloLens=false -set:WithClient=true -set:WithServer=true -set:VS2019=true
c++ 编程,要经常看
- TSharedPtr和TSharedRef不能用于UObject,因为这两者会根据引用计数自动释放对象,这和GC机制冲突;
- TWeakObjectPtr针对UObject,TWeakPtr针对普通类型;
- 创建U开头的,用NewObject;
- 类的成员变量如果是U开头的对象,要加UPROPERTY,不然会被GC;
- FMemory类申请内存;
- 代理只能用于反射文件中(包含继承自UObject的类文件),绑定的代理函数必须使用UFUNCTION宏声明;
- 输出FString:UE_LOG(LogTemp, Log,TEXT("%s"), *FString);
- 在FRenderResource子类的CreateResrouce中不能调用RHI开头方法,这是在主线程调用的;
- BUF_Volatile类型的顶点buffer需要每帧都创建,因为生命周期只有一帧,见说明;
- BUF_Static类型的顶点buffer需要在render pass外提前创建;
- java传含有中文的字符
const char *nativeAction = jenv->GetStringUTFChars(info, 0);
StreamSubsystem->StreamingState.InfoString = FString(UTF8_TO_TCHAR(nativeAction));
- FString 转 char *:
FString result;
cosnt char * ch = StringCast<ANSICHAR>(*result).Get();
- char * 转FString:
const char * value;
FString s = StringCast<TCHAR>(value).Get();
获取BackBuffer
FSlateApplication::Get().GetRenderer()->OnBackBufferReadyToPresent().AddRaw(this, &FPixelStreamingModule::OnBackBufferReady_RenderThread);
IRendererModule* RendererModule = FModuleManager::GetModulePtr<IRendererModule>(RendererModuleName);
RendererModule->GetResolvedSceneColorCallbacks().AddLambda([MediaTexture](FRDGBuilder& GraphBuilder, const FSceneTextures& SceneTextures)
后期处理的alpha相关
- 发现在工程设置里,把Enable alpha channel support改为非disable,用RenderDoc抓帧,发现SceneColor里的alpha会被写入到交换链;
![](https://img.haomeiwen.com/i6010185/6963fb4004259a42.png)
![](https://img.haomeiwen.com/i6010185/b8bb9ea6a9f60a5b.png)
git ignore
# Visual Studio 2015 user specific files
.vs/
# Compiled Object files
*.slo
*.lo
*.o
*.obj
# Precompiled Headers
*.gch
*.pch
# Compiled Dynamic libraries
*.so
*.dylib
*.dll
# Fortran module files
*.mod
# Compiled Static libraries
*.lai
*.la
*.a
*.lib
# Executables
*.exe
*.out
*.app
*.ipa
# These project files can be generated by the engine
*.xcodeproj
*.xcworkspace
*.sln
*.suo
*.opensdf
*.sdf
*.VC.db
*.VC.opendb
# Precompiled Assets
SourceArt/**/*.png
SourceArt/**/*.tga
# Binary Files
Binaries/*
Plugins/*/Binaries/*
# Builds
Build/*
# Whitelist PakBlacklist-<BuildConfiguration>.txt files
!Build/*/
Build/*/**
!Build/*/PakBlacklist*.txt
# Don't ignore icon files in Build
!Build/**/*.ico
# Built data for maps
*_BuiltData.uasset
# Configuration files generated by the Editor
Saved/*
# Compiled source files for the engine to use
Intermediate/*
Plugins/*/Intermediate/*
# Cache files for the editor to use
DerivedDataCache/*
Tick相关
- 继承FTickableGameObject类可实现tick的调用;(比如:UTickableWorldSubsystem继承的就是这个类)
网友评论