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;
}