refactor: route builtin object-id pass through shader assets

This commit is contained in:
2026-04-02 19:17:22 +08:00
parent 9f7d8fd68d
commit 11fb8f3585
8 changed files with 390 additions and 161 deletions

View File

@@ -25,6 +25,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* kBuiltinObjectIdShaderPath = "builtin://shaders/object-id";
constexpr const char* kBuiltinDefaultPrimitiveTexturePath = "builtin://textures/default-primitive-albedo";
constexpr float kPi = 3.14159265358979323846f;
@@ -214,6 +215,99 @@ void main() {
}
)";
const char kBuiltinObjectIdHlsl[] = R"(
cbuffer PerObjectConstants : register(b0) {
float4x4 gProjectionMatrix;
float4x4 gViewMatrix;
float4x4 gModelMatrix;
float4 gObjectIdColor;
};
struct VSInput {
float3 position : POSITION;
};
struct PSInput {
float4 position : SV_POSITION;
};
PSInput MainVS(VSInput input) {
PSInput output;
float4 positionWS = mul(gModelMatrix, float4(input.position, 1.0));
float4 positionVS = mul(gViewMatrix, positionWS);
output.position = mul(gProjectionMatrix, positionVS);
return output;
}
float4 MainPS(PSInput input) : SV_TARGET {
return gObjectIdColor;
}
)";
const char kBuiltinObjectIdVertexShader[] = R"(#version 430
layout(location = 0) in vec3 aPosition;
layout(std140, binding = 0) uniform PerObjectConstants {
mat4 gProjectionMatrix;
mat4 gViewMatrix;
mat4 gModelMatrix;
vec4 gObjectIdColor;
};
void main() {
vec4 positionWS = gModelMatrix * vec4(aPosition, 1.0);
vec4 positionVS = gViewMatrix * positionWS;
gl_Position = gProjectionMatrix * positionVS;
}
)";
const char kBuiltinObjectIdFragmentShader[] = R"(#version 430
layout(std140, binding = 0) uniform PerObjectConstants {
mat4 gProjectionMatrix;
mat4 gViewMatrix;
mat4 gModelMatrix;
vec4 gObjectIdColor;
};
layout(location = 0) out vec4 fragColor;
void main() {
fragColor = gObjectIdColor;
}
)";
const char kBuiltinObjectIdVulkanVertexShader[] = R"(#version 450
layout(location = 0) in vec3 aPosition;
layout(set = 0, binding = 0, std140) uniform PerObjectConstants {
mat4 gProjectionMatrix;
mat4 gViewMatrix;
mat4 gModelMatrix;
vec4 gObjectIdColor;
};
void main() {
vec4 positionWS = gModelMatrix * vec4(aPosition, 1.0);
vec4 positionVS = gViewMatrix * positionWS;
gl_Position = gProjectionMatrix * positionVS;
}
)";
const char kBuiltinObjectIdVulkanFragmentShader[] = R"(#version 450
layout(set = 0, binding = 0, std140) uniform PerObjectConstants {
mat4 gProjectionMatrix;
mat4 gViewMatrix;
mat4 gModelMatrix;
vec4 gObjectIdColor;
};
layout(location = 0) out vec4 fragColor;
void main() {
fragColor = gObjectIdColor;
}
)";
Math::Bounds ComputeBounds(const std::vector<StaticMeshVertex>& vertices) {
if (vertices.empty()) {
return Math::Bounds();
@@ -776,6 +870,79 @@ Shader* BuildBuiltinForwardLitShader(const Containers::String& path) {
return shader;
}
Shader* BuildBuiltinObjectIdShader(const Containers::String& path) {
auto* shader = new Shader();
IResource::ConstructParams params;
params.name = Containers::String("Builtin Object Id");
params.path = path;
params.guid = ResourceGUID::Generate(path);
params.memorySize = 0;
shader->Initialize(params);
const Containers::String passName("ObjectId");
shader->SetPassTag(passName, "LightMode", "ObjectId");
AddBuiltinShaderStageVariant(
*shader,
passName,
ShaderType::Vertex,
ShaderLanguage::HLSL,
ShaderBackend::D3D12,
kBuiltinObjectIdHlsl,
"MainVS",
"vs_5_0");
AddBuiltinShaderStageVariant(
*shader,
passName,
ShaderType::Fragment,
ShaderLanguage::HLSL,
ShaderBackend::D3D12,
kBuiltinObjectIdHlsl,
"MainPS",
"ps_5_0");
AddBuiltinShaderStageVariant(
*shader,
passName,
ShaderType::Vertex,
ShaderLanguage::GLSL,
ShaderBackend::OpenGL,
kBuiltinObjectIdVertexShader,
"main",
"vs_4_30");
AddBuiltinShaderStageVariant(
*shader,
passName,
ShaderType::Fragment,
ShaderLanguage::GLSL,
ShaderBackend::OpenGL,
kBuiltinObjectIdFragmentShader,
"main",
"fs_4_30");
AddBuiltinShaderStageVariant(
*shader,
passName,
ShaderType::Vertex,
ShaderLanguage::GLSL,
ShaderBackend::Vulkan,
kBuiltinObjectIdVulkanVertexShader,
"main",
"vs_4_50");
AddBuiltinShaderStageVariant(
*shader,
passName,
ShaderType::Fragment,
ShaderLanguage::GLSL,
ShaderBackend::Vulkan,
kBuiltinObjectIdVulkanFragmentShader,
"main",
"fs_4_50");
shader->m_memorySize = CalculateBuiltinShaderMemorySize(*shader);
return shader;
}
Material* BuildDefaultPrimitiveMaterial(const Containers::String& path) {
auto* material = new Material();
IResource::ConstructParams params;
@@ -878,6 +1045,10 @@ Containers::String GetBuiltinForwardLitShaderPath() {
return Containers::String(kBuiltinForwardLitShaderPath);
}
Containers::String GetBuiltinObjectIdShaderPath() {
return Containers::String(kBuiltinObjectIdShaderPath);
}
Containers::String GetBuiltinDefaultPrimitiveTexturePath() {
return Containers::String(kBuiltinDefaultPrimitiveTexturePath);
}
@@ -965,11 +1136,15 @@ LoadResult CreateBuiltinMaterialResource(const Containers::String& path) {
}
LoadResult CreateBuiltinShaderResource(const Containers::String& path) {
if (path != GetBuiltinForwardLitShaderPath()) {
Shader* shader = nullptr;
if (path == GetBuiltinForwardLitShaderPath()) {
shader = BuildBuiltinForwardLitShader(path);
} else if (path == GetBuiltinObjectIdShaderPath()) {
shader = BuildBuiltinObjectIdShader(path);
} else {
return LoadResult(Containers::String("Unknown builtin shader: ") + path);
}
Shader* shader = BuildBuiltinForwardLitShader(path);
if (shader == nullptr) {
return LoadResult(Containers::String("Failed to create builtin shader: ") + path);
}