Support camera-config color-scale pass stacks
This commit is contained in:
@@ -9,6 +9,7 @@
|
||||
#include <XCEngine/Resources/Material/Material.h>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace XCEngine {
|
||||
namespace Components {
|
||||
@@ -90,11 +91,16 @@ public:
|
||||
const Math::Color& GetSkyboxBottomColor() const { return m_skyboxBottomColor; }
|
||||
void SetSkyboxBottomColor(const Math::Color& value) { m_skyboxBottomColor = value; }
|
||||
|
||||
bool IsColorScalePostProcessEnabled() const { return m_colorScalePostProcessEnabled; }
|
||||
void SetColorScalePostProcessEnabled(bool value) { m_colorScalePostProcessEnabled = value; }
|
||||
bool IsColorScalePostProcessEnabled() const;
|
||||
void SetColorScalePostProcessEnabled(bool value);
|
||||
|
||||
const Math::Vector4& GetColorScalePostProcessScale() const { return m_colorScalePostProcessScale; }
|
||||
void SetColorScalePostProcessScale(const Math::Vector4& value) { m_colorScalePostProcessScale = value; }
|
||||
const Math::Vector4& GetColorScalePostProcessScale() const;
|
||||
void SetColorScalePostProcessScale(const Math::Vector4& value);
|
||||
|
||||
const std::vector<Math::Vector4>& GetColorScalePostProcessPasses() const { return m_colorScalePostProcessPasses; }
|
||||
void SetColorScalePostProcessPasses(const std::vector<Math::Vector4>& values);
|
||||
void AddColorScalePostProcessPass(const Math::Vector4& value);
|
||||
void ClearColorScalePostProcessPasses() { m_colorScalePostProcessPasses.clear(); }
|
||||
|
||||
void Serialize(std::ostream& os) const override;
|
||||
void Deserialize(std::istream& is) override;
|
||||
@@ -119,8 +125,8 @@ private:
|
||||
Math::Color m_skyboxTopColor = Math::Color(0.18f, 0.36f, 0.74f, 1.0f);
|
||||
Math::Color m_skyboxHorizonColor = Math::Color(0.78f, 0.84f, 0.92f, 1.0f);
|
||||
Math::Color m_skyboxBottomColor = Math::Color(0.92f, 0.93f, 0.95f, 1.0f);
|
||||
bool m_colorScalePostProcessEnabled = false;
|
||||
Math::Vector4 m_colorScalePostProcessScale = Math::Vector4::One();
|
||||
Math::Vector4 m_colorScalePostProcessDefaultScale = Math::Vector4::One();
|
||||
std::vector<Math::Vector4> m_colorScalePostProcessPasses;
|
||||
};
|
||||
|
||||
} // namespace Components
|
||||
|
||||
@@ -42,8 +42,65 @@ bool TryDecodeAssetRef(const std::string& value, Resources::AssetRef& outRef) {
|
||||
return outRef.IsValid();
|
||||
}
|
||||
|
||||
std::string EncodeVector4(const Math::Vector4& value) {
|
||||
std::ostringstream stream;
|
||||
stream << value.x << "," << value.y << "," << value.z << "," << value.w;
|
||||
return stream.str();
|
||||
}
|
||||
|
||||
bool TryParseVector4(const std::string& value, Math::Vector4& outValue) {
|
||||
std::string normalized = value;
|
||||
std::replace(normalized.begin(), normalized.end(), ',', ' ');
|
||||
std::istringstream stream(normalized);
|
||||
stream >> outValue.x >> outValue.y >> outValue.z >> outValue.w;
|
||||
return !stream.fail();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
bool CameraComponent::IsColorScalePostProcessEnabled() const {
|
||||
return !m_colorScalePostProcessPasses.empty();
|
||||
}
|
||||
|
||||
void CameraComponent::SetColorScalePostProcessEnabled(bool value) {
|
||||
if (value) {
|
||||
if (m_colorScalePostProcessPasses.empty()) {
|
||||
m_colorScalePostProcessPasses.push_back(m_colorScalePostProcessDefaultScale);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
m_colorScalePostProcessPasses.clear();
|
||||
}
|
||||
|
||||
const Math::Vector4& CameraComponent::GetColorScalePostProcessScale() const {
|
||||
return m_colorScalePostProcessPasses.empty()
|
||||
? m_colorScalePostProcessDefaultScale
|
||||
: m_colorScalePostProcessPasses.front();
|
||||
}
|
||||
|
||||
void CameraComponent::SetColorScalePostProcessScale(const Math::Vector4& value) {
|
||||
m_colorScalePostProcessDefaultScale = value;
|
||||
if (!m_colorScalePostProcessPasses.empty()) {
|
||||
m_colorScalePostProcessPasses.front() = value;
|
||||
}
|
||||
}
|
||||
|
||||
void CameraComponent::SetColorScalePostProcessPasses(const std::vector<Math::Vector4>& values) {
|
||||
m_colorScalePostProcessPasses = values;
|
||||
if (!m_colorScalePostProcessPasses.empty()) {
|
||||
m_colorScalePostProcessDefaultScale = m_colorScalePostProcessPasses.front();
|
||||
}
|
||||
}
|
||||
|
||||
void CameraComponent::AddColorScalePostProcessPass(const Math::Vector4& value) {
|
||||
if (m_colorScalePostProcessPasses.empty()) {
|
||||
m_colorScalePostProcessDefaultScale = value;
|
||||
}
|
||||
|
||||
m_colorScalePostProcessPasses.push_back(value);
|
||||
}
|
||||
|
||||
void CameraComponent::SetFieldOfView(float value) {
|
||||
m_fieldOfView = std::clamp(value, 1.0f, 179.0f);
|
||||
}
|
||||
@@ -149,22 +206,28 @@ 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=" << (m_colorScalePostProcessEnabled ? 1 : 0) << ";";
|
||||
os << "colorScalePostProcessScale="
|
||||
<< m_colorScalePostProcessScale.x << ","
|
||||
<< m_colorScalePostProcessScale.y << ","
|
||||
<< m_colorScalePostProcessScale.z << ","
|
||||
<< m_colorScalePostProcessScale.w << ";";
|
||||
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]) << ";";
|
||||
}
|
||||
}
|
||||
|
||||
void CameraComponent::Deserialize(std::istream& is) {
|
||||
m_skyboxMaterial.Reset();
|
||||
m_skyboxMaterialPath.clear();
|
||||
m_skyboxMaterialRef.Reset();
|
||||
m_colorScalePostProcessDefaultScale = Math::Vector4::One();
|
||||
m_colorScalePostProcessPasses.clear();
|
||||
|
||||
std::string token;
|
||||
std::string pendingSkyboxMaterialPath;
|
||||
Resources::AssetRef pendingSkyboxMaterialRef;
|
||||
bool legacyColorScaleEnabled = false;
|
||||
size_t colorScalePassCount = 0;
|
||||
std::vector<Math::Vector4> deserializedColorScalePasses;
|
||||
while (std::getline(is, token, ';')) {
|
||||
if (token.empty()) {
|
||||
continue;
|
||||
@@ -227,14 +290,22 @@ void CameraComponent::Deserialize(std::istream& is) {
|
||||
std::istringstream ss(value);
|
||||
ss >> m_skyboxBottomColor.r >> m_skyboxBottomColor.g >> m_skyboxBottomColor.b >> m_skyboxBottomColor.a;
|
||||
} else if (key == "colorScalePostProcessEnabled") {
|
||||
m_colorScalePostProcessEnabled = (std::stoi(value) != 0);
|
||||
legacyColorScaleEnabled = (std::stoi(value) != 0);
|
||||
} else if (key == "colorScalePostProcessScale") {
|
||||
std::replace(value.begin(), value.end(), ',', ' ');
|
||||
std::istringstream ss(value);
|
||||
ss >> m_colorScalePostProcessScale.x
|
||||
>> m_colorScalePostProcessScale.y
|
||||
>> m_colorScalePostProcessScale.z
|
||||
>> m_colorScalePostProcessScale.w;
|
||||
TryParseVector4(value, m_colorScalePostProcessDefaultScale);
|
||||
} else if (key == "colorScalePostProcessPassCount") {
|
||||
colorScalePassCount = static_cast<size_t>(std::stoul(value));
|
||||
deserializedColorScalePasses.clear();
|
||||
deserializedColorScalePasses.resize(colorScalePassCount, Math::Vector4::One());
|
||||
} else if (key.rfind("colorScalePostProcessPass", 0) == 0) {
|
||||
const std::string indexString = key.substr(std::string("colorScalePostProcessPass").size());
|
||||
if (!indexString.empty()) {
|
||||
const size_t index = static_cast<size_t>(std::stoul(indexString));
|
||||
if (index >= deserializedColorScalePasses.size()) {
|
||||
deserializedColorScalePasses.resize(index + 1, Math::Vector4::One());
|
||||
}
|
||||
TryParseVector4(value, deserializedColorScalePasses[index]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -259,6 +330,12 @@ void CameraComponent::Deserialize(std::istream& is) {
|
||||
if (m_skyboxMaterial.Get() == nullptr && pendingSkyboxMaterialRef.IsValid()) {
|
||||
m_skyboxMaterialRef = pendingSkyboxMaterialRef;
|
||||
}
|
||||
|
||||
if (!deserializedColorScalePasses.empty()) {
|
||||
SetColorScalePostProcessPasses(deserializedColorScalePasses);
|
||||
} else if (legacyColorScaleEnabled) {
|
||||
SetColorScalePostProcessEnabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Components
|
||||
|
||||
@@ -99,12 +99,16 @@ void SceneRenderer::AttachCameraPostProcessRequests(
|
||||
for (size_t index = 0; index < requests.size(); ++index) {
|
||||
CameraRenderRequest& request = requests[index];
|
||||
if (request.camera == nullptr ||
|
||||
!request.camera->IsColorScalePostProcessEnabled() ||
|
||||
request.context.device == nullptr ||
|
||||
!HasValidColorTarget(request.surface)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const std::vector<Math::Vector4>& colorScalePasses = request.camera->GetColorScalePostProcessPasses();
|
||||
if (colorScalePasses.empty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const std::vector<RHI::RHIResourceView*>& colorAttachments = request.surface.GetColorAttachments();
|
||||
const RHI::Format colorFormat = colorAttachments[0]->GetFormat();
|
||||
if (colorFormat == RHI::Format::Unknown) {
|
||||
@@ -128,8 +132,10 @@ void SceneRenderer::AttachCameraPostProcessRequests(
|
||||
}
|
||||
|
||||
std::unique_ptr<RenderPassSequence> postProcessSequence = std::make_unique<RenderPassSequence>();
|
||||
postProcessSequence->AddPass(std::make_unique<Passes::BuiltinColorScalePostProcessPass>(
|
||||
request.camera->GetColorScalePostProcessScale()));
|
||||
for (const Math::Vector4& colorScale : colorScalePasses) {
|
||||
postProcessSequence->AddPass(
|
||||
std::make_unique<Passes::BuiltinColorScalePostProcessPass>(colorScale));
|
||||
}
|
||||
|
||||
RenderSurface sourceSurface = sourceEntry->surface;
|
||||
sourceSurface.SetDepthAttachment(request.surface.GetDepthAttachment());
|
||||
|
||||
Reference in New Issue
Block a user