小米互娱VR技术专家房燕良-虚幻4渲染系统架构解析

2020-02-27 534浏览

  • 1.虚幻4渲染系统结构解析 房燕良 2016年9月
  • 2.Overview • 自我介绍 • 3D引擎渲染系统概述 • 虚幻4渲染系统架构 – 游戏线程&渲染线程 – 场景管理与渲染数据管理 – Deferred Shading Scene Renderer • 虚幻4的VR渲染 – 以Google VR HMD插件为例
  • 3.3D引擎渲染系统概述 • 渲染系统架构 – 场景管理与渲染器 – 核心问题是管理复杂度和效率 Scene/Level Management Render Pipeline Resource System (Meshes、Textures) Material System Graphic API(D3D、OpenGL、Metal、Valukan)
  • 4.虚幻4渲染系统概述:Modules • Engine\Source\Runtime • 核心代码模块 – RenderCore – Renderer • RHI抽象层 – RHI:Render Hardware Interface – 基于D3D 11设计 • RHI实现层 – EmptyRHI – Windows\D3D11RHI – Apple\MetalRHI – OpenGLDrv、VulkanRHI
  • 5.虚幻4渲染系统概述:渲染线程 • 从虚幻3开始引入了渲染线程—Gemini • 渲染线程对效率的提升 – 最耗时的系统:渲染、游戏逻辑/脚本、物理模拟 – 没有渲染线程 Game Render Frame 1 Game Render Frame 2 Game Render Frame 3 – 使用渲染线程 Game Render Frame 1 Game Render Frame 2 Game Render Frame 3
  • 6.虚幻4渲染系统概述:渲染线程 • 主线程领先2帧 – Front Buffer:N,Render Thread:N+1,GameThread:N+2 – Render Command Fence:防止Game Thread跑太快 • 场景数据管理 – 主线程管理场景数据;渲染线程使用Proxy对象; – 渲染线程管理一份当前帧的拷贝 Main Thread Main Thread Fence Render Command Queue Rendering Thread Render Hardware Interface Render Thread
  • 7.虚幻4渲染系统概述:核心类的静态结构
  • 8.虚幻4渲染系统概述:核心类的静态结构
  • 9.虚幻4基本渲染流程 • Game线程 voidUGameEngine::Tick(float DeltaSeconds, bool bIdleMode ) {UGameEngine::RedrawViewports(){ voidFViewport::Draw(bool bShouldPresent) { voidUGameViewportClient::Draw(){ //-- 计算ViewFamily、View的各种属性ULocalPlayer::CalcSceneView();//-- 发送渲染命令:FDrawSceneCommandFRendererModule::BeginRenderingViewFamily()//-- Draw HUD PlayerController->MyHUD->PostRender(); } }}} FrameEndSync.Sync();
  • 10.虚幻4基本渲染流程 • Game线程 voidFRendererModule::BeginRenderingViewFamily(){ // render proxies update World->SendAllEndOfFrameUpdates(); // Construct the scene renderer. // This copies the view family attributes // into its own structures. FSceneRenderer* SceneRenderer =FSceneRenderer::CreateSceneRenderer(ViewFamily);ENQUEUE_UNIQUE_RENDER_COMMAND_ONEPARAMETER( FDrawSceneCommand, FSceneRenderer*,SceneRenderer,SceneRenderer, { RenderViewFamily_RenderThread(RHICmdList, SceneRenderer); FlushPendingDeleteRHIResources_RenderThread(); }); }
  • 11.虚幻4基本渲染流程 • 渲染线程 – RenderViewFamily_RenderThread() –FSceneRenderer::Render()– InitViews() • Primitive Visibility Determination:Frustum Cull+Occlusion Cull • Light Visibility:Frustum Cull • 透明物体排序:Back to Front • 不透明物体排序:Front to Back – 渲染Scene Color – Post Process
  • 12.虚幻4的延迟渲染 • FDeferredShadingSceneRenderer –GBuffers:class FSceneRenderTargets – DeferredShadingCommon.usf Name GBufferA GBufferB GBufferC Format PF_A2B10G10R10 PF_B8G8R8A8 PF_B8G8R8A8 Usage WorldNormal:xyz Metallic:r Specular:g Roughness:b ShadingModelID:a BaseColor:rgb GBufferAO:a
  • 13.虚幻4的延迟渲染 • FDeferredShadingSceneRenderer
  • 14.虚幻4的延迟渲染 voidFDeferredShadingSceneRenderer::Render(){ boolFDeferredShadingSceneRenderer::InitViews(){ //-- Visibility determination. voidFSceneRenderer::ComputeViewVisibility(){ FrustumCull(); OcclusionCull(); } //-- 透明对象排序:back to frontFTranslucentPrimSet::SortPrimitives();//determine visibility of each light DoFrustumCullForLights(); //-- Base Pass对象排序:front to back voidFDeferredShadingSceneRenderer::SortBasePassStaticData();} // 下页继续 }
  • 15.虚幻4的延迟渲染 voidFDeferredShadingSceneRenderer::Render(){ //-- EarlyZPassFDeferredShadingSceneRenderer::RenderPrePass();RenderOcclusion(); //-- Build Gbuffers SetAndClearViewGBuffer();FDeferredShadingSceneRenderer::RenderBasePass();FSceneRenderTargets::FinishRenderingGBuffer();//-- Lighting stage RenderLights(); RenderDynamicSkyLighting(); RenderAtmosphere(); RenderFog(); RenderTranslucency(); RenderDistortion(); //-- post processing SceneContext.ResolveSceneColor();FPostProcessing::Process();FDeferredShadingSceneRenderer::RenderFinish();}
  • 16.虚幻4的延迟渲染 voidFDeferredShadingSceneRenderer::RenderLights(){ foreach(FLightSceneInfoCompact light IN Scene->Lights) { voidFDeferredShadingSceneRenderer::RenderLight(Light){ RHICmdList.SetBlendState(Additive Blending); // DeferredLightVertexShaders.usf VertexShader = TDeferredLightVS; // DeferredLightPixelShaders.usf PixelShader = TDeferredLightPS; switch(Light Type) { case LightType_Directional:DrawFullScreenRectangle(); case LightType_Point:StencilingGeometry::DrawSphere();case LightType_Spot:StencilingGeometry::DrawCone();} } } }
  • 17.虚幻4的VR渲染 • 虚幻4的渲染系统与Unity3D的架构不同 – 在Unity3D中,Camera管理一个渲染管线 – 虚幻4将VR渲染流程整合进引擎底层 – Scene View Family、Scene View • Case Study:Google VR HMD插件 – 代码目录:Plugins/Runtime/GoogleVR/GoogleVRHMD – VR渲染系统的静态结构 – VR渲染流程概述
  • 18.虚幻4的VR渲染
  • 19.虚幻4的VR渲染 • 创建HMD Device //-- 在引擎启动时,会创建所有的HMD设备 voidUEngine::Init(){ boolUEngine::InitializeHMDDevice(){ for (auto HMDModuleIt = HMDModules.CreateIterator(); HMDModuleIt; ++HMDModuleIt) { IHeadMountedDisplayModule* HMDModule = *HMDModuleIt; HMDDevice = HMDModule->CreateHeadMountedDisplay(); } } }
  • 20.虚幻4的VR渲染 • 绘制流程入口 //-- 在View绘制时,如果是Stereo则绘制两个View voidUGameViewportClient::Draw(){ const bool bEnableStereo = GEngine->IsStereoscopic3D(InViewport); int32 NumViews = bEnableStereo ? 2 : 1; for (int32 i = 0; i < NumViews; ++i) { } }
  • 21.虚幻4的VR渲染 • IStereoRendering接口调用 voidUGameViewportClient::Draw(){ULocalPlayer::CalcSceneView(){ULocalPlayer::GetProjectionData(){ GEngine->StereoRenderingDevice->AdjustViewRect(StereoPass); GEngine->StereoRenderingDevice->CalculateStereoViewOffset(StereoPass); ProjectionData.ProjectionMatrix = GEngine->StereoRenderingDevice ->GetStereoProjectionMatrix(StereoPass); } } }
  • 22.虚幻4的VR渲染 • GoogleVRHMD实现 voidFGoogleVRHMD::AdjustViewRect(StereoPass,int32& X, int32& Y, uint32& SizeX, uint32& SizeY) const { SizeX = SizeX / 2; if( StereoPass == eSSP_RIGHT_EYE ) X += SizeX; } voidFGoogleVRHMD::CalculateStereoViewOffset(){ const float EyeOffset = (GetInterpupillaryDistance() * 0.5f) * WorldToMeters; const float PassOffset = (StereoPassType == eSSP_LEFT_EYE) ? -EyeOffset : EyeOffset; ViewLocation += ViewRotation.Quaternion().RotateVector(FVector(0,PassOffset,0 )); }
  • 23.虚幻4的VR渲染 • GoogleVRHMD实现 voidFGoogleVRHMD::RenderTexture_RenderThread(){ gvr_distort_to_screen(GVRAPI, SrcTexture->GetNativeResource(), CachedDistortedRenderTextureParams, &CachedPose, &CachedFuturePoseTime); }
  • 24.THANKS 扫码关注我的微信公众号