Formalize camera post-process descriptors
This commit is contained in:
@@ -4,6 +4,7 @@
|
||||
#include "Resources/Material/Material.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cctype>
|
||||
#include <sstream>
|
||||
|
||||
namespace XCEngine {
|
||||
@@ -56,49 +57,118 @@ bool TryParseVector4(const std::string& value, Math::Vector4& outValue) {
|
||||
return !stream.fail();
|
||||
}
|
||||
|
||||
Rendering::CameraPostProcessStack BuildColorScalePostProcessStack(
|
||||
const std::vector<Math::Vector4>& values) {
|
||||
Rendering::CameraPostProcessStack passes;
|
||||
passes.reserve(values.size());
|
||||
for (const Math::Vector4& value : values) {
|
||||
passes.push_back(Rendering::CameraPostProcessPassDesc::MakeColorScale(value));
|
||||
}
|
||||
return passes;
|
||||
}
|
||||
|
||||
size_t FindFirstColorScalePassIndex(const Rendering::CameraPostProcessStack& passes) {
|
||||
for (size_t index = 0; index < passes.size(); ++index) {
|
||||
if (passes[index].type == Rendering::CameraPostProcessPassType::ColorScale) {
|
||||
return index;
|
||||
}
|
||||
}
|
||||
|
||||
return passes.size();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void CameraComponent::SetPostProcessPasses(const Rendering::CameraPostProcessStack& values) {
|
||||
m_postProcessPasses = values;
|
||||
for (const Rendering::CameraPostProcessPassDesc& pass : m_postProcessPasses) {
|
||||
if (pass.type == Rendering::CameraPostProcessPassType::ColorScale) {
|
||||
m_colorScalePostProcessDefaultScale = pass.colorScale.scale;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CameraComponent::AddPostProcessPass(const Rendering::CameraPostProcessPassDesc& value) {
|
||||
if (!value.IsValid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (value.type == Rendering::CameraPostProcessPassType::ColorScale &&
|
||||
FindFirstColorScalePassIndex(m_postProcessPasses) == m_postProcessPasses.size()) {
|
||||
m_colorScalePostProcessDefaultScale = value.colorScale.scale;
|
||||
}
|
||||
|
||||
m_postProcessPasses.push_back(value);
|
||||
}
|
||||
|
||||
bool CameraComponent::IsColorScalePostProcessEnabled() const {
|
||||
return !m_colorScalePostProcessPasses.empty();
|
||||
return FindFirstColorScalePassIndex(m_postProcessPasses) != m_postProcessPasses.size();
|
||||
}
|
||||
|
||||
void CameraComponent::SetColorScalePostProcessEnabled(bool value) {
|
||||
if (value) {
|
||||
if (m_colorScalePostProcessPasses.empty()) {
|
||||
m_colorScalePostProcessPasses.push_back(m_colorScalePostProcessDefaultScale);
|
||||
if (!IsColorScalePostProcessEnabled()) {
|
||||
m_postProcessPasses.push_back(
|
||||
Rendering::CameraPostProcessPassDesc::MakeColorScale(
|
||||
m_colorScalePostProcessDefaultScale));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
m_colorScalePostProcessPasses.clear();
|
||||
ClearColorScalePostProcessPasses();
|
||||
}
|
||||
|
||||
const Math::Vector4& CameraComponent::GetColorScalePostProcessScale() const {
|
||||
return m_colorScalePostProcessPasses.empty()
|
||||
const size_t firstColorScalePassIndex = FindFirstColorScalePassIndex(m_postProcessPasses);
|
||||
return firstColorScalePassIndex == m_postProcessPasses.size()
|
||||
? m_colorScalePostProcessDefaultScale
|
||||
: m_colorScalePostProcessPasses.front();
|
||||
: m_postProcessPasses[firstColorScalePassIndex].colorScale.scale;
|
||||
}
|
||||
|
||||
void CameraComponent::SetColorScalePostProcessScale(const Math::Vector4& value) {
|
||||
m_colorScalePostProcessDefaultScale = value;
|
||||
if (!m_colorScalePostProcessPasses.empty()) {
|
||||
m_colorScalePostProcessPasses.front() = value;
|
||||
const size_t firstColorScalePassIndex = FindFirstColorScalePassIndex(m_postProcessPasses);
|
||||
if (firstColorScalePassIndex != m_postProcessPasses.size()) {
|
||||
m_postProcessPasses[firstColorScalePassIndex].colorScale.scale = value;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<Math::Vector4> CameraComponent::GetColorScalePostProcessPasses() const {
|
||||
std::vector<Math::Vector4> values;
|
||||
values.reserve(m_postProcessPasses.size());
|
||||
for (const Rendering::CameraPostProcessPassDesc& pass : m_postProcessPasses) {
|
||||
if (pass.type == Rendering::CameraPostProcessPassType::ColorScale) {
|
||||
values.push_back(pass.colorScale.scale);
|
||||
}
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
void CameraComponent::SetColorScalePostProcessPasses(const std::vector<Math::Vector4>& values) {
|
||||
m_colorScalePostProcessPasses = values;
|
||||
if (!m_colorScalePostProcessPasses.empty()) {
|
||||
m_colorScalePostProcessDefaultScale = m_colorScalePostProcessPasses.front();
|
||||
SetPostProcessPasses(BuildColorScalePostProcessStack(values));
|
||||
if (!values.empty()) {
|
||||
m_colorScalePostProcessDefaultScale = values.front();
|
||||
}
|
||||
}
|
||||
|
||||
void CameraComponent::AddColorScalePostProcessPass(const Math::Vector4& value) {
|
||||
if (m_colorScalePostProcessPasses.empty()) {
|
||||
if (!IsColorScalePostProcessEnabled()) {
|
||||
m_colorScalePostProcessDefaultScale = value;
|
||||
}
|
||||
|
||||
m_colorScalePostProcessPasses.push_back(value);
|
||||
m_postProcessPasses.push_back(Rendering::CameraPostProcessPassDesc::MakeColorScale(value));
|
||||
}
|
||||
|
||||
void CameraComponent::ClearColorScalePostProcessPasses() {
|
||||
m_postProcessPasses.erase(
|
||||
std::remove_if(
|
||||
m_postProcessPasses.begin(),
|
||||
m_postProcessPasses.end(),
|
||||
[](const Rendering::CameraPostProcessPassDesc& pass) {
|
||||
return pass.type == Rendering::CameraPostProcessPassType::ColorScale;
|
||||
}),
|
||||
m_postProcessPasses.end());
|
||||
}
|
||||
|
||||
void CameraComponent::SetFieldOfView(float value) {
|
||||
@@ -206,12 +276,18 @@ void CameraComponent::Serialize(std::ostream& os) const {
|
||||
os << "skyboxTopColor=" << m_skyboxTopColor.r << "," << m_skyboxTopColor.g << "," << m_skyboxTopColor.b << "," << m_skyboxTopColor.a << ";";
|
||||
os << "skyboxHorizonColor=" << m_skyboxHorizonColor.r << "," << m_skyboxHorizonColor.g << "," << m_skyboxHorizonColor.b << "," << m_skyboxHorizonColor.a << ";";
|
||||
os << "skyboxBottomColor=" << m_skyboxBottomColor.r << "," << m_skyboxBottomColor.g << "," << m_skyboxBottomColor.b << "," << m_skyboxBottomColor.a << ";";
|
||||
os << "colorScalePostProcessEnabled=" << (IsColorScalePostProcessEnabled() ? 1 : 0) << ";";
|
||||
os << "colorScalePostProcessScale=" << EncodeVector4(GetColorScalePostProcessScale()) << ";";
|
||||
os << "colorScalePostProcessPassCount=" << m_colorScalePostProcessPasses.size() << ";";
|
||||
for (size_t index = 0; index < m_colorScalePostProcessPasses.size(); ++index) {
|
||||
os << "colorScalePostProcessPass" << index << "="
|
||||
<< EncodeVector4(m_colorScalePostProcessPasses[index]) << ";";
|
||||
os << "postProcessPassCount=" << m_postProcessPasses.size() << ";";
|
||||
for (size_t index = 0; index < m_postProcessPasses.size(); ++index) {
|
||||
const Rendering::CameraPostProcessPassDesc& pass = m_postProcessPasses[index];
|
||||
os << "postProcessPass" << index << "Type=" << static_cast<int>(pass.type) << ";";
|
||||
switch (pass.type) {
|
||||
case Rendering::CameraPostProcessPassType::ColorScale:
|
||||
os << "postProcessPass" << index << "ColorScale="
|
||||
<< EncodeVector4(pass.colorScale.scale) << ";";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -220,11 +296,13 @@ void CameraComponent::Deserialize(std::istream& is) {
|
||||
m_skyboxMaterialPath.clear();
|
||||
m_skyboxMaterialRef.Reset();
|
||||
m_colorScalePostProcessDefaultScale = Math::Vector4::One();
|
||||
m_colorScalePostProcessPasses.clear();
|
||||
m_postProcessPasses.clear();
|
||||
|
||||
std::string token;
|
||||
std::string pendingSkyboxMaterialPath;
|
||||
Resources::AssetRef pendingSkyboxMaterialRef;
|
||||
size_t postProcessPassCount = 0;
|
||||
Rendering::CameraPostProcessStack deserializedPostProcessPasses;
|
||||
bool legacyColorScaleEnabled = false;
|
||||
size_t colorScalePassCount = 0;
|
||||
std::vector<Math::Vector4> deserializedColorScalePasses;
|
||||
@@ -289,6 +367,33 @@ void CameraComponent::Deserialize(std::istream& is) {
|
||||
std::replace(value.begin(), value.end(), ',', ' ');
|
||||
std::istringstream ss(value);
|
||||
ss >> m_skyboxBottomColor.r >> m_skyboxBottomColor.g >> m_skyboxBottomColor.b >> m_skyboxBottomColor.a;
|
||||
} else if (key == "postProcessPassCount") {
|
||||
postProcessPassCount = static_cast<size_t>(std::stoul(value));
|
||||
deserializedPostProcessPasses.clear();
|
||||
deserializedPostProcessPasses.resize(postProcessPassCount);
|
||||
} else if (key.rfind("postProcessPass", 0) == 0) {
|
||||
const size_t prefixLength = std::string("postProcessPass").size();
|
||||
size_t propertyPos = prefixLength;
|
||||
while (propertyPos < key.size() &&
|
||||
std::isdigit(static_cast<unsigned char>(key[propertyPos])) != 0) {
|
||||
++propertyPos;
|
||||
}
|
||||
|
||||
if (propertyPos > prefixLength) {
|
||||
const size_t index = static_cast<size_t>(
|
||||
std::stoul(key.substr(prefixLength, propertyPos - prefixLength)));
|
||||
if (index >= deserializedPostProcessPasses.size()) {
|
||||
deserializedPostProcessPasses.resize(index + 1);
|
||||
}
|
||||
|
||||
Rendering::CameraPostProcessPassDesc& pass = deserializedPostProcessPasses[index];
|
||||
const std::string property = key.substr(propertyPos);
|
||||
if (property == "Type") {
|
||||
pass.type = static_cast<Rendering::CameraPostProcessPassType>(std::stoi(value));
|
||||
} else if (property == "ColorScale") {
|
||||
TryParseVector4(value, pass.colorScale.scale);
|
||||
}
|
||||
}
|
||||
} else if (key == "colorScalePostProcessEnabled") {
|
||||
legacyColorScaleEnabled = (std::stoi(value) != 0);
|
||||
} else if (key == "colorScalePostProcessScale") {
|
||||
@@ -331,7 +436,9 @@ void CameraComponent::Deserialize(std::istream& is) {
|
||||
m_skyboxMaterialRef = pendingSkyboxMaterialRef;
|
||||
}
|
||||
|
||||
if (!deserializedColorScalePasses.empty()) {
|
||||
if (!deserializedPostProcessPasses.empty()) {
|
||||
SetPostProcessPasses(deserializedPostProcessPasses);
|
||||
} else if (!deserializedColorScalePasses.empty()) {
|
||||
SetColorScalePostProcessPasses(deserializedColorScalePasses);
|
||||
} else if (legacyColorScaleEnabled) {
|
||||
SetColorScalePostProcessEnabled(true);
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
#include "Components/CameraComponent.h"
|
||||
#include "Rendering/Caches/FullscreenPassSurfaceCache.h"
|
||||
#include "Rendering/Passes/BuiltinColorScalePostProcessPass.h"
|
||||
#include "Rendering/Planning/CameraPostProcessPassFactory.h"
|
||||
#include "Rendering/Planning/SceneRenderRequestUtils.h"
|
||||
|
||||
namespace XCEngine {
|
||||
@@ -104,8 +104,8 @@ void SceneRenderer::AttachCameraPostProcessRequests(
|
||||
continue;
|
||||
}
|
||||
|
||||
const std::vector<Math::Vector4>& colorScalePasses = request.camera->GetColorScalePostProcessPasses();
|
||||
if (colorScalePasses.empty()) {
|
||||
const CameraPostProcessStack& postProcessPasses = request.camera->GetPostProcessPasses();
|
||||
if (postProcessPasses.empty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -131,12 +131,11 @@ void SceneRenderer::AttachCameraPostProcessRequests(
|
||||
continue;
|
||||
}
|
||||
|
||||
std::unique_ptr<RenderPassSequence> postProcessSequence = std::make_unique<RenderPassSequence>();
|
||||
for (const Math::Vector4& colorScale : colorScalePasses) {
|
||||
postProcessSequence->AddPass(
|
||||
std::make_unique<Passes::BuiltinColorScalePostProcessPass>(colorScale));
|
||||
std::unique_ptr<RenderPassSequence> postProcessSequence =
|
||||
BuildCameraPostProcessPassSequence(postProcessPasses);
|
||||
if (postProcessSequence == nullptr || postProcessSequence->GetPassCount() == 0u) {
|
||||
continue;
|
||||
}
|
||||
|
||||
RenderSurface sourceSurface = sourceEntry->surface;
|
||||
sourceSurface.SetDepthAttachment(request.surface.GetDepthAttachment());
|
||||
sourceSurface.SetColorStateBefore(RHI::ResourceStates::Common);
|
||||
|
||||
Reference in New Issue
Block a user