Fix lightmap uvs density view to handle scale in lightmap and outline non-static objects

#2080
This commit is contained in:
Wojtek Figat
2024-09-09 05:59:17 +02:00
parent fc9aa5c184
commit 545e59aba5
9 changed files with 42 additions and 76 deletions

View File

@@ -15,7 +15,6 @@
#include "Engine/Renderer/DrawCall.h"
#include "Engine/Foliage/Foliage.h"
#include "Engine/ShadowsOfMordor/Builder.Config.h"
#include "Engine/Level/Level.h"
#include "Engine/Level/Scene/Scene.h"
#include "Engine/Level/Actors/StaticModel.h"
@@ -70,40 +69,6 @@ DrawPass LightmapUVsDensityMaterialShader::GetDrawModes() const
return DrawPass::GBuffer;
}
namespace
{
Actor* FindActorByDrawCall(Actor* actor, const DrawCall& drawCall, float& scaleInLightmap)
{
// TODO: large-worlds
const auto asStaticModel = ScriptingObject::Cast<StaticModel>(actor);
if (asStaticModel && asStaticModel->GetPerInstanceRandom() == drawCall.PerInstanceRandom && asStaticModel->GetPosition() == drawCall.ObjectPosition)
{
scaleInLightmap = asStaticModel->GetScaleInLightmap();
return asStaticModel;
}
const auto asFoliage = ScriptingObject::Cast<Foliage>(actor);
if (asFoliage)
{
for (auto i = asFoliage->Instances.Begin(); i.IsNotEnd(); ++i)
{
auto& instance = *i;
if (instance.Random == drawCall.PerInstanceRandom && instance.Transform.Translation == drawCall.ObjectPosition)
{
scaleInLightmap = asFoliage->FoliageTypes[instance.Type].ScaleInLightmap;
return asFoliage;
}
}
}
for (Actor* child : actor->Children)
{
const auto other = FindActorByDrawCall(child, drawCall, scaleInLightmap);
if (other)
return other;
}
return nullptr;
}
}
void LightmapUVsDensityMaterialShader::Bind(BindParameters& params)
{
// Prepare
@@ -121,33 +86,6 @@ void LightmapUVsDensityMaterialShader::Bind(BindParameters& params)
_ps->Init(psDesc);
}
// Find the static model that produced this draw call
const Actor* drawCallActor = nullptr;
float scaleInLightmap = 1.0f;
if (params.RenderContext.Task)
{
// Skip this lookup as it's too slow
/*if (params.RenderContext.Task->ActorsSource & ActorsSources::CustomActors)
{
for (auto actor : params.RenderContext.Task->CustomActors)
{
drawCallActor = FindActorByDrawCall(actor, drawCall, scaleInLightmap);
if (drawCallActor)
break;
}
}
if (!drawCallActor && params.RenderContext.Task->ActorsSource & ActorsSources::Scenes)
{
for (auto& scene : Level::Scenes)
{
drawCallActor = FindActorByDrawCall(scene, drawCall, scaleInLightmap);
if (drawCallActor)
break;
}
}*/
}
// Bind constants
if (cb && cb->GetSize())
{
@@ -166,19 +104,15 @@ void LightmapUVsDensityMaterialShader::Bind(BindParameters& params)
data.LightmapSize = 1024.0f;
data.LightmapArea = drawCall.Surface.LightmapUVsArea;
const ModelLOD* drawCallModelLod;
if (GBufferPass::IndexBufferToModelLOD.TryGet(drawCall.Geometry.IndexBuffer, drawCallModelLod))
float scaleInLightmap = drawCall.Surface.LODDitherFactor; // Reuse field
if (scaleInLightmap < 0.0f)
data.LightmapSize = -1.0f; // Not using lightmap
else if (GBufferPass::IndexBufferToModelLOD.TryGet(drawCall.Geometry.IndexBuffer, drawCallModelLod))
{
// Calculate current lightmap slot size for the object (matches the ShadowsOfMordor calculations when baking the lighting)
float globalObjectsScale = 1.0f;
int32 atlasSize = 1024;
int32 chartsPadding = 3;
const Scene* drawCallScene = drawCallActor ? drawCallActor->GetScene() : (Level::Scenes.Count() != 0 ? Level::Scenes[0] : nullptr);
if (drawCallScene)
{
globalObjectsScale = drawCallScene->Info.LightmapSettings.GlobalObjectsScale;
atlasSize = (int32)drawCallScene->Info.LightmapSettings.AtlasSize;
chartsPadding = drawCallScene->Info.LightmapSettings.ChartsPadding;
}
BoundingBox box = drawCallModelLod->GetBox(drawCall.World);
Float3 size = box.GetSize();
float dimensionsCoeff = size.AverageArithmetic();