I don’t see any performance issue in The Witcher 3. The reason why open world like Witcher 3 has 184m² tiles (58.5m² for TES: Oblivion) is bigger tiles means more objects per tile so slower loading/streaming times
Let’s not completely derail the discussion.
loading times may be lower, but drawcall count is higher impact so they must be doing something different with the far portions of a landscape, like a custom lod system.
adding rtv to an 8km tile doesn’t really increase performance on a good material. On a bad one it does wonders.
its essentially a give and take - as well as how much man power you have.
you could set 100k tiles up with rtvs now, via automated scripts, in a couple days or so.
BUT, the final size of the project would be impacted…
i think i found another issue with RVTs:
i have a landscape with plenty of height-blended-layers (baselayer is alpha-blended). i write the resulting basecolor, spec, roughness and normal into the RVT-output.
in my lets say rock-material i use a RVT sampler to lookup the landscape RVT and do some distance based blending (using another RVT from the landscape that writes height).
now the problem:
all channels in the blend appear fine beside the basecolor one. the basecolor only shows the alpha-blended baselayer form my layerblend. all other channels (normal, spec, roughness) show up in the blend correctly (as in show the different e.g. normal maps of my different painted layers). only the basecolor shows nothing of my painted layers beside the baseone. i tried different RVT colorformats and compression without solving effect.
does the basecolor in the RVT ignore heightblend layer-input? how is the RVT node able to recognize them? and why doesnt it ignore height-blend for e.g. the normal if this tries to be something clever?
Ok so RVT actually works on tiled landscape with only one single RVT and one RVT volume.
- RVT volume in persistent level. Scale of the volume should be set manualy to whole landscape size because “copy bounds” returns wrong scale
- RVT size has to be set really high to get correct texture quality on landscape (had to set mine to 4096-1024-4). Texture resolution looks 1:1 to non RVT landscape material with 8km² landscape. Larger landscape would still need adaptive virtual texture to be added to the engine.
- Unfortunatly, the virtual texture asset has to be manualy assigned to each LandscapeStreamingProxy because they don’t use the Landscape actor settings. It’s time consuming if you work with 1000 tiles (you can load many tiles, select all LandscapeStreamingProxy and set the virtual texture in one time if you have enough RAM/VRAM to load them)
RVT is cool for final optimization but can’t really be used while working on level design because:
- Layers preview in the paint tool are all black (so you have to chose a good name for your layers and remember how they look)
- RVT updates really slowly in editor so painting landscape layers is not realtime but takes time to update
We tested out RVT for tiled landscape yesterday to get a feel for the Memory and Processing effects and the overall runtime cost and benefits seemed pretty good. But the actually setup and working with RVT for a tiled world as others have stated are pretty painful. The first test we did used 3x3 1km tiles and the largest RVT size with a volume set to capture the whole area. This worked fine, but the resulting texel density was too low compared to our needs and ended up creating a noticeably low res landscape compared to other objects in the scene. Switching to using separate volumes per tile each with its own RVT and then modifying our master RVT version of the landscape material to use a series of switches to use the proper sampler let us somewhat simplify the process, but this would not be feasible for all the tiles in our world and it was still painful. Placement of the volumes based on tiles is tedious as it has to go in the center and the copy bounds doesn’t let you use the proxy as a source for instance.
Given that currently our designs on focusing on making a specific 1x2 km section of the world our playable test area this really wouldn’t have deterred us since we actually unload any Landscapes beyond the immediate bordering ones to optimization and use Static Mesh LOD’s and a very simple and lower resolution Material which we bake the textures for separately. But this would eventually need to be expanded upon over time and most importantly the borders for the tiles would need to be completely seamless. Unfortunately for us we found very noticeable seams were being created with separate tile RVT as shown in the attached images. It’s actually most notable from a distance from various angles, no amount of adjustment would eliminate it that we could find.
We’d really like to use this feature in our large open world setup, but currently given the visible seams, and some of the other reasons given in this thread we’ve decided not to make the switch for now and just watch for future improvements to hopefully make it more viable for this setup. It looks very promising as we would love to leverage the benefits of the approach.
It is worth noting that we have also implemented SVT in our project for objects using large textures, and likely have more optimization to do for using that, so we were very interested in seeing how both implementations would work together.
They stated before that they are aware of these limitations when it comes to large terrains and they plan to improve it. So you will need to just wait. Maybe until 4.26 or UE5, who knows.
I should mention that RVT and SVT don’t really work well together at the moment. Runtime VT will cache the results of evaluating material using streaming VT, but it will likely cache low resolution streaming data. To make this work properly, there needs to be feedback from SVT to continuously invalidate/update the cached RVT until the SVT is sufficiently streamed in, but this system doesn’t currently exist. It’s not a great solution anyway, since even it will reduce the savings gained from cached RVT.
In the 4.24 and 4.25, every time I import UDIM textures into the engine. the textures automatically become one texture file even I didn’t enable virtual texture streaming.
So I want to know, is there any way I can import those UDIM files separately like the old days? If there is a way to control the virtual texture not get blurred will be better.
The reason why I don’t want to use VT is when I rendered out the sequence images sometimes there are several mipped textures. It’s very annoying but I still didn’t get a solution for that.
Any tips for solving an issue with Runtime Virtual Texture streaming?
I have a mesh with UDIMs. The texture it uses as a Virtual texture is 8192x4096. When I change the texture option from low/medium to high/epic the editor crashes. It also crashes a standalone test. And it does the same in a new project as well
Here is my crash log
Fatal error: [File:D:/Build/++UE4+Licensee/Sync/Engine/Source/Runtime/RenderCore/Private/RenderingThread.cpp] [Line: 855]
Rendering thread exception:
Assertion failed: BlockWidthInTiles > 0u [File:D:/Build/++UE4+Licensee/Sync/Engine/Source/Runtime/Renderer/Private/VT/VirtualTextureSystem.cpp] [Line: 420]
0x00007ff9e1c63e49 KERNELBASE.dll!UnknownFunction ]
0x00007ff96382e9e6 UE4Editor-Core.dll!ReportAssert() [D:\Build\++UE4+Licensee\Sync\Engine\Source\Runtime\Core\Private\Windows\WindowsPlatformCrashContext.cpp:1541]
0x00007ff963831dc8 UE4Editor-Core.dll!FWindowsErrorOutputDevice::Serialize() [D:\Build\++UE4+Licensee\Sync\Engine\Source\Runtime\Core\Private\Windows\WindowsErrorOutputDevice.cpp:78]
0x00007ff9635be53d UE4Editor-Core.dll!FOutputDevice::LogfImpl() [D:\Build\++UE4+Licensee\Sync\Engine\Source\Runtime\Core\Private\Misc\OutputDevice.cpp:61]
0x00007ff9635497b5 UE4Editor-Core.dll!AssertFailedImplV() [D:\Build\++UE4+Licensee\Sync\Engine\Source\Runtime\Core\Private\Misc\AssertionMacros.cpp:100]
0x00007ff96354baf0 UE4Editor-Core.dll!FDebug::CheckVerifyFailedImpl() [D:\Build\++UE4+Licensee\Sync\Engine\Source\Runtime\Core\Private\Misc\AssertionMacros.cpp:450]
0x00007ff955e0f360 UE4Editor-Renderer.dll!FVirtualTextureSystem::AllocateVirtualTexture() [D:\Build\++UE4+Licensee\Sync\Engine\Source\Runtime\Renderer\Private\VT\VirtualTextureSystem.cpp:420]
0x00007ff95dc9158f UE4Editor-Engine.dll!FMaterialRenderProxy::AllocateVTStack() [D:\Build\++UE4+Licensee\Sync\Engine\Source\Runtime\Engine\Private\Materials\MaterialShared.cpp:2300]
0x00007ff95dca91fd UE4Editor-Engine.dll!FMaterialRenderProxy::EvaluateUniformExpressions() [D:\Build\++UE4+Licensee\Sync\Engine\Source\Runtime\Engine\Private\Materials\MaterialShared.cpp:2352]
0x00007ff95dce0c50 UE4Editor-Engine.dll!FMaterialRenderProxy::UpdateDeferredCachedUniformExpressions() [D:\Build\++UE4+Licensee\Sync\Engine\Source\Runtime\Engine\Private\Materials\MaterialShared.cpp:2558]
0x00007ff955c6fb3c UE4Editor-Renderer.dll!TEnqueueUniqueRenderCommandType<`FRendererModule::BeginRenderingViewFamily'::`2'::UpdateDeferredCachedUniformExpressionsName,<lambda_77df84eb2b43742b6e3959e275acf541> >::DoTask() [D:\Build\++UE4+Licensee\Sync\Engine\Source\Runtime\RenderCore\Public\RenderingThread.h:195]
0x00007ff955c7337d UE4Editor-Renderer.dll!TGraphTask<TEnqueueUniqueRenderCommandType<`FRendererModule::BeginRenderingViewFamily'::`2'::UpdateDeferredCachedUniformExpressionsName,<lambda_77df84eb2b43742b6e3959e275acf541> > >::ExecuteTask() [D:\Build\++UE4+Licensee\Sync\Engine\Source\Runtime\Core\Public\Async\TaskGraphInterfaces.h:849]
0x00007ff9633687d8 UE4Editor-Core.dll!FNamedTaskThread::ProcessTasksNamedThread() [D:\Build\++UE4+Licensee\Sync\Engine\Source\Runtime\Core\Private\Async\TaskGraph.cpp:692]
0x00007ff963368aa3 UE4Editor-Core.dll!FNamedTaskThread::ProcessTasksUntilQuit() [D:\Build\++UE4+Licensee\Sync\Engine\Source\Runtime\Core\Private\Async\TaskGraph.cpp:587]
0x00007ff962a3f892 UE4Editor-RenderCore.dll!RenderingThreadMain() [D:\Build\++UE4+Licensee\Sync\Engine\Source\Runtime\RenderCore\Private\RenderingThread.cpp:341]
0x00007ff962a453d4 UE4Editor-RenderCore.dll!FRenderingThread::Run() [D:\Build\++UE4+Licensee\Sync\Engine\Source\Runtime\RenderCore\Private\RenderingThread.cpp:473]
0x00007ff96385025b UE4Editor-Core.dll!FRunnableThreadWin::Run() [D:\Build\++UE4+Licensee\Sync\Engine\Source\Runtime\Core\Private\Windows\WindowsRunnableThread.cpp:86]
0x00007ff963847c30 UE4Editor-Core.dll!FRunnableThreadWin::GuardedRun() [D:\Build\++UE4+Licensee\Sync\Engine\Source\Runtime\Core\Private\Windows\WindowsRunnableThread.cpp:35]
0x00007ff9e21e6fd4 KERNEL32.DLL!UnknownFunction ]
0x00007ff9e403cec1 ntdll.dll!UnknownFunction ]
Sorry for the confusion, what I mean is that we use SVT as well as RVT in the same project, but we don’t use them together in the same material, our Landscape master material is separate from our environment props master which actually uses the new Material Layer Blend stack which is not possible to use in landscapes. We are planning to use RVT for the landscape with non-SVT textures, and use SVT on larger object textures, we don’t currently plan to mix both SVT and RVT into the same materials but its good to know this is not a recommended approach we will avoid any thoughts of trying it. The nice benefit of this approach in the project though is SVT saves us some memory in our environmental props, which we then plan to spend in RVT to lower the landscape complexity and also let us potentially bump up the landscape material complexity a bit for better effect. As we understood it this seems like the optimal approach to using them together in the same project.
Since the thread was about both types of VT’s I wanted to add they are currently using SVT as well and have not had any issues regarding that use.
I hadn’t actually seen this posted anywhere but I assumed since its early there would be more improvements coming, just providing some feedback on what I’ve seen so far trying to use it. Since the goal of UE5 is to support large worlds I would imagine this to be the case. Thanks for the info.
I am confused about how RVT handles mips.
Suppose I have a landscape material that previously used camera distance to blend detail. e.g. At far distance a noise texture is applied to reduce tiling effects.
On the stream, they indicated to use Mip level as a proxy for camera distance. This makes sense - and I can see that you can pass the mip level when reading the RVT.
But what still confuses me is when/how are the RVT mip levels created - when the RVT cache is created does it store the various blended values directly in each RVT mip? In this instance, the mip is not auto calculated by the hardware?
In other words, does it render the full rvt at all mip levels when caching?
Thanks for any insight
Hi guys,
I’ve been struggling to get UDIMS working on terrain inside UE4 and was wondering if I was doing anything obviously wrong.
- I have an fbx exported from Houdini with 25 UDIMS 5x5.
- I have a set of maps exported from substance painter - AO maps.
- When I import the maps to UE4 they come in as one file with the VT icon and I have enabled Virtual Textures in the settings menu.
- I then do a basic material and apply the map to the terrain and it looks tiled for some reason, as in the image below.
- I have tried the maps with both types of naming AO_1001.png and AO.1001.png.
- Also tried adding a Virtual Texture Runtime Volume.
Am I missing something here guys? My ultimate aim is to be able to run regular quixel tileable materials through the AO UDIM mask that I have painted in Substance painter but at the moment I cant even get a basic UDIM set of maps to work.
Any help would be appreciated.
> When I import the maps to UE4 they come in as one file with the VT icon and I have enabled Virtual Textures in the settings menu.
This is working as intended.
> I then do a basic material and apply the map to the terrain and it looks tiled for some reason, as in the image below.
Sounds like a problem with your UVs? A 5x5 UDIM texture will need UVs in the range 0.0-5.0 in order to cover the full UDIM space. I’m not actually sure how terrain UVs work, but you might try scaling the UVs in your material.
> I have tried the maps with both types of naming AO_1001.png and AO.1001.png
You should be using Name.1001.png, Name_1001.png won’t be detected as a UDIM
> Also tried adding a Virtual Texture Runtime Volume
Runtime VT won’t work correctly when combined with streaming VT (which includes UDIM). Runtime VT will cache the material results, which means you’ll typically end up caching the low resolution streaming VT mips. There’s currently no mechanism for streaming VT to invalidate the runtime VT cache when new tiles stream in (and it’s not clear if this functionality makes sense to add).
Hi, beningram.
My question is about Virtual Heightfield!
I just found out that Unreal 4.26 has such a feature and I prepared this tutorial for it:
but there are many things that there is no explanation for it.
Is it possible to use a texture instead of mesh to create a decal-like heightfield? and is it possible to create a negative height?
and can you explain a little more about Virtual Heightfield?
Hi y’all! I was wondering if the issue of ‘‘Sample Parameter’’ for RVT has any kind of fixes? It’s really troublesome. In addition, if the node RVT Sampler is inside a MF, it doesn’t work at all, which keeps us to have clean graphs that uses MF instead of the whole setup showcased…
Hi, so ive been looking around since virtual texturing was released, no one really answered my question: Is it possible to update a Virtual Texture at runtime? It seems virtual textures like the road example only works in editor…
What happened to any development regarding Virtual Textures in 4.26 ? I’ve searched UE4 Github repo and it seems there is literally 0 commits related to VTs after April. So sad…
I understand that UE5 is eating more and more of your time but come on, VT do not even support Opacity Mask sampling…
In 4.26 VT works well at runtime.in the previous version, you should convert RVT volume to blueprint.