Unreal Engine 5 и VR с нуля. Часть 10. Unreal Engine 5.5.3. Настройка VR проекта на С++ для Meta Quest 2, 3, 3s, PRO.
Введение
Давно ничего не писал, изучал базу С++ (до сих пор изучаю), знакомился с апи Unreal Engine, читаю книги и смотрю на реализации других авторов. В общем всё по плану прошлой статьи. Думаю пора начать Pet-проект, а может и что-то интересное из этого выйдет.В качестве IDE использую Rider, по-моему на нём куда стабильнее работать чем Visual Studio.Общими вещами, механиками, я буду делиться в статьях. Чем то уникальным для проекта делиться смысла нет, иначе вроде и смысла тогда в проекте не будет.
Настройка Unreal Engine 5.5
Есть видео основанное на документе по настройке UE 5.5 https://www.youtube.com/watch?v=EClbEbNcl4k&list=LL&index=6&ab_channel=MamadouBabaei
Не забываем установить пакеты под целевую платформу Android
Создание проекта
Доля рынка VR всё равно вышел на мобильных проектах, поэтому создавать проект буду на Meta Quest 2, 3, 3s, PRO.
Если что-то получится, можно расшириться на PICO. А еще в след году обещают выпустить мобильную гарнитуру Samsung и Steam.
Поэтому запускаю Unreal Engine 5.5.3 и выбираю:
проект Blank,
C++,
Target Platform: Mobile,
Quality Preset: Maximum
Добавляем плагины MetaXR, MetaXRAudio с сайта:
Листай ниже если не хочешь компилировать под UE 5.5MetaXRAudio компилируем под версию Unreal Engine 5.5 (если используете 5.4, то ничего делать не надо) Инструкция по компиляции плагина под движок - https://developers.meta.com/horizon/documentation/unreal/meta-xr-audio-sdk-unreal-req-setup/#repackaing-for-a-different-version-of-unreal-engine Помещаем их в папку
Добавил папку Android из плагина версии 5.4, без него билд не собирался
Скомпилированные плагины для Unreal Engine 5.5
Можно скачать MetaXR audio скомпилированный мной - https://drive.google.com/drive/folders/1CqixHao8yEvJhiO8BVgK8VKhBeg6Zj4m?usp=sharing
и сразу активируем его.
В папке проекта создаем папку Build (для билдов).
Создаем .gitignore для системы контроля версий (если у вас установлен Git), внутри может быть минимальный набор ограничений для Git:
.idea
.vs
*.sln
DerivedDataCache/
Intermediate/
Saved/
Binaries/
Build/
Настроим Meta XR Audio:
Справочные материалы для Meta Quest и Настройки Rendering для Mobile графики выбранные мной (не тестировал на сложных сценах).
Хочется еще подобрать настройки для ПК версии, но пока нет времени.
Описание всех настроек Rendering в Unreal Engine:
[По желанию при отладке уровня] можно добавить в [/Script/Engine.RendererSettings] r.Streaming.PoolSize = 500
такое значение описано как рекомендуемое для Meta Quest (300-500 mb)
О пуле потоковой передачи текстур: https://dev.epicgames.com/community/learning/knowledge-base/a3vO/unreal-engine-why-is-my-texture-streaming-pool-giving-me-a-warning
НЕ ИСПОЛЬЗУЙТЕ MOBILE HDR и MOBILE MULTI VIEW вместе! При движении камеры это вызывает ошибки рендеринга. В итоге я отказался от MOBILE HDR. Пример ошибки рендеринга в видео:
рутуб:
ютуб:
Дополнительно составил список с описаниями моих настроек на которых успешно собирается билд для apk, возможно будет редактироваться в будущем:
Путь - [YourProject]/Config/DefaultEngine.ini
[/Script/Engine.RendererSettings]
r.Mobile.ShadingPath = 0
r.Mobile.AllowDeferredShadingOpenGL = False
r.Mobile.SupportGPUScene = True
r.Mobile.AntiAliasing = 3
r.Mobile.FloatPrecisionMode = 0
r.Mobile.AllowDitheredLODTransition = False
r.Mobile.VirtualTextures = False
r.DiscardUnusedQuality = True
r.AllowOcclusionQueries = True
r.MinScreenRadiusForLights = 0.050000
r.MinScreenRadiusForDepthPrepass = 0.050000
r.PrecomputedVisibilityWarning = False
r.TextureStreaming = True
Compat.UseDXT5NormalMaps = False
r.VirtualTextures = False
r.VT.EnableAutoImport = False
r.VirtualTexturedLightmaps = False
r.VT.AnisotropicFiltering = False
bEnableVirtualTextureOpacityMask = False
bEnableVirtualTexturePostProcessing = False
r.VT.TileSize = 128
r.VT.TileBorderSize = 4
r.vt.FeedbackFactor = 16
r.MeshPaintVirtualTexture.TileSize = 32
r.MeshPaintVirtualTexture.TileBorderSize = 2
r.MeshPaintVirtualTexture.UseCompression = False
r.StaticMesh.DefaultMeshPaintTextureSupport = False
r.MeshPaintVirtualTexture.DefaultTexelsPerVertex = 4
r.MeshPaintVirtualTexture.MaxTextureSize = 4096
r.vt.rvt.EnableBaseColor = True
r.vt.rvt.EnableBaseColorRoughness = True
r.vt.rvt.EnableBaseColorSpecular = True
r.vt.rvt.EnableMask4 = True
r.vt.rvt.EnableWorldHeight = True
r.vt.rvt.EnableDisplacement = True
r.vt.rvt.HighQualityPerPixelHeight = True
WorkingColorSpaceChoice = sRGB
RedChromaticityCoordinate = (X=0.640000,Y=0.330000)
GreenChromaticityCoordinate = (X=0.300000,Y=0.600000)
BlueChromaticityCoordinate = (X=0.150000,Y=0.060000)
WhiteChromaticityCoordinate = (X=0.312700,Y=0.329000)
r.LegacyLuminanceFactors = False
r.ClearCoatNormal = False
r.DynamicGlobalIlluminationMethod = 0
r.ReflectionMethod = 0
r.ReflectionCaptureResolution = 128
r.ReflectionEnvironmentLightmapMixBasedOnRoughness = True
r.Lumen.HardwareRayTracing = False
r.Lumen.HardwareRayTracing.LightingMode = 0
r.Lumen.TranslucencyReflections.FrontLayer.EnableForProject = False
r.Lumen.TraceMeshSDFs = 1
r.Lumen.ScreenTracingSource = 0
r.Lumen.Reflections.HardwareRayTracing.Translucent.Refraction.EnableForProject = False
r.MegaLights.EnableForProject = False
r.RayTracing.Shadows = False
r.Shadow\.Virtual.Enable = 0
r.RayTracing = False
r.RayTracing.UseTextureLod = False
r.PathTracing = False
r.GenerateMeshDistanceFields = False
r.DistanceFields.DefaultVoxelDensity = 0.200000
r.Nanite.ProjectEnabled = False
r.AllowStaticLighting = True
r.NormalMapsForStaticLighting = True
r.ForwardShading = True
r.VertexFoggingForOpaque = False
r.SeparateTranslucency = False
r.TranslucentSortPolicy = 0
TranslucentSortAxis = (X=0.000000,Y=-1.000000,Z=0.000000)
r.LocalFogVolume.ApplyOnTranslucent = False
xr.VRS.FoveationLevel = 3
xr.VRS.DynamicFoveation = False
r.CustomDepth = 1
r.CustomDepthTemporalAAJitter = False
r.PostProcessing.PropagateAlpha = False
r.Deferred.SupportPrimitiveAlphaHoldout = False
r.DefaultFeature.Bloom = True
r.DefaultFeature.AmbientOcclusion = False
r.DefaultFeature.AmbientOcclusionStaticFraction = False
r.DefaultFeature.AutoExposure = False
r.DefaultFeature.AutoExposure.Method = 2
r.DefaultFeature.AutoExposure.Bias = 1.000000
r.DefaultFeature.AutoExposure.ExtendDefaultLuminanceRange = True
r.DefaultFeature.LocalExposure.HighlightContrastScale = 0.800000
r.DefaultFeature.LocalExposure.ShadowContrastScale = 0.800000
r.DefaultFeature.MotionBlur = False
r.DefaultFeature.LensFlare = False
r.AntiAliasingMethod = 0
r.TemporalAA.Upsampling = False
r.MSAACount = 4
r.DefaultFeature.LightUnits = 1
r.DefaultBackBufferPixelFormat = 4
r.ScreenPercentage.Default = 100.000000
r.ScreenPercentage.Default.Desktop.Mode = 1
r.ScreenPercentage.Default.Mobile.Mode = 0
r.ScreenPercentage.Default.VR.Mode = 0
r.ScreenPercentage.Default.PathTracer.Mode = 0
r.Shadow\.UnbuiltPreviewInGame = False
r.StencilForLODDither = False
r.EarlyZPass = 3
r.EarlyZPassOnlyMaterialMasking = False
r.Shadow\.CSMCaching = True
r.DBuffer = False
r.ClearSceneMethod = 1
r.VelocityOutputPass = 0
r.Velocity.EnableVertexDeformation = 2
r.SelectiveBasePassOutputs = False
bDefaultParticleCutouts = False
fx.GPUSimulationTextureSizeX = 1024
fx.GPUSimulationTextureSizeY = 1024
r.AllowGlobalClipPlane = False
r.GBufferFormat = 1
r.MorphTarget.Mode = True
r.MorphTarget.MaxBlendWeight = 5.000000
r.SupportSkyAtmosphere = True
r.SupportSkyAtmosphereAffectsHeightFog = True
r.SupportExpFogMatchesVolumetricFog = False
r.SupportLocalFogVolumes = True
r.SupportCloudShadowOnForwardLitTranslucent = False
r.LightFunctionAtlas.Format = 0
r.VolumetricFog.LightFunction = False
r.Deferred.UsesLightFunctionAtlas = False
r.SingleLayerWater.UsesLightFunctionAtlas = False
r.Translucent.UsesLightFunctionAtlas = False
r.Translucent.UsesIESProfiles = False
r.Translucent.UsesRectLights = False
r.GPUCrashDebugging = False
vr.InstancedStereo = True
r.MobileHDR = False
vr.MobileMultiView = True
r.Mobile.UseHWsRGBEncoding = True
vr.RoundRobinOcclusion = False
r.MeshStreaming = False
r.HeterogeneousVolumes = False
r.HeterogeneousVolumes.Shadows = False
r.Translucency.HeterogeneousVolumes = False
r.WireframeCullThreshold = 5.000000
r.SupportStationarySkylight = True
r.SupportLowQualityLightmaps = True
r.SupportPointLightWholeSceneShadows = True
r.Shadow\.TranslucentPerObject.ProjectEnabled = False
r.Water.SingleLayerWater.SupportCloudShadow = False
r.Substrate = False
r.Substrate.OpaqueMaterialRoughRefraction = True
r.Refraction.Blur = True
r.Substrate.Debug.AdvancedVisualizationShaders = False
r.Material.RoughDiffuse = False
r.Material.EnergyConservation = False
r.Material.DefaultAutoMaterialUsage = True
r.OIT.SortedPixels = False
r.HairStrands.LODMode = False
r.SkinCache.CompileShaders = True
r.VRS.Support = True
r.SkinCache.SkipCompilingGPUSkinVF = False
r.SkinCache.DefaultBehavior = 1
r.SkinCache.SceneMemoryLimitInMB = 128.000000
r.Mobile.EnableStaticAndCSMShadowReceivers = False
r.Mobile.EnableMovableLightCSMShaderCulling = True
r.Mobile.Forward.EnableLocalLights = 1
r.Mobile.Forward.EnableClusteredReflections = False
r.Mobile.AllowDistanceFieldShadows = False
r.Mobile.EnableMovableSpotlightsShadow = False
r.GPUSkin.Support16BitBoneIndex = False
r.GPUSkin.Limit2BoneInfluences = False
r.SupportDepthOnlyIndexBuffers = False
r.SupportReversedIndexBuffers = False
r.Mobile.AmbientOcclusion = False
r.Mobile.DBuffer = False
r.GPUSkin.UnlimitedBoneInfluences = False
r.GPUSkin.AlwaysUseDeformerForUnlimitedBoneInfluences = False
r.GPUSkin.UnlimitedBoneInfluencesThreshold = 8
DefaultBoneInfluenceLimit = (Default=0,PerPlatform=())
MaxSkinBones = (Default=65536,PerPlatform=(("Mobile", 256)))
r.Mobile.PlanarReflectionMode = 0
r.Mobile.ScreenSpaceReflections = False
r.Mobile.SupportsGen4TAA = False
bStreamSkeletalMeshLODs = (Default=False,PerPlatform=())
bDiscardSkeletalMeshOptionalLODs = (Default=False,PerPlatform=())
VisualizeCalibrationColorMaterialPath = /Engine/EngineMaterials/PPM\_DefaultCalibrationColor.PPM\_DefaultCalibrationColor
VisualizeCalibrationCustomMaterialPath = None
VisualizeCalibrationGrayscaleMaterialPath = /Engine/EngineMaterials/PPM\_DefaultCalibrationGrayscale.PPM\_DefaultCalibrationGrayscale
r.AllowGlobalClipPlane = False
Прописываем Описание проекта в нас��ройках, чтобы эта запись была внутри каждого .h файла. Она будет уникальна для Вашего проекта.
С такими настройками мне успешно удалось собрать apk для Meta Quest и запустить его на шлеме.