Formalize material-driven panoramic skybox path
This commit is contained in:
@@ -1,8 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include <XCEngine/Components/Component.h>
|
||||
#include <XCEngine/Core/Asset/AssetRef.h>
|
||||
#include <XCEngine/Core/Asset/ResourceHandle.h>
|
||||
#include <XCEngine/Core/Math/Color.h>
|
||||
#include <XCEngine/Core/Math/Rect.h>
|
||||
#include <XCEngine/Resources/Material/Material.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace XCEngine {
|
||||
namespace Components {
|
||||
@@ -67,6 +72,14 @@ public:
|
||||
bool IsSkyboxEnabled() const { return m_skyboxEnabled; }
|
||||
void SetSkyboxEnabled(bool value) { m_skyboxEnabled = value; }
|
||||
|
||||
const Resources::ResourceHandle<Resources::Material>& GetSkyboxMaterialHandle() const { return m_skyboxMaterial; }
|
||||
Resources::Material* GetSkyboxMaterial() const { return m_skyboxMaterial.Get(); }
|
||||
const std::string& GetSkyboxMaterialPath() const { return m_skyboxMaterialPath; }
|
||||
const Resources::AssetRef& GetSkyboxMaterialAssetRef() const { return m_skyboxMaterialRef; }
|
||||
void SetSkyboxMaterialPath(const std::string& materialPath);
|
||||
void SetSkyboxMaterial(const Resources::ResourceHandle<Resources::Material>& material);
|
||||
void SetSkyboxMaterial(Resources::Material* material);
|
||||
|
||||
const Math::Color& GetSkyboxTopColor() const { return m_skyboxTopColor; }
|
||||
void SetSkyboxTopColor(const Math::Color& value) { m_skyboxTopColor = value; }
|
||||
|
||||
@@ -93,6 +106,9 @@ private:
|
||||
Math::Rect m_viewportRect = Math::Rect(0.0f, 0.0f, 1.0f, 1.0f);
|
||||
Math::Color m_clearColor = Math::Color(0.192f, 0.302f, 0.475f, 1.0f);
|
||||
bool m_skyboxEnabled = false;
|
||||
Resources::ResourceHandle<Resources::Material> m_skyboxMaterial;
|
||||
std::string m_skyboxMaterialPath;
|
||||
Resources::AssetRef m_skyboxMaterialRef;
|
||||
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);
|
||||
|
||||
@@ -4,12 +4,19 @@
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace XCEngine {
|
||||
namespace Resources {
|
||||
class Material;
|
||||
} // namespace Resources
|
||||
} // namespace XCEngine
|
||||
|
||||
namespace XCEngine {
|
||||
namespace Rendering {
|
||||
|
||||
enum class RenderEnvironmentMode : uint32_t {
|
||||
None = 0,
|
||||
ProceduralSkybox
|
||||
ProceduralSkybox,
|
||||
MaterialSkybox
|
||||
};
|
||||
|
||||
struct ProceduralSkyboxData {
|
||||
@@ -18,13 +25,30 @@ struct ProceduralSkyboxData {
|
||||
Math::Color bottomColor = Math::Color(0.92f, 0.93f, 0.95f, 1.0f);
|
||||
};
|
||||
|
||||
struct MaterialSkyboxData {
|
||||
const Resources::Material* material = nullptr;
|
||||
|
||||
bool IsValid() const {
|
||||
return material != nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
struct RenderEnvironmentData {
|
||||
RenderEnvironmentMode mode = RenderEnvironmentMode::None;
|
||||
ProceduralSkyboxData skybox = {};
|
||||
MaterialSkyboxData materialSkybox = {};
|
||||
|
||||
bool HasProceduralSkybox() const {
|
||||
return mode == RenderEnvironmentMode::ProceduralSkybox;
|
||||
}
|
||||
|
||||
bool HasMaterialSkybox() const {
|
||||
return mode == RenderEnvironmentMode::MaterialSkybox && materialSkybox.IsValid();
|
||||
}
|
||||
|
||||
bool HasSkybox() const {
|
||||
return HasProceduralSkybox() || HasMaterialSkybox();
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace Rendering
|
||||
|
||||
@@ -16,6 +16,12 @@ struct BuiltinForwardMaterialData {
|
||||
Math::Vector4 baseColorFactor = Math::Vector4::One();
|
||||
};
|
||||
|
||||
struct BuiltinSkyboxMaterialData {
|
||||
Math::Vector4 tint = Math::Vector4::One();
|
||||
float exposure = 1.0f;
|
||||
float rotationDegrees = 0.0f;
|
||||
};
|
||||
|
||||
struct MaterialConstantLayoutView {
|
||||
const Resources::MaterialConstantFieldDesc* fields = nullptr;
|
||||
size_t count = 0;
|
||||
@@ -134,6 +140,129 @@ inline BuiltinForwardMaterialData BuildBuiltinForwardMaterialData(const Resource
|
||||
return data;
|
||||
}
|
||||
|
||||
inline const Resources::Texture* ResolveSkyboxTexture(const Resources::Material* material) {
|
||||
if (material == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (const Resources::ShaderPropertyDesc* property = FindShaderPropertyBySemantic(material, "SkyboxTexture")) {
|
||||
const Resources::ResourceHandle<Resources::Texture> textureHandle = material->GetTexture(property->name);
|
||||
if (textureHandle.Get() != nullptr && textureHandle->IsValid()) {
|
||||
return textureHandle.Get();
|
||||
}
|
||||
}
|
||||
|
||||
static const char* kSkyboxTexturePropertyNames[] = {
|
||||
"_MainTex",
|
||||
"_PanoramicTex",
|
||||
"_SkyboxTexture",
|
||||
"panoramicTexture",
|
||||
"skyboxTexture",
|
||||
"texture"
|
||||
};
|
||||
|
||||
for (const char* propertyName : kSkyboxTexturePropertyNames) {
|
||||
const Resources::ResourceHandle<Resources::Texture> textureHandle =
|
||||
material->GetTexture(Containers::String(propertyName));
|
||||
if (textureHandle.Get() != nullptr && textureHandle->IsValid()) {
|
||||
return textureHandle.Get();
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
inline Math::Vector4 ResolveSkyboxTint(const Resources::Material* material) {
|
||||
if (material == nullptr) {
|
||||
return Math::Vector4::One();
|
||||
}
|
||||
|
||||
if (const Resources::ShaderPropertyDesc* property = FindShaderPropertyBySemantic(material, "Tint")) {
|
||||
if (material->HasProperty(property->name) &&
|
||||
(property->type == Resources::ShaderPropertyType::Color ||
|
||||
property->type == Resources::ShaderPropertyType::Vector)) {
|
||||
return material->GetFloat4(property->name);
|
||||
}
|
||||
}
|
||||
|
||||
static const char* kTintPropertyNames[] = {
|
||||
"_Tint",
|
||||
"tint",
|
||||
"_Color",
|
||||
"color"
|
||||
};
|
||||
|
||||
for (const char* propertyName : kTintPropertyNames) {
|
||||
if (material->HasProperty(Containers::String(propertyName))) {
|
||||
return material->GetFloat4(Containers::String(propertyName));
|
||||
}
|
||||
}
|
||||
|
||||
return Math::Vector4::One();
|
||||
}
|
||||
|
||||
inline float ResolveSkyboxExposure(const Resources::Material* material) {
|
||||
if (material == nullptr) {
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
if (const Resources::ShaderPropertyDesc* property = FindShaderPropertyBySemantic(material, "Exposure")) {
|
||||
if (material->HasProperty(property->name) &&
|
||||
(property->type == Resources::ShaderPropertyType::Float ||
|
||||
property->type == Resources::ShaderPropertyType::Range)) {
|
||||
return material->GetFloat(property->name);
|
||||
}
|
||||
}
|
||||
|
||||
static const char* kExposurePropertyNames[] = {
|
||||
"_Exposure",
|
||||
"exposure"
|
||||
};
|
||||
|
||||
for (const char* propertyName : kExposurePropertyNames) {
|
||||
if (material->HasProperty(Containers::String(propertyName))) {
|
||||
return material->GetFloat(Containers::String(propertyName));
|
||||
}
|
||||
}
|
||||
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
inline float ResolveSkyboxRotationDegrees(const Resources::Material* material) {
|
||||
if (material == nullptr) {
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
if (const Resources::ShaderPropertyDesc* property = FindShaderPropertyBySemantic(material, "Rotation")) {
|
||||
if (material->HasProperty(property->name) &&
|
||||
(property->type == Resources::ShaderPropertyType::Float ||
|
||||
property->type == Resources::ShaderPropertyType::Range)) {
|
||||
return material->GetFloat(property->name);
|
||||
}
|
||||
}
|
||||
|
||||
static const char* kRotationPropertyNames[] = {
|
||||
"_Rotation",
|
||||
"rotation"
|
||||
};
|
||||
|
||||
for (const char* propertyName : kRotationPropertyNames) {
|
||||
if (material->HasProperty(Containers::String(propertyName))) {
|
||||
return material->GetFloat(Containers::String(propertyName));
|
||||
}
|
||||
}
|
||||
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
inline BuiltinSkyboxMaterialData BuildBuiltinSkyboxMaterialData(const Resources::Material* material) {
|
||||
BuiltinSkyboxMaterialData data = {};
|
||||
data.tint = ResolveSkyboxTint(material);
|
||||
data.exposure = ResolveSkyboxExposure(material);
|
||||
data.rotationDegrees = ResolveSkyboxRotationDegrees(material);
|
||||
return data;
|
||||
}
|
||||
|
||||
inline MaterialConstantPayloadView ResolveSchemaMaterialConstantPayload(const Resources::Material* material) {
|
||||
if (material == nullptr || material->GetShader() == nullptr) {
|
||||
return {};
|
||||
|
||||
@@ -109,6 +109,11 @@ private:
|
||||
Math::Vector4 cameraForwardAndUnused = Math::Vector4::Zero();
|
||||
};
|
||||
|
||||
struct SkyboxMaterialConstants {
|
||||
Math::Vector4 tintAndExposure = Math::Vector4(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
Math::Vector4 rotationRadiansAndMode = Math::Vector4::Zero();
|
||||
};
|
||||
|
||||
struct PassLayoutKey {
|
||||
const Resources::Shader* shader = nullptr;
|
||||
Containers::String passName;
|
||||
@@ -243,9 +248,11 @@ private:
|
||||
void DestroyPassResourceLayout(PassResourceLayout& passLayout);
|
||||
|
||||
const Resources::Texture* ResolveTexture(const Resources::Material* material) const;
|
||||
RHI::RHIResourceView* ResolveTextureView(const Resources::Texture* texture);
|
||||
RHI::RHIResourceView* ResolveTextureView(const VisibleRenderItem& visibleItem);
|
||||
static LightingConstants BuildLightingConstants(const RenderLightingData& lightingData);
|
||||
static AdditionalLightConstants BuildAdditionalLightConstants(const RenderAdditionalLightData& lightData);
|
||||
bool HasSkybox(const RenderSceneData& sceneData) const;
|
||||
bool HasProceduralSkybox(const RenderSceneData& sceneData) const;
|
||||
bool BeginForwardScenePass(const RenderPassContext& context);
|
||||
void EndForwardScenePass(const RenderPassContext& context);
|
||||
@@ -282,8 +289,11 @@ private:
|
||||
RHI::RHIResourceView* m_fallbackTextureView = nullptr;
|
||||
RHI::RHIPipelineLayout* m_skyboxPipelineLayout = nullptr;
|
||||
RHI::RHIPipelineState* m_skyboxPipelineState = nullptr;
|
||||
RHI::RHIDescriptorPool* m_skyboxConstantPool = nullptr;
|
||||
RHI::RHIDescriptorSet* m_skyboxConstantSet = nullptr;
|
||||
OwnedDescriptorSet m_skyboxEnvironmentSet = {};
|
||||
OwnedDescriptorSet m_skyboxMaterialSet = {};
|
||||
OwnedDescriptorSet m_skyboxTextureSet = {};
|
||||
OwnedDescriptorSet m_skyboxSamplerSet = {};
|
||||
RHI::RHIResourceView* m_skyboxBoundTextureView = nullptr;
|
||||
RenderPassSequence m_passSequence;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user