impostor system revived
This commit is contained in:
+11
-5
@@ -105,7 +105,8 @@ MeshWindow::MeshWindow(wiGUI* gui) : GUI(gui)
|
||||
MeshComponent* mesh = wiRenderer::GetScene().meshes.GetComponent(entity);
|
||||
if (mesh != nullptr)
|
||||
{
|
||||
wiRenderer::CreateImpostor(entity, GRAPHICSTHREAD_IMMEDIATE);
|
||||
Scene& scene = wiRenderer::GetScene();
|
||||
scene.impostors.Create(entity).swapInDistance = impostorDistanceSlider->GetValue();
|
||||
}
|
||||
});
|
||||
meshWindow->AddWidget(impostorCreateButton);
|
||||
@@ -115,10 +116,10 @@ MeshWindow::MeshWindow(wiGUI* gui) : GUI(gui)
|
||||
impostorDistanceSlider->SetSize(XMFLOAT2(100, 30));
|
||||
impostorDistanceSlider->SetPos(XMFLOAT2(x, y += step));
|
||||
impostorDistanceSlider->OnSlide([&](wiEventArgs args) {
|
||||
MeshComponent* mesh = wiRenderer::GetScene().meshes.GetComponent(entity);
|
||||
if (mesh != nullptr)
|
||||
ImpostorComponent* impostor = wiRenderer::GetScene().impostors.GetComponent(entity);
|
||||
if (impostor != nullptr)
|
||||
{
|
||||
mesh->impostorDistance = args.fValue;
|
||||
impostor->swapInDistance = args.fValue;
|
||||
}
|
||||
});
|
||||
meshWindow->AddWidget(impostorDistanceSlider);
|
||||
@@ -229,7 +230,12 @@ void MeshWindow::SetEntity(Entity entity)
|
||||
meshInfoLabel->SetText(ss.str());
|
||||
|
||||
doubleSidedCheckBox->SetCheck(mesh->IsDoubleSided());
|
||||
impostorDistanceSlider->SetValue(mesh->impostorDistance);
|
||||
|
||||
const ImpostorComponent* impostor = scene.impostors.GetComponent(entity);
|
||||
if (impostor != nullptr)
|
||||
{
|
||||
impostorDistanceSlider->SetValue(impostor->swapInDistance);
|
||||
}
|
||||
tessellationFactorSlider->SetValue(mesh->GetTessellationFactor());
|
||||
|
||||
SoftBodyPhysicsComponent* physicscomponent = wiRenderer::GetScene().softbodies.GetComponent(entity);
|
||||
|
||||
@@ -226,6 +226,8 @@ void wiEmittedParticle::Restart()
|
||||
//#define DEBUG_SORTING // slow but great for debug!!
|
||||
void wiEmittedParticle::UpdateRenderData(const TransformComponent& transform, const MaterialComponent& material, const MeshComponent* mesh, GRAPHICSTHREAD threadID)
|
||||
{
|
||||
center = transform.GetPosition();
|
||||
|
||||
CreateSelfBuffers();
|
||||
|
||||
GraphicsDevice* device = wiRenderer::GetDevice();
|
||||
|
||||
@@ -115,6 +115,9 @@ public:
|
||||
uint32_t GetMaxParticleCount() const { return MAX_PARTICLES; }
|
||||
uint32_t GetMemorySizeInBytes() const;
|
||||
|
||||
// Non-serialized attributes:
|
||||
XMFLOAT3 center;
|
||||
|
||||
inline bool IsDebug() const { return _flags & DEBUG; }
|
||||
inline bool IsPaused() const { return _flags & PAUSED; }
|
||||
inline bool IsSorted() const { return _flags & SORTING; }
|
||||
|
||||
+580
-546
File diff suppressed because it is too large
Load Diff
@@ -99,6 +99,7 @@ namespace wiRenderer
|
||||
void DrawLensFlares(GRAPHICSTHREAD threadID);
|
||||
void DrawDecals(const wiSceneSystem::CameraComponent& camera, GRAPHICSTHREAD threadID);
|
||||
void RefreshEnvProbes(GRAPHICSTHREAD threadID);
|
||||
void RefreshImpostors(GRAPHICSTHREAD threadID);
|
||||
void VoxelRadiance(GRAPHICSTHREAD threadID);
|
||||
void ComputeTiledLightCulling(bool deferred, GRAPHICSTHREAD threadID);
|
||||
void ResolveMSAADepthBuffer(wiGraphicsTypes::Texture2D* dst, wiGraphicsTypes::Texture2D* src, GRAPHICSTHREAD threadID);
|
||||
@@ -138,7 +139,6 @@ namespace wiRenderer
|
||||
void GenerateClouds(wiGraphicsTypes::Texture2D* dst, UINT refinementCount, float randomness, GRAPHICSTHREAD threadID);
|
||||
|
||||
void ManageDecalAtlas(GRAPHICSTHREAD threadID);
|
||||
void CreateImpostor(wiECS::Entity, GRAPHICSTHREAD threadID);
|
||||
|
||||
void PutWaterRipple(const std::string& image, const XMFLOAT3& pos);
|
||||
void ManageWaterRipples();
|
||||
|
||||
@@ -824,7 +824,9 @@ namespace wiSceneSystem
|
||||
|
||||
RunMaterialUpdateSystem(materials, dt);
|
||||
|
||||
RunObjectUpdateSystem(transforms, meshes, materials, objects, aabb_objects, bounds, waterPlane);
|
||||
RunImpostorUpdateSystem(impostors);
|
||||
|
||||
RunObjectUpdateSystem(transforms, meshes, materials, objects, aabb_objects, impostors, bounds, waterPlane);
|
||||
|
||||
RunCameraUpdateSystem(transforms, cameras);
|
||||
|
||||
@@ -847,6 +849,7 @@ namespace wiSceneSystem
|
||||
hierarchy.Clear();
|
||||
materials.Clear();
|
||||
meshes.Clear();
|
||||
impostors.Clear();
|
||||
objects.Clear();
|
||||
aabb_objects.Clear();
|
||||
rigidbodies.Clear();
|
||||
@@ -874,6 +877,7 @@ namespace wiSceneSystem
|
||||
hierarchy.Merge(other.hierarchy);
|
||||
materials.Merge(other.materials);
|
||||
meshes.Merge(other.meshes);
|
||||
impostors.Merge(other.impostors);
|
||||
objects.Merge(other.objects);
|
||||
aabb_objects.Merge(other.aabb_objects);
|
||||
rigidbodies.Merge(other.rigidbodies);
|
||||
@@ -906,6 +910,7 @@ namespace wiSceneSystem
|
||||
entityCount = max(entityCount, hierarchy.GetCount());
|
||||
entityCount = max(entityCount, materials.GetCount());
|
||||
entityCount = max(entityCount, meshes.GetCount());
|
||||
entityCount = max(entityCount, impostors.GetCount());
|
||||
entityCount = max(entityCount, objects.GetCount());
|
||||
entityCount = max(entityCount, aabb_objects.GetCount());
|
||||
entityCount = max(entityCount, rigidbodies.GetCount());
|
||||
@@ -934,6 +939,7 @@ namespace wiSceneSystem
|
||||
hierarchy.Remove_KeepSorted(entity);
|
||||
materials.Remove(entity);
|
||||
meshes.Remove(entity);
|
||||
impostors.Remove(entity);
|
||||
objects.Remove(entity);
|
||||
aabb_objects.Remove(entity);
|
||||
rigidbodies.Remove(entity);
|
||||
@@ -1500,12 +1506,22 @@ namespace wiSceneSystem
|
||||
|
||||
}
|
||||
}
|
||||
void RunImpostorUpdateSystem(ComponentManager<ImpostorComponent>& impostors)
|
||||
{
|
||||
for (size_t i = 0; i < impostors.GetCount(); ++i)
|
||||
{
|
||||
ImpostorComponent& impostor = impostors[i];
|
||||
impostor.aabb = AABB();
|
||||
impostor.instanceMatrices.clear();
|
||||
}
|
||||
}
|
||||
void RunObjectUpdateSystem(
|
||||
const ComponentManager<TransformComponent>& transforms,
|
||||
const ComponentManager<MeshComponent>& meshes,
|
||||
const ComponentManager<MaterialComponent>& materials,
|
||||
ComponentManager<ObjectComponent>& objects,
|
||||
ComponentManager<AABB>& aabb_objects,
|
||||
ComponentManager<ImpostorComponent>& impostors,
|
||||
AABB& sceneBounds,
|
||||
XMFLOAT4& waterPlane
|
||||
)
|
||||
@@ -1523,6 +1539,7 @@ namespace wiSceneSystem
|
||||
object.rendertypeMask = 0;
|
||||
object.SetDynamic(false);
|
||||
object.SetCastShadow(false);
|
||||
object.SetImpostorPlacement(false);
|
||||
|
||||
if (object.meshID != INVALID_ENTITY)
|
||||
{
|
||||
@@ -1535,7 +1552,12 @@ namespace wiSceneSystem
|
||||
aabb = mesh->aabb.get(transform->world);
|
||||
sceneBounds = AABB::Merge(sceneBounds, aabb);
|
||||
|
||||
object.position = transform->GetPosition();
|
||||
// This is instance bounding box matrix:
|
||||
XMFLOAT4X4 meshMatrix;
|
||||
XMStoreFloat4x4(&meshMatrix, mesh->aabb.getAsBoxMatrix() * XMLoadFloat4x4(&transform->world));
|
||||
|
||||
// We need sometimes the center of the instance bounding box, not the transform position (which can be outside the bounding box)
|
||||
object.center = *((XMFLOAT3*)&meshMatrix._41);
|
||||
|
||||
if (mesh->IsSkinned() || mesh->IsDynamic())
|
||||
{
|
||||
@@ -1568,6 +1590,18 @@ namespace wiSceneSystem
|
||||
object.SetCastShadow(material->IsCastingShadow());
|
||||
}
|
||||
}
|
||||
|
||||
ImpostorComponent* impostor = impostors.GetComponent(object.meshID);
|
||||
if (impostor != nullptr)
|
||||
{
|
||||
object.SetImpostorPlacement(true);
|
||||
object.impostorSwapDistance = impostor->swapInDistance;
|
||||
object.impostorFadeThresholdRadius = aabb.getRadius();
|
||||
|
||||
impostor->aabb = AABB::Merge(impostor->aabb, aabb);
|
||||
impostor->fadeThresholdRadius = object.impostorFadeThresholdRadius;
|
||||
impostor->instanceMatrices.push_back(meshMatrix);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -160,9 +160,7 @@ namespace wiSceneSystem
|
||||
|
||||
inline float GetOpacity() const { return baseColor.w; }
|
||||
|
||||
|
||||
inline void SetDirty() { _flags |= DIRTY; }
|
||||
inline void SetClean() { _flags &= ~DIRTY; }
|
||||
inline void SetDirty(bool value = true) { if (value) { _flags |= DIRTY; } else { _flags &= ~DIRTY; } }
|
||||
inline bool IsDirty() const { return _flags & DIRTY; }
|
||||
|
||||
inline void SetCastShadow(bool value) { if (value) { _flags |= CAST_SHADOW; } else { _flags &= ~CAST_SHADOW; } }
|
||||
@@ -219,7 +217,6 @@ namespace wiSceneSystem
|
||||
std::vector<MeshSubset> subsets;
|
||||
|
||||
float tessellationFactor = 0.0f;
|
||||
float impostorDistance = 100.0f;
|
||||
wiECS::Entity armatureID = wiECS::INVALID_ENTITY;
|
||||
|
||||
// Non-serialized attributes:
|
||||
@@ -232,7 +229,6 @@ namespace wiSceneSystem
|
||||
std::unique_ptr<wiGraphicsTypes::GPUBuffer> vertexBuffer_ATL;
|
||||
std::unique_ptr<wiGraphicsTypes::GPUBuffer> streamoutBuffer_POS;
|
||||
std::unique_ptr<wiGraphicsTypes::GPUBuffer> streamoutBuffer_PRE;
|
||||
wiRenderTarget impostorTarget;
|
||||
|
||||
|
||||
inline void SetRenderable(bool value) { if (value) { _flags |= RENDERABLE; } else { _flags &= ~RENDERABLE; } }
|
||||
@@ -243,7 +239,6 @@ namespace wiSceneSystem
|
||||
inline bool IsDoubleSided() const { return _flags & DOUBLE_SIDED; }
|
||||
inline bool IsDynamic() const { return _flags & DYNAMIC; }
|
||||
|
||||
bool HasImpostor() const { return impostorTarget.IsInitialized(); }
|
||||
inline float GetTessellationFactor() const { return tessellationFactor; }
|
||||
inline wiGraphicsTypes::INDEXBUFFER_FORMAT GetIndexFormat() const { return vertex_positions.size() > 65535 ? wiGraphicsTypes::INDEXFORMAT_32BIT : wiGraphicsTypes::INDEXFORMAT_16BIT; }
|
||||
inline bool IsSkinned() const { return armatureID != wiECS::INVALID_ENTITY; }
|
||||
@@ -369,6 +364,29 @@ namespace wiSceneSystem
|
||||
|
||||
};
|
||||
|
||||
struct ImpostorComponent
|
||||
{
|
||||
enum FLAGS
|
||||
{
|
||||
EMPTY = 0,
|
||||
DIRTY = 1 << 0,
|
||||
};
|
||||
uint32_t _flags = DIRTY;
|
||||
|
||||
float swapInDistance = 100.0f;
|
||||
|
||||
// Non-serialized attributes:
|
||||
AABB aabb;
|
||||
wiRenderTarget rendertarget; // todo: combine all impostors into atlas/texture2darray
|
||||
float fadeThresholdRadius;
|
||||
std::vector<XMFLOAT4X4> instanceMatrices;
|
||||
|
||||
inline void SetDirty(bool value = true) { if (value) { _flags |= DIRTY; } else { _flags &= ~DIRTY; } }
|
||||
inline bool IsDirty() const { return _flags & DIRTY; }
|
||||
|
||||
void Serialize(wiArchive& archive, uint32_t seed = 0);
|
||||
};
|
||||
|
||||
struct ObjectComponent
|
||||
{
|
||||
enum FLAGS
|
||||
@@ -377,6 +395,7 @@ namespace wiSceneSystem
|
||||
RENDERABLE = 1 << 0,
|
||||
CAST_SHADOW = 1 << 1,
|
||||
DYNAMIC = 1 << 2,
|
||||
IMPOSTOR_PLACEMENT = 1 << 3,
|
||||
};
|
||||
uint32_t _flags = RENDERABLE | CAST_SHADOW;
|
||||
|
||||
@@ -387,7 +406,9 @@ namespace wiSceneSystem
|
||||
|
||||
// Non-serialized attributes:
|
||||
|
||||
XMFLOAT3 position = XMFLOAT3(0, 0, 0);
|
||||
XMFLOAT3 center = XMFLOAT3(0, 0, 0);
|
||||
float impostorFadeThresholdRadius;
|
||||
float impostorSwapDistance;
|
||||
|
||||
// occlusion result history bitfield (32 bit->32 frame history)
|
||||
uint32_t occlusionHistory = ~0;
|
||||
@@ -406,10 +427,12 @@ namespace wiSceneSystem
|
||||
inline void SetRenderable(bool value) { if (value) { _flags |= RENDERABLE; } else { _flags &= ~RENDERABLE; } }
|
||||
inline void SetCastShadow(bool value) { if (value) { _flags |= CAST_SHADOW; } else { _flags &= ~CAST_SHADOW; } }
|
||||
inline void SetDynamic(bool value) { if (value) { _flags |= DYNAMIC; } else { _flags &= ~DYNAMIC; } }
|
||||
inline void SetImpostorPlacement(bool value) { if (value) { _flags |= IMPOSTOR_PLACEMENT; } else { _flags &= ~IMPOSTOR_PLACEMENT; } }
|
||||
|
||||
inline bool IsRenderable() const { return _flags & RENDERABLE; }
|
||||
inline bool IsCastingShadow() const { return _flags & CAST_SHADOW; }
|
||||
inline bool IsDynamic() const { return _flags & DYNAMIC; }
|
||||
inline bool IsImpostorPlacement() const { return _flags & IMPOSTOR_PLACEMENT; }
|
||||
|
||||
inline float GetTransparency() const { return 1 - color.w; }
|
||||
inline uint32_t GetRenderTypes() const { return rendertypeMask; }
|
||||
@@ -884,6 +907,7 @@ namespace wiSceneSystem
|
||||
wiECS::ComponentManager<HierarchyComponent> hierarchy;
|
||||
wiECS::ComponentManager<MaterialComponent> materials;
|
||||
wiECS::ComponentManager<MeshComponent> meshes;
|
||||
wiECS::ComponentManager<ImpostorComponent> impostors;
|
||||
wiECS::ComponentManager<ObjectComponent> objects;
|
||||
wiECS::ComponentManager<AABB> aabb_objects;
|
||||
wiECS::ComponentManager<RigidBodyPhysicsComponent> rigidbodies;
|
||||
@@ -1001,12 +1025,14 @@ namespace wiSceneSystem
|
||||
wiECS::ComponentManager<ArmatureComponent>& armatures
|
||||
);
|
||||
void RunMaterialUpdateSystem(wiECS::ComponentManager<MaterialComponent>& materials, float dt);
|
||||
void RunImpostorUpdateSystem(wiECS::ComponentManager<ImpostorComponent>& impostors);
|
||||
void RunObjectUpdateSystem(
|
||||
const wiECS::ComponentManager<TransformComponent>& transforms,
|
||||
const wiECS::ComponentManager<MeshComponent>& meshes,
|
||||
const wiECS::ComponentManager<MaterialComponent>& materials,
|
||||
wiECS::ComponentManager<ObjectComponent>& objects,
|
||||
wiECS::ComponentManager<AABB>& aabb_objects,
|
||||
wiECS::ComponentManager<ImpostorComponent>& impostors,
|
||||
AABB& sceneBounds,
|
||||
XMFLOAT4& waterPlane
|
||||
);
|
||||
|
||||
@@ -10,6 +10,7 @@ namespace wiSceneSystem
|
||||
struct HierarchyComponent;
|
||||
struct MaterialComponent;
|
||||
struct MeshComponent;
|
||||
struct ImpostorComponent;
|
||||
struct ObjectComponent;
|
||||
struct RigidBodyPhysicsComponent;
|
||||
struct SoftBodyPhysicsComponent;
|
||||
|
||||
@@ -173,7 +173,6 @@ namespace wiSceneSystem
|
||||
}
|
||||
|
||||
archive >> tessellationFactor;
|
||||
archive >> impostorDistance;
|
||||
SerializeEntity(archive, armatureID, seed);
|
||||
|
||||
CreateRenderData();
|
||||
@@ -199,11 +198,25 @@ namespace wiSceneSystem
|
||||
}
|
||||
|
||||
archive << tessellationFactor;
|
||||
archive << impostorDistance;
|
||||
SerializeEntity(archive, armatureID, seed);
|
||||
|
||||
}
|
||||
}
|
||||
void ImpostorComponent::Serialize(wiArchive& archive, uint32_t seed)
|
||||
{
|
||||
if (archive.IsReadMode())
|
||||
{
|
||||
archive >> _flags;
|
||||
archive >> swapInDistance;
|
||||
|
||||
SetDirty();
|
||||
}
|
||||
else
|
||||
{
|
||||
archive << _flags;
|
||||
archive << swapInDistance;
|
||||
}
|
||||
}
|
||||
void ObjectComponent::Serialize(wiArchive& archive, uint32_t seed)
|
||||
{
|
||||
if (archive.IsReadMode())
|
||||
@@ -512,6 +525,7 @@ namespace wiSceneSystem
|
||||
hierarchy.Serialize(archive, seed);
|
||||
materials.Serialize(archive, seed);
|
||||
meshes.Serialize(archive, seed);
|
||||
impostors.Serialize(archive, seed);
|
||||
objects.Serialize(archive, seed);
|
||||
aabb_objects.Serialize(archive, seed);
|
||||
rigidbodies.Serialize(archive, seed);
|
||||
@@ -602,6 +616,15 @@ namespace wiSceneSystem
|
||||
component.Serialize(archive, propagateSeedDeep ? seed : 0);
|
||||
}
|
||||
}
|
||||
{
|
||||
bool component_exists;
|
||||
archive >> component_exists;
|
||||
if (component_exists)
|
||||
{
|
||||
auto& component = impostors.Create(entity);
|
||||
component.Serialize(archive, propagateSeedDeep ? seed : 0);
|
||||
}
|
||||
}
|
||||
{
|
||||
bool component_exists;
|
||||
archive >> component_exists;
|
||||
@@ -843,6 +866,18 @@ namespace wiSceneSystem
|
||||
archive << false;
|
||||
}
|
||||
}
|
||||
{
|
||||
auto component = impostors.GetComponent(entity);
|
||||
if (component != nullptr)
|
||||
{
|
||||
archive << true;
|
||||
component->Serialize(archive, seed);
|
||||
}
|
||||
else
|
||||
{
|
||||
archive << false;
|
||||
}
|
||||
}
|
||||
{
|
||||
auto component = objects.GetComponent(entity);
|
||||
if (component != nullptr)
|
||||
|
||||
Reference in New Issue
Block a user