rendering: add builtin alpha-test pass support

This commit is contained in:
2026-04-06 21:05:50 +08:00
parent eea38d57d1
commit 9568cf0a16
26 changed files with 856 additions and 104 deletions

View File

@@ -14,6 +14,7 @@ namespace Rendering {
struct BuiltinForwardMaterialData {
Math::Vector4 baseColorFactor = Math::Vector4::One();
float alphaCutoff = 0.5f;
};
enum class BuiltinSkyboxTextureMode : Core::uint8 {
@@ -141,9 +142,39 @@ inline const Resources::Texture* ResolveBuiltinBaseColorTexture(const Resources:
return nullptr;
}
inline float ResolveBuiltinAlphaCutoff(const Resources::Material* material) {
if (material == nullptr) {
return 0.5f;
}
if (const Resources::ShaderPropertyDesc* property = FindShaderPropertyBySemantic(material, "AlphaCutoff")) {
if (material->HasProperty(property->name) &&
(property->type == Resources::ShaderPropertyType::Float ||
property->type == Resources::ShaderPropertyType::Range)) {
return material->GetFloat(property->name);
}
}
static const char* kCutoffPropertyNames[] = {
"_Cutoff",
"cutoff",
"_AlphaCutoff",
"alphaCutoff"
};
for (const char* propertyName : kCutoffPropertyNames) {
if (material->HasProperty(Containers::String(propertyName))) {
return material->GetFloat(Containers::String(propertyName));
}
}
return 0.5f;
}
inline BuiltinForwardMaterialData BuildBuiltinForwardMaterialData(const Resources::Material* material) {
BuiltinForwardMaterialData data = {};
data.baseColorFactor = ResolveBuiltinBaseColorFactor(material);
data.alphaCutoff = ResolveBuiltinAlphaCutoff(material);
return data;
}

View File

@@ -3,6 +3,7 @@
#include <XCEngine/Core/Asset/ResourceHandle.h>
#include <XCEngine/Core/Math/Matrix4.h>
#include <XCEngine/Rendering/Builtin/BuiltinPassTypes.h>
#include <XCEngine/Rendering/Materials/RenderMaterialResolve.h>
#include <XCEngine/Rendering/RenderPass.h>
#include <XCEngine/Rendering/Materials/RenderMaterialStateUtils.h>
#include <XCEngine/Rendering/Caches/RenderResourceCache.h>
@@ -10,14 +11,19 @@
#include <XCEngine/RHI/RHIDescriptorSet.h>
#include <XCEngine/RHI/RHIPipelineLayout.h>
#include <XCEngine/RHI/RHIPipelineState.h>
#include <XCEngine/RHI/RHIResourceView.h>
#include <XCEngine/RHI/RHISampler.h>
#include <XCEngine/RHI/RHITexture.h>
#include <XCEngine/Resources/Shader/Shader.h>
#include <unordered_map>
#include <vector>
namespace XCEngine {
namespace Resources {
class Material;
class Shader;
class Texture;
} // namespace Resources
namespace Rendering {
@@ -54,6 +60,11 @@ private:
RHI::RHIDescriptorSet* set = nullptr;
};
struct FallbackPerMaterialConstants {
Math::Vector4 baseColorFactor = Math::Vector4::One();
Math::Vector4 alphaCutoffParams = Math::Vector4(0.5f, 0.0f, 0.0f, 0.0f);
};
struct PassLayoutKey {
const Resources::Shader* shader = nullptr;
Containers::String passName;
@@ -73,29 +84,46 @@ private:
struct PassResourceLayout {
RHI::RHIPipelineLayout* pipelineLayout = nullptr;
PassResourceBindingLocation perObject = {};
BuiltinPassSetLayoutMetadata perObjectSetLayout = {};
Core::uint32 firstDescriptorSet = 0;
Core::uint32 descriptorSetCount = 0;
std::vector<BuiltinPassSetLayoutMetadata> setLayouts;
std::vector<OwnedDescriptorSet> staticDescriptorSets;
PassResourceBindingLocation perObject = {};
PassResourceBindingLocation material = {};
PassResourceBindingLocation baseColorTexture = {};
PassResourceBindingLocation linearClampSampler = {};
};
struct PerObjectSetKey {
struct DynamicDescriptorSetKey {
PassLayoutKey passLayout = {};
Core::uint32 setIndex = 0;
Core::uint64 objectId = 0;
const Resources::Material* material = nullptr;
bool operator==(const PerObjectSetKey& other) const {
bool operator==(const DynamicDescriptorSetKey& other) const {
return passLayout == other.passLayout &&
setIndex == other.setIndex &&
material == other.material &&
objectId == other.objectId;
}
};
struct PerObjectSetKeyHash {
size_t operator()(const PerObjectSetKey& key) const noexcept {
struct DynamicDescriptorSetKeyHash {
size_t operator()(const DynamicDescriptorSetKey& key) const noexcept {
size_t hash = PassLayoutKeyHash()(key.passLayout);
hash ^= std::hash<Core::uint32>{}(key.setIndex) + 0x9e3779b9u + (hash << 6) + (hash >> 2);
hash ^= std::hash<Core::uint64>{}(key.objectId) + 0x9e3779b9u + (hash << 6) + (hash >> 2);
hash ^= reinterpret_cast<size_t>(key.material) + 0x9e3779b9u + (hash << 6) + (hash >> 2);
return hash;
}
};
struct CachedDescriptorSet {
OwnedDescriptorSet descriptorSet = {};
Core::uint64 materialVersion = 0;
RHI::RHIResourceView* baseColorTextureView = nullptr;
};
struct ResolvedShaderPass {
const Resources::Shader* shader = nullptr;
const Resources::ShaderPass* pass = nullptr;
@@ -157,12 +185,23 @@ private:
bool CreateOwnedDescriptorSet(
const BuiltinPassSetLayoutMetadata& setLayout,
OwnedDescriptorSet& descriptorSet);
RHI::RHIDescriptorSet* GetOrCreatePerObjectSet(
RHI::RHIDescriptorSet* GetOrCreateStaticDescriptorSet(
const PassLayoutKey& passLayoutKey,
PassResourceLayout& passLayout,
Core::uint32 setIndex);
CachedDescriptorSet* GetOrCreateDynamicDescriptorSet(
const PassLayoutKey& passLayoutKey,
const PassResourceLayout& passLayout,
Core::uint64 objectId);
const BuiltinPassSetLayoutMetadata& setLayout,
Core::uint32 setIndex,
Core::uint64 objectId,
const Resources::Material* material,
const MaterialConstantPayloadView& materialConstants,
RHI::RHIResourceView* baseColorTextureView);
void DestroyOwnedDescriptorSet(OwnedDescriptorSet& descriptorSet);
void DestroyPassResourceLayout(PassResourceLayout& passLayout);
RHI::RHIResourceView* ResolveTextureView(const Resources::Texture* texture);
RHI::RHIResourceView* ResolveTextureView(const VisibleRenderItem& visibleItem);
bool DrawVisibleItem(
const RenderContext& context,
const RenderSurface& surface,
@@ -178,7 +217,10 @@ private:
std::unordered_map<PassLayoutKey, PassResourceLayout, PassLayoutKeyHash> m_passResourceLayouts;
std::unordered_map<PipelineStateKey, RHI::RHIPipelineState*, PipelineStateKeyHash> m_pipelineStates;
std::unordered_map<PerObjectSetKey, OwnedDescriptorSet, PerObjectSetKeyHash> m_perObjectSets;
std::unordered_map<DynamicDescriptorSetKey, CachedDescriptorSet, DynamicDescriptorSetKeyHash> m_dynamicDescriptorSets;
RHI::RHISampler* m_sampler = nullptr;
RHI::RHITexture* m_fallbackTexture2D = nullptr;
RHI::RHIResourceView* m_fallbackTexture2DView = nullptr;
};
} // namespace Passes

View File

@@ -98,6 +98,7 @@ private:
struct FallbackPerMaterialConstants {
Math::Vector4 baseColorFactor = Math::Vector4::One();
Math::Vector4 alphaCutoffParams = Math::Vector4(0.5f, 0.0f, 0.0f, 0.0f);
};
struct SkyboxConstants {