Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,4 @@
/active_project
/test/assets/assets.db
/test/products/
_codeql_detected_source_root
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
//
// Created by Copilot on 2026/2/16.
//

#pragma once

#include <framework/world/Component.h>
#include <render/hlod/HLODTree.h>
#include <render/hlod/HLODRenderer.h>

namespace sky {

class HLODComponent : public ComponentBase {
public:
HLODComponent() = default;
~HLODComponent() override;

COMPONENT_RUNTIME_INFO(HLODComponent)

static void Reflect(SerializationContext *context);

void Tick(float time) override;

void SaveJson(JsonOutputArchive &ar) const override;
void LoadJson(JsonInputArchive &ar) override;

void SetHLODTree(const HLODTreePtr &tree);
HLODRenderer *GetRenderer() const { return renderer; }

void OnAttachToWorld() override;
void OnDetachFromWorld() override;
private:
void ShutDown();
void BuildRenderer();

HLODTreePtr hlodTree;
HLODRenderer *renderer = nullptr;
};

} // namespace sky
6 changes: 6 additions & 0 deletions runtime/render/adaptor/src/RenderModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,14 @@
#include <render/adaptor/components/StaticMeshComponent.h>
#include <render/adaptor/components/SkeletonMeshComponent.h>
#include <render/adaptor/components/SkyBoxComponent.h>
#include <render/adaptor/components/HLODComponent.h>
#include <render/adaptor/Reflection.h>
#include <render/adaptor/assets/TechniqueAsset.h>
#include <render/RenderTechniqueLibrary.h>

#include <render/light/LightFeature.h>
#include <render/mesh/MeshFeature.h>
#include <render/hlod/HLODFeature.h>
#include <render/text/TextFeature.h>
#include <imgui/ImGuiFeature.h>

Expand All @@ -43,13 +45,15 @@ namespace sky {
CameraComponent::Reflect(context);
SkeletonMeshComponent::Reflect(context);
SkyBoxComponent::Reflect(context);
HLODComponent::Reflect(context);

static std::string GROUP = "Render";
ComponentFactory::Get()->RegisterComponent<MainDirectLightComponent>(GROUP);
ComponentFactory::Get()->RegisterComponent<StaticMeshComponent>(GROUP);
ComponentFactory::Get()->RegisterComponent<SkeletonMeshComponent>(GROUP);
ComponentFactory::Get()->RegisterComponent<CameraComponent>(GROUP);
ComponentFactory::Get()->RegisterComponent<SkyBoxComponent>(GROUP);
ComponentFactory::Get()->RegisterComponent<HLODComponent>(GROUP);
}

void RenderModule::ProcessArgs(const StartArguments &args)
Expand Down Expand Up @@ -121,6 +125,7 @@ namespace sky {
void RenderModule::InitFeatures() // NOLINT
{
MeshFeature::Get()->Init();
HLODFeature::Get()->Init();
ImGuiFeature::Get()->Init();
TextFeature::Get()->Init();
LightFeature::Get()->Init();
Expand Down Expand Up @@ -149,6 +154,7 @@ namespace sky {

RenderTechniqueLibrary::Destroy();
MeshFeature::Destroy();
HLODFeature::Destroy();
ImGuiFeature::Destroy();
TextFeature::Destroy();

Expand Down
94 changes: 94 additions & 0 deletions runtime/render/adaptor/src/components/HLODComponent.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
//
// Created by Copilot on 2026/2/16.
//

#include <render/adaptor/components/HLODComponent.h>

#include <framework/serialization/JsonArchive.h>
#include <framework/world/Actor.h>
#include <framework/world/TransformComponent.h>

#include <render/adaptor/Util.h>
#include <render/hlod/HLODFeatureProcessor.h>

namespace sky {

HLODComponent::~HLODComponent()
{
ShutDown();
}

void HLODComponent::Reflect(SerializationContext *context)
{
context->Register<HLODComponent>("HLODComponent");
}

void HLODComponent::SaveJson(JsonOutputArchive &ar) const
{
ar.StartObject();
ar.EndObject();
}

void HLODComponent::LoadJson(JsonInputArchive &ar)
{
}

void HLODComponent::SetHLODTree(const HLODTreePtr &tree)
{
hlodTree = tree;
if (renderer != nullptr) {
renderer->SetHLODTree(hlodTree);
}
}

void HLODComponent::BuildRenderer()
{
auto *fp = GetFeatureProcessor<HLODFeatureProcessor>(actor);

if (renderer != nullptr) {
fp->RemoveHLODRenderer(renderer);
}

renderer = fp->CreateHLODRenderer();
if (hlodTree) {
renderer->SetHLODTree(hlodTree);
}
}

void HLODComponent::ShutDown()
{
if (renderer != nullptr) {
GetFeatureProcessor<HLODFeatureProcessor>(actor)->RemoveHLODRenderer(renderer);
renderer = nullptr;
}
}

void HLODComponent::Tick(float time)
{
if (renderer == nullptr) {
BuildRenderer();
}

if (renderer != nullptr) {
auto *ts = actor->GetComponent<TransformComponent>();
renderer->UpdateTransform(ts->GetWorldMatrix());

auto *renderScene = GetRenderSceneFromActor(actor);
auto *sceneView = renderScene->GetSceneView(Name("MainCamera"));
if (sceneView != nullptr) {
const auto &col = sceneView->GetWorld()[3];
renderer->UpdateLODSelection(Vector3{col.x, col.y, col.z});
}
}
}

void HLODComponent::OnAttachToWorld()
{
}

void HLODComponent::OnDetachFromWorld()
{
ShutDown();
}

} // namespace sky
19 changes: 19 additions & 0 deletions runtime/render/core/include/render/hlod/HLODFeature.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//
// Created by Copilot on 2026/2/16.
//

#pragma once

#include <core/environment/Singleton.h>

namespace sky {

class HLODFeature : public Singleton<HLODFeature> {
public:
HLODFeature() = default;
~HLODFeature() override = default;

void Init();
};

} // namespace sky
29 changes: 29 additions & 0 deletions runtime/render/core/include/render/hlod/HLODFeatureProcessor.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
//
// Created by Copilot on 2026/2/16.
//

#pragma once

#include <render/FeatureProcessor.h>
#include <render/hlod/HLODRenderer.h>
#include <list>
#include <memory>

namespace sky {

class HLODFeatureProcessor : public IFeatureProcessor {
public:
explicit HLODFeatureProcessor(RenderScene *scene) : IFeatureProcessor(scene) {}
~HLODFeatureProcessor() override = default;

void Tick(float time) override;
void Render(rdg::RenderGraph &rdg) override;

HLODRenderer *CreateHLODRenderer();
void RemoveHLODRenderer(HLODRenderer *renderer);

private:
std::list<std::unique_ptr<HLODRenderer>> renderers;
};

} // namespace sky
28 changes: 28 additions & 0 deletions runtime/render/core/include/render/hlod/HLODNode.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
//
// Created by Copilot on 2026/2/16.
//

#pragma once

#include <cstdint>
#include <vector>
#include <core/shapes/AABB.h>
#include <core/template/ReferenceObject.h>
#include <render/resource/Mesh.h>

namespace sky {

struct HLODNode {
uint32_t lodLevel = 0;
float switchInDistance = 0.f;
float switchOutDistance = 0.f;

AABB worldBound;

RDMeshPtr mesh;

uint32_t parentIndex = ~0U;
std::vector<uint32_t> childIndices;
};

} // namespace sky
41 changes: 41 additions & 0 deletions runtime/render/core/include/render/hlod/HLODRenderer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
//
// Created by Copilot on 2026/2/16.
//

#pragma once

#include <render/hlod/HLODTree.h>
#include <render/RenderPrimitive.h>
#include <core/math/Matrix4.h>
#include <memory>

namespace sky {
class RenderScene;

class HLODRenderer {
public:
HLODRenderer() = default;
~HLODRenderer();

void AttachScene(RenderScene *scn);
void SetHLODTree(const HLODTreePtr &tree);

void UpdateTransform(const Matrix4 &matrix);
void UpdateLODSelection(const Vector3 &cameraPos);

void Tick();

private:
void RebuildPrimitives(const std::vector<uint32_t> &visibleNodes);
void ClearPrimitives();

RenderScene *scene = nullptr;

HLODTreePtr hlodTree;
Matrix4 worldMatrix;

std::vector<uint32_t> activeNodes;
std::vector<std::unique_ptr<RenderMaterialPrimitive>> primitives;
};

} // namespace sky
32 changes: 32 additions & 0 deletions runtime/render/core/include/render/hlod/HLODTree.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
//
// Created by Copilot on 2026/2/16.
//

#pragma once

#include <vector>
#include <core/math/Vector3.h>
#include <render/hlod/HLODNode.h>

namespace sky {

class HLODTree : public RefObject {
public:
HLODTree() = default;
~HLODTree() override = default;

uint32_t AddNode(const HLODNode &node);
const HLODNode &GetNode(uint32_t index) const;
uint32_t GetNodeCount() const { return static_cast<uint32_t>(nodes.size()); }

void SelectLODs(const Vector3 &cameraPos, std::vector<uint32_t> &visibleNodes) const;

private:
void SelectLODRecursive(uint32_t nodeIndex, const Vector3 &cameraPos, std::vector<uint32_t> &visibleNodes) const;
float ComputeDistanceSq(const AABB &bound, const Vector3 &point) const;

std::vector<HLODNode> nodes;
};
using HLODTreePtr = CounterPtr<HLODTree>;

} // namespace sky
16 changes: 16 additions & 0 deletions runtime/render/core/src/hlod/HLODFeature.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
//
// Created by Copilot on 2026/2/16.
//

#include <render/hlod/HLODFeature.h>
#include <render/hlod/HLODFeatureProcessor.h>
#include <render/Renderer.h>

namespace sky {

void HLODFeature::Init()
{
Renderer::Get()->RegisterRenderFeature<HLODFeatureProcessor>();
}

} // namespace sky
34 changes: 34 additions & 0 deletions runtime/render/core/src/hlod/HLODFeatureProcessor.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
//
// Created by Copilot on 2026/2/16.
//

#include <render/hlod/HLODFeatureProcessor.h>

namespace sky {

void HLODFeatureProcessor::Tick(float time)
{
for (auto &renderer : renderers) {
renderer->Tick();
}
}

void HLODFeatureProcessor::Render(rdg::RenderGraph &rdg)
{
}

HLODRenderer *HLODFeatureProcessor::CreateHLODRenderer()
{
auto *renderer = new HLODRenderer();
renderer->AttachScene(scene);
return renderers.emplace_back(renderer).get();
}

void HLODFeatureProcessor::RemoveHLODRenderer(HLODRenderer *renderer)
{
renderers.remove_if([renderer](const auto &val) {
return renderer == val.get();
});
}

} // namespace sky
Loading