Fix triplanar texture mapping when using Large Worlds

#3001
This commit is contained in:
Wojtek Figat
2025-02-11 00:31:37 +01:00
parent a5fffc0c9e
commit 58090aa6d6
4 changed files with 21 additions and 3 deletions

View File

@@ -3,6 +3,7 @@
#include "MaterialShader.h"
#include "Engine/Core/Log.h"
#include "Engine/Serialization/MemoryReadStream.h"
#include "Engine/Level/LargeWorlds.h"
#include "Engine/Renderer/RenderList.h"
#include "Engine/Graphics/RenderTask.h"
#include "Engine/Graphics/GPUDevice.h"
@@ -33,6 +34,8 @@ GPU_CB_STRUCT(MaterialShaderDataPerView {
Float4 ViewInfo;
Float4 ScreenSize;
Float4 TemporalAAJitter;
Float3 LargeWorldsChunkIndex;
float LargeWorldsChunkSize;
});
IMaterial::BindParameters::BindParameters(::GPUContext* context, const ::RenderContext& renderContext)
@@ -78,6 +81,8 @@ void IMaterial::BindParameters::BindViewData()
cb.ViewInfo = view.ViewInfo;
cb.ScreenSize = view.ScreenSize;
cb.TemporalAAJitter = view.TemporalAAJitter;
cb.LargeWorldsChunkIndex = LargeWorlds::Enable ? (Float3)Int3(view.Origin / LargeWorlds::ChunkSize) : Float3::Zero;
cb.LargeWorldsChunkSize = LargeWorlds::ChunkSize;
// Update constants
GPUContext->UpdateCB(PerViewConstants, &cb);

View File

@@ -10,7 +10,7 @@
/// <summary>
/// Current materials shader version.
/// </summary>
#define MATERIAL_GRAPH_VERSION 169
#define MATERIAL_GRAPH_VERSION 170
class Material;
class GPUShader;

View File

@@ -697,10 +697,11 @@ void MaterialGenerator::ProcessGroupTextures(Box* box, Node* node, Value& value)
auto result = writeLocal(Value::InitForZero(ValueType::Float4), node);
const String triplanarTexture = String::Format(TEXT(
" {{\n"
" float3 worldPos = input.WorldPosition.xyz * ({1} * 0.001f);\n"
" float tiling = {1} * 0.001f;\n"
" float3 worldPos = (input.WorldPosition.xyz + GetLargeWorldsTileOffset(1.0f / tiling)) * tiling;\n"
" float3 normal = abs(input.TBN[2]);\n"
" normal = pow(normal, {2});\n"
" normal = normal / (normal.x + normal.y + normal.z);\n"
" normal = normalize(normal);\n"
" {3} += {0}.{4}(SamplerLinearWrap, worldPos.yz{5}) * normal.x;\n"
" {3} += {0}.{4}(SamplerLinearWrap, worldPos.xz{5}) * normal.y;\n"
" {3} += {0}.{4}(SamplerLinearWrap, worldPos.xy{5}) * normal.z;\n"

View File

@@ -171,6 +171,8 @@ cbuffer ViewData : register(b1)
float4 ViewInfo;
float4 ScreenSize;
float4 TemporalAAJitter;
float3 LargeWorldsChunkIndex;
float LargeWorldsChunkSize;
};
#endif
@@ -277,4 +279,14 @@ float2 Flipbook(float2 uv, float frame, float2 sizeXY, float2 flipXY = 0.0f)
return (uv + frameXY) / sizeXY;
}
#if USE_PER_VIEW_CONSTANTS
// Calculates the world-position offset to stabilize tiling (eg. via triplanar mapping) due to Large Worlds view origin offset.
float3 GetLargeWorldsTileOffset(float tileSize)
{
return LargeWorldsChunkIndex * fmod(LargeWorldsChunkSize, tileSize);
}
#endif
#endif