Add builtin unlit surface path
This commit is contained in:
@@ -342,8 +342,12 @@ Unity-like Shader Authoring (.shader)
|
|||||||
- builtin object-id shader 已显式声明 `PerObject` 资源合约
|
- builtin object-id shader 已显式声明 `PerObject` 资源合约
|
||||||
- `BuiltinObjectIdPass` 已改为消费通用 binding plan,不再硬编码 `set0/binding0` 常量布局
|
- `BuiltinObjectIdPass` 已改为消费通用 binding plan,不再硬编码 `set0/binding0` 常量布局
|
||||||
- 显式 shader `resources` 与 legacy object-id fallback 现在走同一套解析与校验路径
|
- 显式 shader `resources` 与 legacy object-id fallback 现在走同一套解析与校验路径
|
||||||
- 已验证:`rendering_unit_tests` 59/59,`shader_tests` 26/26
|
- 已完成:builtin `Unlit` shader / pipeline 主线接入共享执行边界
|
||||||
- 下一步:把同一套共享执行边界继续推到 `Unlit`,并评估是否抽出 forward/object-id 共用的 pass layout 构建与 descriptor set 组装骨架
|
- 新增 builtin `unlit` shader 资产与 `BuiltinResources` 入口
|
||||||
|
- `BuiltinForwardPipeline` 现在会在 `ForwardLit + Unlit` 之间按 material/shader metadata 解析目标 pass
|
||||||
|
- `Unlit` 与 `ForwardLit` 现在共用同一套 input layout、material schema、binding plan 与 descriptor 组装路径
|
||||||
|
- 已验证:`rendering_unit_tests` 61/61,`shader_tests` 27/27,`material_tests` 51/51
|
||||||
|
- 下一步:评估是否抽出 `ForwardLit / Unlit / ObjectId` 共用的 pass layout 构建与 descriptor set 组装骨架,并继续推进 `DepthOnly / ShadowCaster`
|
||||||
|
|
||||||
### 阶段 D:扩展 AssetDatabase / Library Artifact 能力
|
### 阶段 D:扩展 AssetDatabase / Library Artifact 能力
|
||||||
|
|
||||||
|
|||||||
24
engine/assets/builtin/shaders/unlit/unlit.frag.glsl
Normal file
24
engine/assets/builtin/shaders/unlit/unlit.frag.glsl
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
// XC_BUILTIN_UNLIT_OPENGL_PS
|
||||||
|
#version 430
|
||||||
|
layout(binding = 1) uniform sampler2D uBaseColorTexture;
|
||||||
|
|
||||||
|
layout(std140, binding = 1) uniform PerObjectConstants {
|
||||||
|
mat4 gProjectionMatrix;
|
||||||
|
mat4 gViewMatrix;
|
||||||
|
mat4 gModelMatrix;
|
||||||
|
mat4 gNormalMatrix;
|
||||||
|
vec4 gMainLightDirectionAndIntensity;
|
||||||
|
vec4 gMainLightColorAndFlags;
|
||||||
|
};
|
||||||
|
|
||||||
|
layout(std140, binding = 2) uniform MaterialConstants {
|
||||||
|
vec4 gBaseColorFactor;
|
||||||
|
};
|
||||||
|
|
||||||
|
in vec2 vTexCoord;
|
||||||
|
|
||||||
|
layout(location = 0) out vec4 fragColor;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
fragColor = texture(uBaseColorTexture, vTexCoord) * gBaseColorFactor;
|
||||||
|
}
|
||||||
25
engine/assets/builtin/shaders/unlit/unlit.frag.vk.glsl
Normal file
25
engine/assets/builtin/shaders/unlit/unlit.frag.vk.glsl
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
// XC_BUILTIN_UNLIT_VULKAN_PS
|
||||||
|
#version 450
|
||||||
|
layout(set = 3, binding = 0) uniform texture2D uBaseColorTexture;
|
||||||
|
layout(set = 4, binding = 0) uniform sampler uLinearSampler;
|
||||||
|
|
||||||
|
layout(set = 1, binding = 0, std140) uniform PerObjectConstants {
|
||||||
|
mat4 gProjectionMatrix;
|
||||||
|
mat4 gViewMatrix;
|
||||||
|
mat4 gModelMatrix;
|
||||||
|
mat4 gNormalMatrix;
|
||||||
|
vec4 gMainLightDirectionAndIntensity;
|
||||||
|
vec4 gMainLightColorAndFlags;
|
||||||
|
};
|
||||||
|
|
||||||
|
layout(set = 2, binding = 0, std140) uniform MaterialConstants {
|
||||||
|
vec4 gBaseColorFactor;
|
||||||
|
};
|
||||||
|
|
||||||
|
layout(location = 0) in vec2 vTexCoord;
|
||||||
|
|
||||||
|
layout(location = 0) out vec4 fragColor;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
fragColor = texture(sampler2D(uBaseColorTexture, uLinearSampler), vTexCoord) * gBaseColorFactor;
|
||||||
|
}
|
||||||
25
engine/assets/builtin/shaders/unlit/unlit.ps.hlsl
Normal file
25
engine/assets/builtin/shaders/unlit/unlit.ps.hlsl
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
// XC_BUILTIN_UNLIT_D3D12_PS
|
||||||
|
Texture2D gBaseColorTexture : register(t1);
|
||||||
|
SamplerState gLinearSampler : register(s1);
|
||||||
|
|
||||||
|
cbuffer PerObjectConstants : register(b1) {
|
||||||
|
float4x4 gProjectionMatrix;
|
||||||
|
float4x4 gViewMatrix;
|
||||||
|
float4x4 gModelMatrix;
|
||||||
|
float4x4 gNormalMatrix;
|
||||||
|
float4 gMainLightDirectionAndIntensity;
|
||||||
|
float4 gMainLightColorAndFlags;
|
||||||
|
};
|
||||||
|
|
||||||
|
cbuffer MaterialConstants : register(b2) {
|
||||||
|
float4 gBaseColorFactor;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PSInput {
|
||||||
|
float4 position : SV_POSITION;
|
||||||
|
float2 texcoord : TEXCOORD0;
|
||||||
|
};
|
||||||
|
|
||||||
|
float4 MainPS(PSInput input) : SV_TARGET {
|
||||||
|
return gBaseColorTexture.Sample(gLinearSampler, input.texcoord) * gBaseColorFactor;
|
||||||
|
}
|
||||||
99
engine/assets/builtin/shaders/unlit/unlit.shader
Normal file
99
engine/assets/builtin/shaders/unlit/unlit.shader
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
{
|
||||||
|
"name": "Builtin Unlit",
|
||||||
|
"properties": [
|
||||||
|
{
|
||||||
|
"name": "_BaseColor",
|
||||||
|
"displayName": "Base Color",
|
||||||
|
"type": "Color",
|
||||||
|
"defaultValue": "(1,1,1,1)",
|
||||||
|
"semantic": "BaseColor"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "_MainTex",
|
||||||
|
"displayName": "Base Map",
|
||||||
|
"type": "2D",
|
||||||
|
"defaultValue": "white",
|
||||||
|
"semantic": "BaseColorTexture"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"passes": [
|
||||||
|
{
|
||||||
|
"name": "Unlit",
|
||||||
|
"tags": {
|
||||||
|
"LightMode": "Unlit"
|
||||||
|
},
|
||||||
|
"resources": [
|
||||||
|
{
|
||||||
|
"name": "PerObjectConstants",
|
||||||
|
"type": "ConstantBuffer",
|
||||||
|
"set": 1,
|
||||||
|
"binding": 0,
|
||||||
|
"semantic": "PerObject"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "MaterialConstants",
|
||||||
|
"type": "ConstantBuffer",
|
||||||
|
"set": 2,
|
||||||
|
"binding": 0,
|
||||||
|
"semantic": "Material"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "BaseColorTexture",
|
||||||
|
"type": "Texture2D",
|
||||||
|
"set": 3,
|
||||||
|
"binding": 0,
|
||||||
|
"semantic": "BaseColorTexture"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "LinearClampSampler",
|
||||||
|
"type": "Sampler",
|
||||||
|
"set": 4,
|
||||||
|
"binding": 0,
|
||||||
|
"semantic": "LinearClampSampler"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"variants": [
|
||||||
|
{
|
||||||
|
"stage": "Vertex",
|
||||||
|
"backend": "D3D12",
|
||||||
|
"language": "HLSL",
|
||||||
|
"source": "unlit.vs.hlsl",
|
||||||
|
"entryPoint": "MainVS",
|
||||||
|
"profile": "vs_5_0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"stage": "Fragment",
|
||||||
|
"backend": "D3D12",
|
||||||
|
"language": "HLSL",
|
||||||
|
"source": "unlit.ps.hlsl",
|
||||||
|
"entryPoint": "MainPS",
|
||||||
|
"profile": "ps_5_0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"stage": "Vertex",
|
||||||
|
"backend": "OpenGL",
|
||||||
|
"language": "GLSL",
|
||||||
|
"source": "unlit.vert.glsl"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"stage": "Fragment",
|
||||||
|
"backend": "OpenGL",
|
||||||
|
"language": "GLSL",
|
||||||
|
"source": "unlit.frag.glsl"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"stage": "Vertex",
|
||||||
|
"backend": "Vulkan",
|
||||||
|
"language": "GLSL",
|
||||||
|
"source": "unlit.vert.vk.glsl"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"stage": "Fragment",
|
||||||
|
"backend": "Vulkan",
|
||||||
|
"language": "GLSL",
|
||||||
|
"source": "unlit.frag.vk.glsl"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
23
engine/assets/builtin/shaders/unlit/unlit.vert.glsl
Normal file
23
engine/assets/builtin/shaders/unlit/unlit.vert.glsl
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
// XC_BUILTIN_UNLIT_OPENGL_VS
|
||||||
|
#version 430
|
||||||
|
layout(location = 0) in vec3 aPosition;
|
||||||
|
layout(location = 1) in vec3 aNormal;
|
||||||
|
layout(location = 2) in vec2 aTexCoord;
|
||||||
|
|
||||||
|
layout(std140, binding = 1) uniform PerObjectConstants {
|
||||||
|
mat4 gProjectionMatrix;
|
||||||
|
mat4 gViewMatrix;
|
||||||
|
mat4 gModelMatrix;
|
||||||
|
mat4 gNormalMatrix;
|
||||||
|
vec4 gMainLightDirectionAndIntensity;
|
||||||
|
vec4 gMainLightColorAndFlags;
|
||||||
|
};
|
||||||
|
|
||||||
|
out vec2 vTexCoord;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vec4 positionWS = gModelMatrix * vec4(aPosition, 1.0);
|
||||||
|
vec4 positionVS = gViewMatrix * positionWS;
|
||||||
|
gl_Position = gProjectionMatrix * positionVS;
|
||||||
|
vTexCoord = aTexCoord;
|
||||||
|
}
|
||||||
23
engine/assets/builtin/shaders/unlit/unlit.vert.vk.glsl
Normal file
23
engine/assets/builtin/shaders/unlit/unlit.vert.vk.glsl
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
// XC_BUILTIN_UNLIT_VULKAN_VS
|
||||||
|
#version 450
|
||||||
|
layout(location = 0) in vec3 aPosition;
|
||||||
|
layout(location = 1) in vec3 aNormal;
|
||||||
|
layout(location = 2) in vec2 aTexCoord;
|
||||||
|
|
||||||
|
layout(set = 1, binding = 0, std140) uniform PerObjectConstants {
|
||||||
|
mat4 gProjectionMatrix;
|
||||||
|
mat4 gViewMatrix;
|
||||||
|
mat4 gModelMatrix;
|
||||||
|
mat4 gNormalMatrix;
|
||||||
|
vec4 gMainLightDirectionAndIntensity;
|
||||||
|
vec4 gMainLightColorAndFlags;
|
||||||
|
};
|
||||||
|
|
||||||
|
layout(location = 0) out vec2 vTexCoord;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vec4 positionWS = gModelMatrix * vec4(aPosition, 1.0);
|
||||||
|
vec4 positionVS = gViewMatrix * positionWS;
|
||||||
|
gl_Position = gProjectionMatrix * positionVS;
|
||||||
|
vTexCoord = aTexCoord;
|
||||||
|
}
|
||||||
29
engine/assets/builtin/shaders/unlit/unlit.vs.hlsl
Normal file
29
engine/assets/builtin/shaders/unlit/unlit.vs.hlsl
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
// XC_BUILTIN_UNLIT_D3D12_VS
|
||||||
|
cbuffer PerObjectConstants : register(b1) {
|
||||||
|
float4x4 gProjectionMatrix;
|
||||||
|
float4x4 gViewMatrix;
|
||||||
|
float4x4 gModelMatrix;
|
||||||
|
float4x4 gNormalMatrix;
|
||||||
|
float4 gMainLightDirectionAndIntensity;
|
||||||
|
float4 gMainLightColorAndFlags;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct VSInput {
|
||||||
|
float3 position : POSITION;
|
||||||
|
float3 normal : NORMAL;
|
||||||
|
float2 texcoord : TEXCOORD0;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PSInput {
|
||||||
|
float4 position : SV_POSITION;
|
||||||
|
float2 texcoord : TEXCOORD0;
|
||||||
|
};
|
||||||
|
|
||||||
|
PSInput MainVS(VSInput input) {
|
||||||
|
PSInput output;
|
||||||
|
float4 positionWS = mul(gModelMatrix, float4(input.position, 1.0f));
|
||||||
|
float4 positionVS = mul(gViewMatrix, positionWS);
|
||||||
|
output.position = mul(gProjectionMatrix, positionVS);
|
||||||
|
output.texcoord = input.texcoord;
|
||||||
|
return output;
|
||||||
|
}
|
||||||
@@ -180,7 +180,7 @@ private:
|
|||||||
bool EnsureInitialized(const RenderContext& context);
|
bool EnsureInitialized(const RenderContext& context);
|
||||||
bool CreatePipelineResources(const RenderContext& context);
|
bool CreatePipelineResources(const RenderContext& context);
|
||||||
void DestroyPipelineResources();
|
void DestroyPipelineResources();
|
||||||
ResolvedShaderPass ResolveForwardShaderPass(const Resources::Material* material) const;
|
ResolvedShaderPass ResolveSurfaceShaderPass(const Resources::Material* material) const;
|
||||||
PassResourceLayout* GetOrCreatePassResourceLayout(
|
PassResourceLayout* GetOrCreatePassResourceLayout(
|
||||||
const RenderContext& context,
|
const RenderContext& context,
|
||||||
const ResolvedShaderPass& resolvedShaderPass);
|
const ResolvedShaderPass& resolvedShaderPass);
|
||||||
@@ -217,6 +217,7 @@ private:
|
|||||||
RHI::RHIType m_backendType = RHI::RHIType::D3D12;
|
RHI::RHIType m_backendType = RHI::RHIType::D3D12;
|
||||||
bool m_initialized = false;
|
bool m_initialized = false;
|
||||||
Resources::ResourceHandle<Resources::Shader> m_builtinForwardShader;
|
Resources::ResourceHandle<Resources::Shader> m_builtinForwardShader;
|
||||||
|
Resources::ResourceHandle<Resources::Shader> m_builtinUnlitShader;
|
||||||
|
|
||||||
RenderResourceCache m_resourceCache;
|
RenderResourceCache m_resourceCache;
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ const char* GetBuiltinPrimitiveDisplayName(BuiltinPrimitiveType primitiveType);
|
|||||||
Containers::String GetBuiltinPrimitiveMeshPath(BuiltinPrimitiveType primitiveType);
|
Containers::String GetBuiltinPrimitiveMeshPath(BuiltinPrimitiveType primitiveType);
|
||||||
Containers::String GetBuiltinDefaultPrimitiveMaterialPath();
|
Containers::String GetBuiltinDefaultPrimitiveMaterialPath();
|
||||||
Containers::String GetBuiltinForwardLitShaderPath();
|
Containers::String GetBuiltinForwardLitShaderPath();
|
||||||
|
Containers::String GetBuiltinUnlitShaderPath();
|
||||||
Containers::String GetBuiltinObjectIdShaderPath();
|
Containers::String GetBuiltinObjectIdShaderPath();
|
||||||
Containers::String GetBuiltinDefaultPrimitiveTexturePath();
|
Containers::String GetBuiltinDefaultPrimitiveTexturePath();
|
||||||
|
|
||||||
|
|||||||
@@ -118,9 +118,26 @@ bool BindingNumberExists(
|
|||||||
return false;
|
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::Shader& shader,
|
||||||
const Resources::Material* material,
|
const Resources::Material* material,
|
||||||
|
BuiltinMaterialPass pass,
|
||||||
Resources::ShaderBackend backend) {
|
Resources::ShaderBackend backend) {
|
||||||
if (material != nullptr && !material->GetShaderPass().Empty()) {
|
if (material != nullptr && !material->GetShaderPass().Empty()) {
|
||||||
const Resources::ShaderPass* explicitPass = shader.FindPass(material->GetShaderPass());
|
const Resources::ShaderPass* explicitPass = shader.FindPass(material->GetShaderPass());
|
||||||
@@ -131,12 +148,16 @@ const Resources::ShaderPass* FindForwardCompatiblePass(
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (const Resources::ShaderPass& shaderPass : shader.GetPasses()) {
|
for (const Resources::ShaderPass& shaderPass : shader.GetPasses()) {
|
||||||
if (ShaderPassMatchesBuiltinPass(shaderPass, BuiltinMaterialPass::ForwardLit) &&
|
if (ShaderPassMatchesBuiltinPass(shaderPass, pass) &&
|
||||||
::XCEngine::Rendering::Detail::ShaderPassHasGraphicsVariants(shader, shaderPass.name, backend)) {
|
::XCEngine::Rendering::Detail::ShaderPassHasGraphicsVariants(shader, shaderPass.name, backend)) {
|
||||||
return &shaderPass;
|
return &shaderPass;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pass != BuiltinMaterialPass::ForwardLit) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
const Resources::ShaderPass* defaultPass = shader.FindPass("ForwardLit");
|
const Resources::ShaderPass* defaultPass = shader.FindPass("ForwardLit");
|
||||||
if (defaultPass != nullptr &&
|
if (defaultPass != nullptr &&
|
||||||
::XCEngine::Rendering::Detail::ShaderPassHasGraphicsVariants(shader, defaultPass->name, backend)) {
|
::XCEngine::Rendering::Detail::ShaderPassHasGraphicsVariants(shader, defaultPass->name, backend)) {
|
||||||
@@ -331,7 +352,8 @@ bool BuiltinForwardPipeline::ExecuteForwardOpaquePass(const RenderPassContext& p
|
|||||||
RHI::RHIPipelineState* currentPipelineState = nullptr;
|
RHI::RHIPipelineState* currentPipelineState = nullptr;
|
||||||
for (const VisibleRenderItem& visibleItem : sceneData.visibleItems) {
|
for (const VisibleRenderItem& visibleItem : sceneData.visibleItems) {
|
||||||
const Resources::Material* material = ResolveMaterial(visibleItem);
|
const Resources::Material* material = ResolveMaterial(visibleItem);
|
||||||
if (!MatchesBuiltinPass(material, BuiltinMaterialPass::ForwardLit)) {
|
BuiltinMaterialPass pass = BuiltinMaterialPass::ForwardLit;
|
||||||
|
if (!TryResolveSurfacePassType(material, pass)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -389,6 +411,15 @@ bool BuiltinForwardPipeline::CreatePipelineResources(const RenderContext& contex
|
|||||||
return false;
|
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 = {};
|
RHI::SamplerDesc samplerDesc = {};
|
||||||
samplerDesc.filter = static_cast<uint32_t>(RHI::FilterMode::Linear);
|
samplerDesc.filter = static_cast<uint32_t>(RHI::FilterMode::Linear);
|
||||||
samplerDesc.addressU = static_cast<uint32_t>(RHI::TextureAddressMode::Clamp);
|
samplerDesc.addressU = static_cast<uint32_t>(RHI::TextureAddressMode::Clamp);
|
||||||
@@ -475,17 +506,23 @@ void BuiltinForwardPipeline::DestroyPipelineResources() {
|
|||||||
m_device = nullptr;
|
m_device = nullptr;
|
||||||
m_initialized = false;
|
m_initialized = false;
|
||||||
m_builtinForwardShader.Reset();
|
m_builtinForwardShader.Reset();
|
||||||
|
m_builtinUnlitShader.Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
BuiltinForwardPipeline::ResolvedShaderPass BuiltinForwardPipeline::ResolveForwardShaderPass(
|
BuiltinForwardPipeline::ResolvedShaderPass BuiltinForwardPipeline::ResolveSurfaceShaderPass(
|
||||||
const Resources::Material* material) const {
|
const Resources::Material* material) const {
|
||||||
ResolvedShaderPass resolved = {};
|
ResolvedShaderPass resolved = {};
|
||||||
|
BuiltinMaterialPass pass = BuiltinMaterialPass::ForwardLit;
|
||||||
|
if (!TryResolveSurfacePassType(material, pass)) {
|
||||||
|
return resolved;
|
||||||
|
}
|
||||||
|
|
||||||
const Resources::ShaderBackend backend = ::XCEngine::Rendering::Detail::ToShaderBackend(m_backendType);
|
const Resources::ShaderBackend backend = ::XCEngine::Rendering::Detail::ToShaderBackend(m_backendType);
|
||||||
|
|
||||||
if (material != nullptr && material->GetShader() != nullptr) {
|
if (material != nullptr && material->GetShader() != nullptr) {
|
||||||
const Resources::Shader* materialShader = material->GetShader();
|
const Resources::Shader* materialShader = material->GetShader();
|
||||||
if (const Resources::ShaderPass* shaderPass =
|
if (const Resources::ShaderPass* shaderPass =
|
||||||
FindForwardCompatiblePass(*materialShader, material, backend)) {
|
FindCompatibleSurfacePass(*materialShader, material, pass, backend)) {
|
||||||
resolved.shader = materialShader;
|
resolved.shader = materialShader;
|
||||||
resolved.pass = shaderPass;
|
resolved.pass = shaderPass;
|
||||||
resolved.passName = shaderPass->name;
|
resolved.passName = shaderPass->name;
|
||||||
@@ -493,10 +530,12 @@ BuiltinForwardPipeline::ResolvedShaderPass BuiltinForwardPipeline::ResolveForwar
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_builtinForwardShader.IsValid()) {
|
const Resources::ResourceHandle<Resources::Shader>* builtinShaderHandle =
|
||||||
const Resources::Shader* builtinShader = m_builtinForwardShader.Get();
|
pass == BuiltinMaterialPass::Unlit ? &m_builtinUnlitShader : &m_builtinForwardShader;
|
||||||
|
if (builtinShaderHandle->IsValid()) {
|
||||||
|
const Resources::Shader* builtinShader = builtinShaderHandle->Get();
|
||||||
if (const Resources::ShaderPass* shaderPass =
|
if (const Resources::ShaderPass* shaderPass =
|
||||||
FindForwardCompatiblePass(*builtinShader, nullptr, backend)) {
|
FindCompatibleSurfacePass(*builtinShader, nullptr, pass, backend)) {
|
||||||
resolved.shader = builtinShader;
|
resolved.shader = builtinShader;
|
||||||
resolved.pass = shaderPass;
|
resolved.pass = shaderPass;
|
||||||
resolved.passName = shaderPass->name;
|
resolved.passName = shaderPass->name;
|
||||||
@@ -672,11 +711,11 @@ BuiltinForwardPipeline::PassResourceLayout* BuiltinForwardPipeline::GetOrCreateP
|
|||||||
RHI::RHIPipelineState* BuiltinForwardPipeline::GetOrCreatePipelineState(
|
RHI::RHIPipelineState* BuiltinForwardPipeline::GetOrCreatePipelineState(
|
||||||
const RenderContext& context,
|
const RenderContext& context,
|
||||||
const Resources::Material* material) {
|
const Resources::Material* material) {
|
||||||
const ResolvedShaderPass resolvedShaderPass = ResolveForwardShaderPass(material);
|
const ResolvedShaderPass resolvedShaderPass = ResolveSurfaceShaderPass(material);
|
||||||
if (resolvedShaderPass.shader == nullptr || resolvedShaderPass.pass == nullptr) {
|
if (resolvedShaderPass.shader == nullptr || resolvedShaderPass.pass == nullptr) {
|
||||||
Debug::Logger::Get().Error(
|
Debug::Logger::Get().Error(
|
||||||
Debug::LogCategory::Rendering,
|
Debug::LogCategory::Rendering,
|
||||||
"BuiltinForwardPipeline could not resolve a valid ForwardLit shader pass");
|
"BuiltinForwardPipeline could not resolve a valid surface shader pass");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -919,7 +958,7 @@ bool BuiltinForwardPipeline::DrawVisibleItem(
|
|||||||
};
|
};
|
||||||
|
|
||||||
const Resources::Material* material = ResolveMaterial(visibleItem);
|
const Resources::Material* material = ResolveMaterial(visibleItem);
|
||||||
const ResolvedShaderPass resolvedShaderPass = ResolveForwardShaderPass(material);
|
const ResolvedShaderPass resolvedShaderPass = ResolveSurfaceShaderPass(material);
|
||||||
if (resolvedShaderPass.shader == nullptr || resolvedShaderPass.pass == nullptr) {
|
if (resolvedShaderPass.shader == nullptr || resolvedShaderPass.pass == nullptr) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ constexpr const char* kBuiltinShaderPrefix = "builtin://shaders/";
|
|||||||
constexpr const char* kBuiltinTexturePrefix = "builtin://textures/";
|
constexpr const char* kBuiltinTexturePrefix = "builtin://textures/";
|
||||||
constexpr const char* kBuiltinDefaultPrimitiveMaterialPath = "builtin://materials/default-primitive";
|
constexpr const char* kBuiltinDefaultPrimitiveMaterialPath = "builtin://materials/default-primitive";
|
||||||
constexpr const char* kBuiltinForwardLitShaderPath = "builtin://shaders/forward-lit";
|
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* kBuiltinObjectIdShaderPath = "builtin://shaders/object-id";
|
||||||
constexpr const char* kBuiltinDefaultPrimitiveTexturePath = "builtin://textures/default-primitive-albedo";
|
constexpr const char* kBuiltinDefaultPrimitiveTexturePath = "builtin://textures/default-primitive-albedo";
|
||||||
constexpr float kPi = 3.14159265358979323846f;
|
constexpr float kPi = 3.14159265358979323846f;
|
||||||
@@ -41,6 +42,8 @@ size_t CalculateBuiltinShaderMemorySize(const Shader& shader);
|
|||||||
|
|
||||||
constexpr const char* kBuiltinForwardLitShaderManifestRelativePath =
|
constexpr const char* kBuiltinForwardLitShaderManifestRelativePath =
|
||||||
"engine/assets/builtin/shaders/forward-lit/forward-lit.shader";
|
"engine/assets/builtin/shaders/forward-lit/forward-lit.shader";
|
||||||
|
constexpr const char* kBuiltinUnlitShaderManifestRelativePath =
|
||||||
|
"engine/assets/builtin/shaders/unlit/unlit.shader";
|
||||||
constexpr const char* kBuiltinObjectIdShaderManifestRelativePath =
|
constexpr const char* kBuiltinObjectIdShaderManifestRelativePath =
|
||||||
"engine/assets/builtin/shaders/object-id/object-id.shader";
|
"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)) {
|
if (builtinShaderPath == Containers::String(kBuiltinForwardLitShaderPath)) {
|
||||||
return kBuiltinForwardLitShaderManifestRelativePath;
|
return kBuiltinForwardLitShaderManifestRelativePath;
|
||||||
}
|
}
|
||||||
|
if (builtinShaderPath == Containers::String(kBuiltinUnlitShaderPath)) {
|
||||||
|
return kBuiltinUnlitShaderManifestRelativePath;
|
||||||
|
}
|
||||||
if (builtinShaderPath == Containers::String(kBuiltinObjectIdShaderPath)) {
|
if (builtinShaderPath == Containers::String(kBuiltinObjectIdShaderPath)) {
|
||||||
return kBuiltinObjectIdShaderManifestRelativePath;
|
return kBuiltinObjectIdShaderManifestRelativePath;
|
||||||
}
|
}
|
||||||
@@ -636,6 +642,10 @@ Shader* BuildBuiltinForwardLitShader(const Containers::String& path) {
|
|||||||
return TryLoadBuiltinShaderFromManifest(path);
|
return TryLoadBuiltinShaderFromManifest(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Shader* BuildBuiltinUnlitShader(const Containers::String& path) {
|
||||||
|
return TryLoadBuiltinShaderFromManifest(path);
|
||||||
|
}
|
||||||
|
|
||||||
Shader* BuildBuiltinObjectIdShader(const Containers::String& path) {
|
Shader* BuildBuiltinObjectIdShader(const Containers::String& path) {
|
||||||
return TryLoadBuiltinShaderFromManifest(path);
|
return TryLoadBuiltinShaderFromManifest(path);
|
||||||
}
|
}
|
||||||
@@ -742,6 +752,10 @@ Containers::String GetBuiltinForwardLitShaderPath() {
|
|||||||
return Containers::String(kBuiltinForwardLitShaderPath);
|
return Containers::String(kBuiltinForwardLitShaderPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Containers::String GetBuiltinUnlitShaderPath() {
|
||||||
|
return Containers::String(kBuiltinUnlitShaderPath);
|
||||||
|
}
|
||||||
|
|
||||||
Containers::String GetBuiltinObjectIdShaderPath() {
|
Containers::String GetBuiltinObjectIdShaderPath() {
|
||||||
return Containers::String(kBuiltinObjectIdShaderPath);
|
return Containers::String(kBuiltinObjectIdShaderPath);
|
||||||
}
|
}
|
||||||
@@ -836,6 +850,8 @@ LoadResult CreateBuiltinShaderResource(const Containers::String& path) {
|
|||||||
Shader* shader = nullptr;
|
Shader* shader = nullptr;
|
||||||
if (path == GetBuiltinForwardLitShaderPath()) {
|
if (path == GetBuiltinForwardLitShaderPath()) {
|
||||||
shader = BuildBuiltinForwardLitShader(path);
|
shader = BuildBuiltinForwardLitShader(path);
|
||||||
|
} else if (path == GetBuiltinUnlitShaderPath()) {
|
||||||
|
shader = BuildBuiltinUnlitShader(path);
|
||||||
} else if (path == GetBuiltinObjectIdShaderPath()) {
|
} else if (path == GetBuiltinObjectIdShaderPath()) {
|
||||||
shader = BuildBuiltinObjectIdShader(path);
|
shader = BuildBuiltinObjectIdShader(path);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -78,6 +78,42 @@ TEST(BuiltinForwardPipeline_Test, BuiltinForwardShaderDeclaresExplicitForwardRes
|
|||||||
delete shader;
|
delete shader;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(BuiltinForwardPipeline_Test, BuiltinUnlitShaderDeclaresExplicitSurfaceResourceContract) {
|
||||||
|
ShaderLoader loader;
|
||||||
|
LoadResult result = loader.Load(GetBuiltinUnlitShaderPath());
|
||||||
|
ASSERT_TRUE(result);
|
||||||
|
ASSERT_NE(result.resource, nullptr);
|
||||||
|
|
||||||
|
Shader* shader = static_cast<Shader*>(result.resource);
|
||||||
|
ASSERT_NE(shader, nullptr);
|
||||||
|
|
||||||
|
const ShaderPass* pass = shader->FindPass("Unlit");
|
||||||
|
ASSERT_NE(pass, nullptr);
|
||||||
|
ASSERT_EQ(pass->resources.Size(), 4u);
|
||||||
|
|
||||||
|
EXPECT_EQ(pass->resources[0].semantic, "PerObject");
|
||||||
|
EXPECT_EQ(pass->resources[0].type, ShaderResourceType::ConstantBuffer);
|
||||||
|
EXPECT_EQ(pass->resources[0].set, 1u);
|
||||||
|
EXPECT_EQ(pass->resources[0].binding, 0u);
|
||||||
|
|
||||||
|
EXPECT_EQ(pass->resources[1].semantic, "Material");
|
||||||
|
EXPECT_EQ(pass->resources[1].type, ShaderResourceType::ConstantBuffer);
|
||||||
|
EXPECT_EQ(pass->resources[1].set, 2u);
|
||||||
|
EXPECT_EQ(pass->resources[1].binding, 0u);
|
||||||
|
|
||||||
|
EXPECT_EQ(pass->resources[2].semantic, "BaseColorTexture");
|
||||||
|
EXPECT_EQ(pass->resources[2].type, ShaderResourceType::Texture2D);
|
||||||
|
EXPECT_EQ(pass->resources[2].set, 3u);
|
||||||
|
EXPECT_EQ(pass->resources[2].binding, 0u);
|
||||||
|
|
||||||
|
EXPECT_EQ(pass->resources[3].semantic, "LinearClampSampler");
|
||||||
|
EXPECT_EQ(pass->resources[3].type, ShaderResourceType::Sampler);
|
||||||
|
EXPECT_EQ(pass->resources[3].set, 4u);
|
||||||
|
EXPECT_EQ(pass->resources[3].binding, 0u);
|
||||||
|
|
||||||
|
delete shader;
|
||||||
|
}
|
||||||
|
|
||||||
TEST(BuiltinForwardPipeline_Test, BuildsBuiltinPassResourceBindingPlanFromExplicitForwardResources) {
|
TEST(BuiltinForwardPipeline_Test, BuildsBuiltinPassResourceBindingPlanFromExplicitForwardResources) {
|
||||||
ShaderLoader loader;
|
ShaderLoader loader;
|
||||||
LoadResult result = loader.Load(GetBuiltinForwardLitShaderPath());
|
LoadResult result = loader.Load(GetBuiltinForwardLitShaderPath());
|
||||||
@@ -106,6 +142,34 @@ TEST(BuiltinForwardPipeline_Test, BuildsBuiltinPassResourceBindingPlanFromExplic
|
|||||||
delete shader;
|
delete shader;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(BuiltinForwardPipeline_Test, BuildsBuiltinPassResourceBindingPlanFromExplicitUnlitResources) {
|
||||||
|
ShaderLoader loader;
|
||||||
|
LoadResult result = loader.Load(GetBuiltinUnlitShaderPath());
|
||||||
|
ASSERT_TRUE(result);
|
||||||
|
ASSERT_NE(result.resource, nullptr);
|
||||||
|
|
||||||
|
Shader* shader = static_cast<Shader*>(result.resource);
|
||||||
|
ASSERT_NE(shader, nullptr);
|
||||||
|
|
||||||
|
const ShaderPass* pass = shader->FindPass("Unlit");
|
||||||
|
ASSERT_NE(pass, nullptr);
|
||||||
|
|
||||||
|
BuiltinPassResourceBindingPlan plan = {};
|
||||||
|
String error;
|
||||||
|
EXPECT_TRUE(TryBuildBuiltinPassResourceBindingPlan(pass->resources, plan, &error)) << error.CStr();
|
||||||
|
EXPECT_TRUE(plan.perObject.IsValid());
|
||||||
|
EXPECT_TRUE(plan.material.IsValid());
|
||||||
|
EXPECT_TRUE(plan.baseColorTexture.IsValid());
|
||||||
|
EXPECT_TRUE(plan.linearClampSampler.IsValid());
|
||||||
|
EXPECT_EQ(plan.firstDescriptorSet, 1u);
|
||||||
|
EXPECT_EQ(plan.descriptorSetCount, 4u);
|
||||||
|
EXPECT_TRUE(plan.usesConstantBuffers);
|
||||||
|
EXPECT_TRUE(plan.usesTextures);
|
||||||
|
EXPECT_TRUE(plan.usesSamplers);
|
||||||
|
|
||||||
|
delete shader;
|
||||||
|
}
|
||||||
|
|
||||||
TEST(BuiltinForwardPipeline_Test, BuildsBuiltinPassResourceBindingPlanFromLegacyFallbackResources) {
|
TEST(BuiltinForwardPipeline_Test, BuildsBuiltinPassResourceBindingPlanFromLegacyFallbackResources) {
|
||||||
const Array<ShaderResourceBindingDesc> bindings = BuildLegacyBuiltinForwardPassResourceBindings();
|
const Array<ShaderResourceBindingDesc> bindings = BuildLegacyBuiltinForwardPassResourceBindings();
|
||||||
ASSERT_EQ(bindings.Size(), 4u);
|
ASSERT_EQ(bindings.Size(), 4u);
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ TEST(ShaderLoader, CanLoad) {
|
|||||||
EXPECT_TRUE(loader.CanLoad("test.hlsl"));
|
EXPECT_TRUE(loader.CanLoad("test.hlsl"));
|
||||||
EXPECT_TRUE(loader.CanLoad("test.xcshader"));
|
EXPECT_TRUE(loader.CanLoad("test.xcshader"));
|
||||||
EXPECT_TRUE(loader.CanLoad(GetBuiltinForwardLitShaderPath()));
|
EXPECT_TRUE(loader.CanLoad(GetBuiltinForwardLitShaderPath()));
|
||||||
|
EXPECT_TRUE(loader.CanLoad(GetBuiltinUnlitShaderPath()));
|
||||||
EXPECT_TRUE(loader.CanLoad(GetBuiltinObjectIdShaderPath()));
|
EXPECT_TRUE(loader.CanLoad(GetBuiltinObjectIdShaderPath()));
|
||||||
EXPECT_FALSE(loader.CanLoad("test.txt"));
|
EXPECT_FALSE(loader.CanLoad("test.txt"));
|
||||||
EXPECT_FALSE(loader.CanLoad("test.png"));
|
EXPECT_FALSE(loader.CanLoad("test.png"));
|
||||||
@@ -495,6 +496,74 @@ TEST(ShaderLoader, LoadBuiltinForwardLitShaderBuildsBackendVariants) {
|
|||||||
delete shader;
|
delete shader;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(ShaderLoader, LoadBuiltinUnlitShaderBuildsBackendVariants) {
|
||||||
|
ShaderLoader loader;
|
||||||
|
LoadResult result = loader.Load(GetBuiltinUnlitShaderPath());
|
||||||
|
ASSERT_TRUE(result);
|
||||||
|
ASSERT_NE(result.resource, nullptr);
|
||||||
|
|
||||||
|
Shader* shader = static_cast<Shader*>(result.resource);
|
||||||
|
ASSERT_NE(shader, nullptr);
|
||||||
|
ASSERT_TRUE(shader->IsValid());
|
||||||
|
|
||||||
|
const ShaderPass* pass = shader->FindPass("Unlit");
|
||||||
|
ASSERT_NE(pass, nullptr);
|
||||||
|
ASSERT_EQ(shader->GetProperties().Size(), 2u);
|
||||||
|
ASSERT_EQ(pass->variants.Size(), 6u);
|
||||||
|
ASSERT_EQ(pass->tags.Size(), 1u);
|
||||||
|
ASSERT_EQ(pass->resources.Size(), 4u);
|
||||||
|
EXPECT_EQ(pass->tags[0].name, "LightMode");
|
||||||
|
EXPECT_EQ(pass->tags[0].value, "Unlit");
|
||||||
|
|
||||||
|
const ShaderPropertyDesc* baseColorProperty = shader->FindProperty("_BaseColor");
|
||||||
|
ASSERT_NE(baseColorProperty, nullptr);
|
||||||
|
EXPECT_EQ(baseColorProperty->type, ShaderPropertyType::Color);
|
||||||
|
EXPECT_EQ(baseColorProperty->semantic, "BaseColor");
|
||||||
|
|
||||||
|
const ShaderPropertyDesc* baseMapProperty = shader->FindProperty("_MainTex");
|
||||||
|
ASSERT_NE(baseMapProperty, nullptr);
|
||||||
|
EXPECT_EQ(baseMapProperty->type, ShaderPropertyType::Texture2D);
|
||||||
|
EXPECT_EQ(baseMapProperty->semantic, "BaseColorTexture");
|
||||||
|
|
||||||
|
const ShaderResourceBindingDesc* perObjectBinding =
|
||||||
|
shader->FindPassResourceBinding("Unlit", "PerObjectConstants");
|
||||||
|
ASSERT_NE(perObjectBinding, nullptr);
|
||||||
|
EXPECT_EQ(perObjectBinding->type, ShaderResourceType::ConstantBuffer);
|
||||||
|
EXPECT_EQ(perObjectBinding->set, 1u);
|
||||||
|
EXPECT_EQ(perObjectBinding->binding, 0u);
|
||||||
|
EXPECT_EQ(perObjectBinding->semantic, "PerObject");
|
||||||
|
|
||||||
|
EXPECT_NE(shader->FindVariant("Unlit", ShaderType::Vertex, ShaderBackend::D3D12), nullptr);
|
||||||
|
EXPECT_NE(shader->FindVariant("Unlit", ShaderType::Fragment, ShaderBackend::D3D12), nullptr);
|
||||||
|
EXPECT_NE(shader->FindVariant("Unlit", ShaderType::Vertex, ShaderBackend::OpenGL), nullptr);
|
||||||
|
EXPECT_NE(shader->FindVariant("Unlit", ShaderType::Fragment, ShaderBackend::OpenGL), nullptr);
|
||||||
|
EXPECT_NE(shader->FindVariant("Unlit", ShaderType::Vertex, ShaderBackend::Vulkan), nullptr);
|
||||||
|
EXPECT_NE(shader->FindVariant("Unlit", ShaderType::Fragment, ShaderBackend::Vulkan), nullptr);
|
||||||
|
|
||||||
|
const ShaderStageVariant* d3d12Vertex = shader->FindVariant(
|
||||||
|
"Unlit",
|
||||||
|
ShaderType::Vertex,
|
||||||
|
ShaderBackend::D3D12);
|
||||||
|
ASSERT_NE(d3d12Vertex, nullptr);
|
||||||
|
EXPECT_NE(std::string(d3d12Vertex->sourceCode.CStr()).find("XC_BUILTIN_UNLIT_D3D12_VS"), std::string::npos);
|
||||||
|
|
||||||
|
const ShaderStageVariant* openglFragment = shader->FindVariant(
|
||||||
|
"Unlit",
|
||||||
|
ShaderType::Fragment,
|
||||||
|
ShaderBackend::OpenGL);
|
||||||
|
ASSERT_NE(openglFragment, nullptr);
|
||||||
|
EXPECT_NE(std::string(openglFragment->sourceCode.CStr()).find("XC_BUILTIN_UNLIT_OPENGL_PS"), std::string::npos);
|
||||||
|
|
||||||
|
const ShaderStageVariant* vulkanFragment = shader->FindVariant(
|
||||||
|
"Unlit",
|
||||||
|
ShaderType::Fragment,
|
||||||
|
ShaderBackend::Vulkan);
|
||||||
|
ASSERT_NE(vulkanFragment, nullptr);
|
||||||
|
EXPECT_NE(std::string(vulkanFragment->sourceCode.CStr()).find("XC_BUILTIN_UNLIT_VULKAN_PS"), std::string::npos);
|
||||||
|
|
||||||
|
delete shader;
|
||||||
|
}
|
||||||
|
|
||||||
TEST(ShaderLoader, LoadBuiltinObjectIdShaderBuildsBackendVariants) {
|
TEST(ShaderLoader, LoadBuiltinObjectIdShaderBuildsBackendVariants) {
|
||||||
ShaderLoader loader;
|
ShaderLoader loader;
|
||||||
LoadResult result = loader.Load(GetBuiltinObjectIdShaderPath());
|
LoadResult result = loader.Load(GetBuiltinObjectIdShaderPath());
|
||||||
@@ -557,6 +626,10 @@ TEST(ShaderLoader, ResourceManagerLazilyLoadsBuiltinForwardLitShader) {
|
|||||||
ASSERT_TRUE(shaderHandle.IsValid());
|
ASSERT_TRUE(shaderHandle.IsValid());
|
||||||
ASSERT_NE(shaderHandle->FindPass("ForwardLit"), nullptr);
|
ASSERT_NE(shaderHandle->FindPass("ForwardLit"), nullptr);
|
||||||
|
|
||||||
|
ResourceHandle<Shader> unlitShaderHandle = manager.Load<Shader>(GetBuiltinUnlitShaderPath());
|
||||||
|
ASSERT_TRUE(unlitShaderHandle.IsValid());
|
||||||
|
ASSERT_NE(unlitShaderHandle->FindPass("Unlit"), nullptr);
|
||||||
|
|
||||||
ResourceHandle<Shader> objectIdShaderHandle = manager.Load<Shader>(GetBuiltinObjectIdShaderPath());
|
ResourceHandle<Shader> objectIdShaderHandle = manager.Load<Shader>(GetBuiltinObjectIdShaderPath());
|
||||||
ASSERT_TRUE(objectIdShaderHandle.IsValid());
|
ASSERT_TRUE(objectIdShaderHandle.IsValid());
|
||||||
ASSERT_NE(objectIdShaderHandle->FindPass("ObjectId"), nullptr);
|
ASSERT_NE(objectIdShaderHandle->FindPass("ObjectId"), nullptr);
|
||||||
@@ -604,6 +677,12 @@ TEST(ShaderLoader, ResourceManagerLoadsBuiltinShadersOutsideProjectWorkingDirect
|
|||||||
ShaderType::Vertex,
|
ShaderType::Vertex,
|
||||||
ShaderBackend::D3D12,
|
ShaderBackend::D3D12,
|
||||||
"XC_BUILTIN_FORWARD_LIT_D3D12_VS");
|
"XC_BUILTIN_FORWARD_LIT_D3D12_VS");
|
||||||
|
expectBuiltinShader(
|
||||||
|
GetBuiltinUnlitShaderPath(),
|
||||||
|
"Unlit",
|
||||||
|
ShaderType::Fragment,
|
||||||
|
ShaderBackend::OpenGL,
|
||||||
|
"XC_BUILTIN_UNLIT_OPENGL_PS");
|
||||||
expectBuiltinShader(
|
expectBuiltinShader(
|
||||||
GetBuiltinObjectIdShaderPath(),
|
GetBuiltinObjectIdShaderPath(),
|
||||||
"ObjectId",
|
"ObjectId",
|
||||||
|
|||||||
Reference in New Issue
Block a user