Add builtin unlit surface path

This commit is contained in:
2026-04-03 17:18:46 +08:00
parent 1ac2afb0bb
commit 308b3b061c
14 changed files with 466 additions and 14 deletions

View File

@@ -118,9 +118,26 @@ bool BindingNumberExists(
return false;
}
const Resources::ShaderPass* FindForwardCompatiblePass(
bool TryResolveSurfacePassType(
const Resources::Material* material,
BuiltinMaterialPass& outPass) {
if (MatchesBuiltinPass(material, BuiltinMaterialPass::Unlit)) {
outPass = BuiltinMaterialPass::Unlit;
return true;
}
if (MatchesBuiltinPass(material, BuiltinMaterialPass::ForwardLit)) {
outPass = BuiltinMaterialPass::ForwardLit;
return true;
}
return false;
}
const Resources::ShaderPass* FindCompatibleSurfacePass(
const Resources::Shader& shader,
const Resources::Material* material,
BuiltinMaterialPass pass,
Resources::ShaderBackend backend) {
if (material != nullptr && !material->GetShaderPass().Empty()) {
const Resources::ShaderPass* explicitPass = shader.FindPass(material->GetShaderPass());
@@ -131,12 +148,16 @@ const Resources::ShaderPass* FindForwardCompatiblePass(
}
for (const Resources::ShaderPass& shaderPass : shader.GetPasses()) {
if (ShaderPassMatchesBuiltinPass(shaderPass, BuiltinMaterialPass::ForwardLit) &&
if (ShaderPassMatchesBuiltinPass(shaderPass, pass) &&
::XCEngine::Rendering::Detail::ShaderPassHasGraphicsVariants(shader, shaderPass.name, backend)) {
return &shaderPass;
}
}
if (pass != BuiltinMaterialPass::ForwardLit) {
return nullptr;
}
const Resources::ShaderPass* defaultPass = shader.FindPass("ForwardLit");
if (defaultPass != nullptr &&
::XCEngine::Rendering::Detail::ShaderPassHasGraphicsVariants(shader, defaultPass->name, backend)) {
@@ -331,7 +352,8 @@ bool BuiltinForwardPipeline::ExecuteForwardOpaquePass(const RenderPassContext& p
RHI::RHIPipelineState* currentPipelineState = nullptr;
for (const VisibleRenderItem& visibleItem : sceneData.visibleItems) {
const Resources::Material* material = ResolveMaterial(visibleItem);
if (!MatchesBuiltinPass(material, BuiltinMaterialPass::ForwardLit)) {
BuiltinMaterialPass pass = BuiltinMaterialPass::ForwardLit;
if (!TryResolveSurfacePassType(material, pass)) {
continue;
}
@@ -389,6 +411,15 @@ bool BuiltinForwardPipeline::CreatePipelineResources(const RenderContext& contex
return false;
}
m_builtinUnlitShader = Resources::ResourceManager::Get().Load<Resources::Shader>(
Resources::GetBuiltinUnlitShaderPath());
if (!m_builtinUnlitShader.IsValid()) {
Debug::Logger::Get().Error(
Debug::LogCategory::Rendering,
"BuiltinForwardPipeline failed to load builtin unlit shader resource");
return false;
}
RHI::SamplerDesc samplerDesc = {};
samplerDesc.filter = static_cast<uint32_t>(RHI::FilterMode::Linear);
samplerDesc.addressU = static_cast<uint32_t>(RHI::TextureAddressMode::Clamp);
@@ -475,17 +506,23 @@ void BuiltinForwardPipeline::DestroyPipelineResources() {
m_device = nullptr;
m_initialized = false;
m_builtinForwardShader.Reset();
m_builtinUnlitShader.Reset();
}
BuiltinForwardPipeline::ResolvedShaderPass BuiltinForwardPipeline::ResolveForwardShaderPass(
BuiltinForwardPipeline::ResolvedShaderPass BuiltinForwardPipeline::ResolveSurfaceShaderPass(
const Resources::Material* material) const {
ResolvedShaderPass resolved = {};
BuiltinMaterialPass pass = BuiltinMaterialPass::ForwardLit;
if (!TryResolveSurfacePassType(material, pass)) {
return resolved;
}
const Resources::ShaderBackend backend = ::XCEngine::Rendering::Detail::ToShaderBackend(m_backendType);
if (material != nullptr && material->GetShader() != nullptr) {
const Resources::Shader* materialShader = material->GetShader();
if (const Resources::ShaderPass* shaderPass =
FindForwardCompatiblePass(*materialShader, material, backend)) {
FindCompatibleSurfacePass(*materialShader, material, pass, backend)) {
resolved.shader = materialShader;
resolved.pass = shaderPass;
resolved.passName = shaderPass->name;
@@ -493,10 +530,12 @@ BuiltinForwardPipeline::ResolvedShaderPass BuiltinForwardPipeline::ResolveForwar
}
}
if (m_builtinForwardShader.IsValid()) {
const Resources::Shader* builtinShader = m_builtinForwardShader.Get();
const Resources::ResourceHandle<Resources::Shader>* builtinShaderHandle =
pass == BuiltinMaterialPass::Unlit ? &m_builtinUnlitShader : &m_builtinForwardShader;
if (builtinShaderHandle->IsValid()) {
const Resources::Shader* builtinShader = builtinShaderHandle->Get();
if (const Resources::ShaderPass* shaderPass =
FindForwardCompatiblePass(*builtinShader, nullptr, backend)) {
FindCompatibleSurfacePass(*builtinShader, nullptr, pass, backend)) {
resolved.shader = builtinShader;
resolved.pass = shaderPass;
resolved.passName = shaderPass->name;
@@ -672,11 +711,11 @@ BuiltinForwardPipeline::PassResourceLayout* BuiltinForwardPipeline::GetOrCreateP
RHI::RHIPipelineState* BuiltinForwardPipeline::GetOrCreatePipelineState(
const RenderContext& context,
const Resources::Material* material) {
const ResolvedShaderPass resolvedShaderPass = ResolveForwardShaderPass(material);
const ResolvedShaderPass resolvedShaderPass = ResolveSurfaceShaderPass(material);
if (resolvedShaderPass.shader == nullptr || resolvedShaderPass.pass == nullptr) {
Debug::Logger::Get().Error(
Debug::LogCategory::Rendering,
"BuiltinForwardPipeline could not resolve a valid ForwardLit shader pass");
"BuiltinForwardPipeline could not resolve a valid surface shader pass");
return nullptr;
}
@@ -919,7 +958,7 @@ bool BuiltinForwardPipeline::DrawVisibleItem(
};
const Resources::Material* material = ResolveMaterial(visibleItem);
const ResolvedShaderPass resolvedShaderPass = ResolveForwardShaderPass(material);
const ResolvedShaderPass resolvedShaderPass = ResolveSurfaceShaderPass(material);
if (resolvedShaderPass.shader == nullptr || resolvedShaderPass.pass == nullptr) {
return false;
}

View File

@@ -28,6 +28,7 @@ constexpr const char* kBuiltinShaderPrefix = "builtin://shaders/";
constexpr const char* kBuiltinTexturePrefix = "builtin://textures/";
constexpr const char* kBuiltinDefaultPrimitiveMaterialPath = "builtin://materials/default-primitive";
constexpr const char* kBuiltinForwardLitShaderPath = "builtin://shaders/forward-lit";
constexpr const char* kBuiltinUnlitShaderPath = "builtin://shaders/unlit";
constexpr const char* kBuiltinObjectIdShaderPath = "builtin://shaders/object-id";
constexpr const char* kBuiltinDefaultPrimitiveTexturePath = "builtin://textures/default-primitive-albedo";
constexpr float kPi = 3.14159265358979323846f;
@@ -41,6 +42,8 @@ size_t CalculateBuiltinShaderMemorySize(const Shader& shader);
constexpr const char* kBuiltinForwardLitShaderManifestRelativePath =
"engine/assets/builtin/shaders/forward-lit/forward-lit.shader";
constexpr const char* kBuiltinUnlitShaderManifestRelativePath =
"engine/assets/builtin/shaders/unlit/unlit.shader";
constexpr const char* kBuiltinObjectIdShaderManifestRelativePath =
"engine/assets/builtin/shaders/object-id/object-id.shader";
@@ -109,6 +112,9 @@ const char* GetBuiltinShaderManifestRelativePath(const Containers::String& built
if (builtinShaderPath == Containers::String(kBuiltinForwardLitShaderPath)) {
return kBuiltinForwardLitShaderManifestRelativePath;
}
if (builtinShaderPath == Containers::String(kBuiltinUnlitShaderPath)) {
return kBuiltinUnlitShaderManifestRelativePath;
}
if (builtinShaderPath == Containers::String(kBuiltinObjectIdShaderPath)) {
return kBuiltinObjectIdShaderManifestRelativePath;
}
@@ -636,6 +642,10 @@ Shader* BuildBuiltinForwardLitShader(const Containers::String& path) {
return TryLoadBuiltinShaderFromManifest(path);
}
Shader* BuildBuiltinUnlitShader(const Containers::String& path) {
return TryLoadBuiltinShaderFromManifest(path);
}
Shader* BuildBuiltinObjectIdShader(const Containers::String& path) {
return TryLoadBuiltinShaderFromManifest(path);
}
@@ -742,6 +752,10 @@ Containers::String GetBuiltinForwardLitShaderPath() {
return Containers::String(kBuiltinForwardLitShaderPath);
}
Containers::String GetBuiltinUnlitShaderPath() {
return Containers::String(kBuiltinUnlitShaderPath);
}
Containers::String GetBuiltinObjectIdShaderPath() {
return Containers::String(kBuiltinObjectIdShaderPath);
}
@@ -836,6 +850,8 @@ LoadResult CreateBuiltinShaderResource(const Containers::String& path) {
Shader* shader = nullptr;
if (path == GetBuiltinForwardLitShaderPath()) {
shader = BuildBuiltinForwardLitShader(path);
} else if (path == GetBuiltinUnlitShaderPath()) {
shader = BuildBuiltinUnlitShader(path);
} else if (path == GetBuiltinObjectIdShaderPath()) {
shader = BuildBuiltinObjectIdShader(path);
} else {