mirror of
https://github.com/barkeser2002/flower.git
synced 2026-09-25 14:56:14 +03:00
163 lines
4.5 KiB
C++
163 lines
4.5 KiB
C++
#include "render_scene.h"
|
|
#include <scene/component/static_mesh.h>
|
|
#include <scene/scene.h>
|
|
|
|
namespace engine
|
|
{
|
|
RenderScene::RenderScene(VulkanContext* context, SceneManager* sceneManager)
|
|
: m_context(context), m_sceneManager(sceneManager)
|
|
{
|
|
|
|
}
|
|
|
|
RenderScene::~RenderScene()
|
|
{
|
|
|
|
}
|
|
|
|
void RenderScene::tick(const RuntimeModuleTickData& tickData, VkCommandBuffer cmd)
|
|
{
|
|
m_postprocessVolumeInfo = {};
|
|
m_mmdCamera = {};
|
|
|
|
auto activeScene = m_sceneManager->getActiveScene();
|
|
|
|
renderObjectCollect(tickData, activeScene.get(), cmd);
|
|
|
|
tlasPrepare(tickData, activeScene.get(), cmd);
|
|
|
|
lightCollect(activeScene.get(), cmd);
|
|
|
|
|
|
activeScene->loopComponents<PostprocessVolumeComponent>([&](std::shared_ptr<PostprocessVolumeComponent> comp) -> bool
|
|
{
|
|
m_postprocessVolumeInfo = comp->getSetting();
|
|
return true;
|
|
});
|
|
|
|
activeScene->loopComponents<MMDCameraComponent>(
|
|
[&](std::shared_ptr<MMDCameraComponent> comp) -> bool
|
|
{
|
|
m_mmdCamera = comp;
|
|
return true;
|
|
});
|
|
|
|
|
|
}
|
|
|
|
bool RenderScene::shouldRenderSDSM() const
|
|
{
|
|
bool bExistMeshNeedRender = isStaticMeshExist(); // || isTerrainExist();
|
|
return isSkyExist() && (bExistMeshNeedRender);
|
|
}
|
|
|
|
|
|
bool RenderScene::isASValid() const
|
|
{
|
|
return !m_cacheASInstances.empty() && m_tlas.isInit();
|
|
}
|
|
|
|
void RenderScene::fillMMDCameraInfo(GPUPerFrameData& view, float width, float height)
|
|
{
|
|
auto frame = m_mmdCamera.lock()->getCameraPerframe(width, height, view.camInfo.z, view.camInfo.w);
|
|
|
|
view.camWorldPos = { frame.worldPos, 1.0f };
|
|
view.camInfo.x = frame.fovy;
|
|
|
|
view.camView = frame.viewMat;
|
|
view.camProjNoJitter = frame.projMat;
|
|
|
|
view.camForward = { frame.front, 0.0f };
|
|
|
|
auto frustum = Frustum::build(view.camProjNoJitter * view.camView);
|
|
view.frustumPlanes[0] = frustum.planes[0];
|
|
view.frustumPlanes[1] = frustum.planes[1];
|
|
view.frustumPlanes[2] = frustum.planes[2];
|
|
view.frustumPlanes[3] = frustum.planes[3];
|
|
view.frustumPlanes[4] = frustum.planes[4];
|
|
view.frustumPlanes[5] = frustum.planes[5];
|
|
}
|
|
|
|
// All dynamic, no cache yet, I don't want to make the logic too complex, keep simple make life easy.
|
|
void RenderScene::renderObjectCollect(const RuntimeModuleTickData& tickData, Scene* scene, VkCommandBuffer cmd)
|
|
{
|
|
// Clear AS instance.
|
|
m_cacheASInstances.clear();
|
|
m_staticmeshObjects.clear();
|
|
m_collectPMXes.clear();
|
|
|
|
// Collect all terrain object.
|
|
m_terrainComponents.clear();
|
|
scene->loopComponents<TerrainComponent>([&](std::shared_ptr<TerrainComponent> comp) -> bool
|
|
{
|
|
m_terrainComponents.push_back(comp);
|
|
return false;
|
|
});
|
|
|
|
// Collect all pmx mesh object.
|
|
scene->loopComponents<PMXComponent>([&](std::shared_ptr<PMXComponent> comp) -> bool
|
|
{
|
|
comp->onRenderTick(tickData, cmd, m_staticmeshObjects, m_cacheASInstances);
|
|
m_collectPMXes.push_back(comp);
|
|
return false;
|
|
});
|
|
|
|
// Static mesh.
|
|
scene->loopComponents<StaticMeshComponent>([&](std::shared_ptr<StaticMeshComponent> comp) -> bool
|
|
{
|
|
comp->renderObjectCollect(m_staticmeshObjects, m_cacheASInstances);
|
|
|
|
// We need to loop all static mesh component.
|
|
return false;
|
|
});
|
|
|
|
// Now update all static mesh info.
|
|
if (!m_staticmeshObjects.empty())
|
|
{
|
|
m_staticmeshObjectsGPU = getContext()->getBufferParameters().getStaticStorage("StaticMeshObjects", sizeof(m_staticmeshObjects[0]) * m_staticmeshObjects.size());
|
|
m_staticmeshObjectsGPU->updateDataPtr((void*)m_staticmeshObjects.data());
|
|
}
|
|
}
|
|
|
|
void RenderScene::lightCollect(Scene* scene, VkCommandBuffer cmd)
|
|
{
|
|
// Sky component.
|
|
scene->loopComponents<SkyComponent>([&](std::shared_ptr<SkyComponent> comp) -> bool
|
|
{
|
|
// Cache weak pointer. when move to multi-thread rendering, will require cache owner pointer or copy resource. but current just use weak ptr is enough.
|
|
m_sky = comp;
|
|
|
|
m_skyGPU.intensity = comp->getIntensity();
|
|
m_skyGPU.color = comp->getColor();
|
|
m_skyGPU.direction = comp->getDirection();
|
|
|
|
m_skyGPU.cacsadeConfig = comp->getCacsadeConfig();
|
|
m_skyGPU.atmosphereConfig = comp->getAtmosphereConfig();
|
|
m_skyGPU.rayTraceShadow = comp->isRayTraceShadow() ? 1 : 0;
|
|
|
|
// Current we only support one sky light, so pre-return when first sky light collect finish.
|
|
return true;
|
|
});
|
|
}
|
|
|
|
|
|
void RenderScene::tlasPrepare(const RuntimeModuleTickData& tickData, Scene* scene, VkCommandBuffer cmd)
|
|
{
|
|
// When instance is empty, destroy tlas and pre-return.
|
|
if (m_cacheASInstances.empty())
|
|
{
|
|
m_tlas.destroy();
|
|
return;
|
|
}
|
|
|
|
// Sometimes need rebuild. clear here.
|
|
if (false)
|
|
{
|
|
|
|
m_tlas.destroy();
|
|
}
|
|
|
|
// Update or build TLAS.
|
|
m_tlas.buildTlas(cmd, m_cacheASInstances, m_tlas.isInit());
|
|
}
|
|
} |