refactor: remove builtin shader source fallbacks

This commit is contained in:
2026-04-02 23:31:03 +08:00
parent 1c8c28e32b
commit ca019157be

View File

@@ -164,529 +164,6 @@ Shader* TryLoadBuiltinShaderFromManifest(const Containers::String& builtinPath)
return LoadBuiltinShaderFromManifest(builtinPath, manifestPath);
}
const char kBuiltinForwardHlsl[] = R"(
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 VSInput {
float3 position : POSITION;
float3 normal : NORMAL;
float2 texcoord : TEXCOORD0;
};
struct PSInput {
float4 position : SV_POSITION;
float3 normalWS : TEXCOORD0;
float2 texcoord : TEXCOORD1;
};
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.normalWS = mul((float3x3)gNormalMatrix, input.normal);
output.texcoord = input.texcoord;
return output;
}
float4 MainPS(PSInput input) : SV_TARGET {
float4 baseColor = gBaseColorTexture.Sample(gLinearSampler, input.texcoord) * gBaseColorFactor;
if (gMainLightColorAndFlags.a < 0.5f) {
return baseColor;
}
float3 normalWS = normalize(input.normalWS);
float3 directionToLightWS = normalize(gMainLightDirectionAndIntensity.xyz);
float diffuse = saturate(dot(normalWS, directionToLightWS));
float3 lighting = float3(0.28f, 0.28f, 0.28f) +
gMainLightColorAndFlags.rgb * (diffuse * gMainLightDirectionAndIntensity.w);
return float4(baseColor.rgb * lighting, baseColor.a);
}
)";
const char kBuiltinForwardVertexShader[] = R"(#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 vec3 vNormalWS;
out vec2 vTexCoord;
void main() {
vec4 positionWS = gModelMatrix * vec4(aPosition, 1.0);
vec4 positionVS = gViewMatrix * positionWS;
gl_Position = gProjectionMatrix * positionVS;
vNormalWS = mat3(gNormalMatrix) * aNormal;
vTexCoord = aTexCoord;
}
)";
const char kBuiltinForwardFragmentShader[] = R"(#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 vec3 vNormalWS;
in vec2 vTexCoord;
layout(location = 0) out vec4 fragColor;
void main() {
vec4 baseColor = texture(uBaseColorTexture, vTexCoord) * gBaseColorFactor;
if (gMainLightColorAndFlags.w < 0.5) {
fragColor = baseColor;
return;
}
vec3 normalWS = normalize(vNormalWS);
vec3 directionToLightWS = normalize(gMainLightDirectionAndIntensity.xyz);
float diffuse = max(dot(normalWS, directionToLightWS), 0.0);
vec3 lighting = vec3(0.28) +
gMainLightColorAndFlags.rgb * (diffuse * gMainLightDirectionAndIntensity.w);
fragColor = vec4(baseColor.rgb * lighting, baseColor.a);
}
)";
const char kBuiltinForwardVulkanVertexShader[] = R"(#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 vec3 vNormalWS;
layout(location = 1) out vec2 vTexCoord;
void main() {
vec4 positionWS = gModelMatrix * vec4(aPosition, 1.0);
vec4 positionVS = gViewMatrix * positionWS;
gl_Position = gProjectionMatrix * positionVS;
vNormalWS = mat3(gNormalMatrix) * aNormal;
vTexCoord = aTexCoord;
}
)";
const char kBuiltinForwardVulkanFragmentShader[] = R"(#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 vec3 vNormalWS;
layout(location = 1) in vec2 vTexCoord;
layout(location = 0) out vec4 fragColor;
void main() {
vec4 baseColor = texture(sampler2D(uBaseColorTexture, uLinearSampler), vTexCoord) * gBaseColorFactor;
if (gMainLightColorAndFlags.w < 0.5) {
fragColor = baseColor;
return;
}
vec3 normalWS = normalize(vNormalWS);
vec3 directionToLightWS = normalize(gMainLightDirectionAndIntensity.xyz);
float diffuse = max(dot(normalWS, directionToLightWS), 0.0);
vec3 lighting = vec3(0.28) +
gMainLightColorAndFlags.rgb * (diffuse * gMainLightDirectionAndIntensity.w);
fragColor = vec4(baseColor.rgb * lighting, baseColor.a);
}
)";
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;
}
)";
const char kBuiltinObjectIdOutlineHlsl[] = R"(
cbuffer OutlineConstants : register(b0) {
float4 gViewportSizeAndTexelSize;
float4 gOutlineColor;
float4 gSelectedInfo;
float4 gSelectedObjectColors[256];
};
Texture2D gObjectIdTexture : register(t0);
struct VSOutput {
float4 position : SV_POSITION;
};
VSOutput MainVS(uint vertexId : SV_VertexID) {
static const float2 positions[3] = {
float2(-1.0, -1.0),
float2(-1.0, 3.0),
float2( 3.0, -1.0)
};
VSOutput output;
output.position = float4(positions[vertexId], 0.0, 1.0);
return output;
}
int2 ClampPixelCoord(int2 pixelCoord) {
const int2 maxCoord = int2(
max((int)gViewportSizeAndTexelSize.x - 1, 0),
max((int)gViewportSizeAndTexelSize.y - 1, 0));
return clamp(pixelCoord, int2(0, 0), maxCoord);
}
float4 LoadObjectId(int2 pixelCoord) {
return gObjectIdTexture.Load(int3(ClampPixelCoord(pixelCoord), 0));
}
bool IsSelectedObject(float4 objectIdColor) {
if (objectIdColor.a <= 0.0) {
return false;
}
const int selectedCount = min((int)gSelectedInfo.x, 256);
[loop]
for (int i = 0; i < selectedCount; ++i) {
const float4 selectedColor = gSelectedObjectColors[i];
if (all(abs(objectIdColor - selectedColor) <= float4(
0.0025,
0.0025,
0.0025,
0.0025))) {
return true;
}
}
return false;
}
float4 MainPS(VSOutput input) : SV_TARGET {
const int2 pixelCoord = int2(input.position.xy);
const bool debugSelectionMask = gSelectedInfo.y > 0.5;
const bool centerSelected = IsSelectedObject(LoadObjectId(pixelCoord));
if (debugSelectionMask) {
return centerSelected ? float4(1.0, 1.0, 1.0, 1.0) : float4(0.0, 0.0, 0.0, 1.0);
}
if (centerSelected) {
discard;
}
const int outlineWidth = max((int)gSelectedInfo.z, 1);
float outline = 0.0;
[loop]
for (int y = -2; y <= 2; ++y) {
[loop]
for (int x = -2; x <= 2; ++x) {
if (x == 0 && y == 0) {
continue;
}
const float distancePixels = length(float2((float)x, (float)y));
if (distancePixels > outlineWidth) {
continue;
}
if (!IsSelectedObject(LoadObjectId(pixelCoord + int2(x, y)))) {
continue;
}
const float weight = saturate(1.0 - ((distancePixels - 1.0) / max((float)outlineWidth, 1.0)));
outline = max(outline, weight);
}
}
if (outline <= 0.001) {
discard;
}
return float4(gOutlineColor.rgb, gOutlineColor.a * outline);
}
)";
const char kBuiltinInfiniteGridHlsl[] = R"(
cbuffer GridConstants : register(b0) {
float4x4 gViewProjectionMatrix;
float4 gCameraPositionAndScale;
float4 gCameraRightAndFade;
float4 gCameraUpAndTanHalfFov;
float4 gCameraForwardAndAspect;
float4 gViewportNearFar;
float4 gGridTransition;
};
struct VSOutput {
float4 position : SV_POSITION;
};
VSOutput MainVS(uint vertexId : SV_VertexID) {
static const float2 positions[3] = {
float2(-1.0, -1.0),
float2(-1.0, 3.0),
float2( 3.0, -1.0)
};
VSOutput output;
output.position = float4(positions[vertexId], 0.0, 1.0);
return output;
}
float PristineGridLine(float2 uv) {
float2 deriv = max(fwidth(uv), float2(1e-6, 1e-6));
float2 uvMod = frac(uv);
float2 uvDist = min(uvMod, 1.0 - uvMod);
float2 distInPixels = uvDist / deriv;
float2 lineAlpha = 1.0 - smoothstep(0.0, 1.0, distInPixels);
float density = max(deriv.x, deriv.y);
float densityFade = 1.0 - smoothstep(0.5, 1.0, density);
return max(lineAlpha.x, lineAlpha.y) * densityFade;
}
float AxisLineAA(float coord, float deriv) {
float distInPixels = abs(coord) / max(deriv, 1e-6);
return 1.0 - smoothstep(0.0, 1.5, distInPixels);
}
struct GridLayer {
float minor;
float major;
};
GridLayer SampleGridLayer(float2 worldPos2D, float baseScale) {
GridLayer layer;
const float2 gridCoord1 = worldPos2D / baseScale;
const float2 gridCoord10 = worldPos2D / (baseScale * 10.0);
const float grid1 = PristineGridLine(gridCoord1);
const float grid10 = PristineGridLine(gridCoord10);
const float2 deriv1 = fwidth(gridCoord1);
const float lodFactor = smoothstep(0.3, 0.6, max(deriv1.x, deriv1.y));
layer.major = max(grid10, grid1 * 0.35);
layer.minor = grid1 * (1.0 - lodFactor);
return layer;
}
struct PSOutput {
float4 color : SV_TARGET0;
float depth : SV_Depth;
};
PSOutput MainPS(VSOutput input) {
const float2 viewportSize = max(gViewportNearFar.xy, float2(1.0, 1.0));
const float scale = max(gCameraPositionAndScale.w, 1e-4);
const float fadeDistance = max(gCameraRightAndFade.w, scale * 10.0);
const float tanHalfFov = max(gCameraUpAndTanHalfFov.w, 1e-4);
const float aspect = max(gCameraForwardAndAspect.w, 1e-4);
const float transitionBlend = saturate(gGridTransition.x);
const float nearClip = gViewportNearFar.z;
const float sceneFarClip = gViewportNearFar.w;
const float2 ndc = float2(
(input.position.x / viewportSize.x) * 2.0 - 1.0,
1.0 - (input.position.y / viewportSize.y) * 2.0);
const float3 cameraPosition = gCameraPositionAndScale.xyz;
const float3 rayDirection = normalize(
gCameraForwardAndAspect.xyz +
ndc.x * aspect * tanHalfFov * gCameraRightAndFade.xyz +
ndc.y * tanHalfFov * gCameraUpAndTanHalfFov.xyz);
if (abs(rayDirection.y) < 1e-5) {
discard;
}
const float t = -cameraPosition.y / rayDirection.y;
if (t <= nearClip) {
discard;
}
const float3 worldPosition = cameraPosition + rayDirection * t;
float depth = 0.999999;
if (t < sceneFarClip) {
const float4 clipPosition = mul(gViewProjectionMatrix, float4(worldPosition, 1.0));
if (clipPosition.w <= 1e-6) {
discard;
}
depth = clipPosition.z / clipPosition.w;
if (depth <= 0.0 || depth >= 1.0) {
discard;
}
}
const float radialFade =
1.0 - smoothstep(fadeDistance * 0.3, fadeDistance, length(worldPosition - cameraPosition));
const float normalFade = smoothstep(0.0, 0.15, abs(rayDirection.y));
const float fadeFactor = radialFade * normalFade;
if (fadeFactor < 1e-3) {
discard;
}
const float2 worldPos2D = worldPosition.xz;
const GridLayer baseLayer = SampleGridLayer(worldPos2D, scale);
const GridLayer nextLayer = SampleGridLayer(worldPos2D, scale * 10.0);
const float minorGridIntensity = lerp(baseLayer.minor, nextLayer.minor, transitionBlend);
const float majorGridIntensity = lerp(baseLayer.major, nextLayer.major, transitionBlend);
float3 finalColor = float3(0.56, 0.56, 0.56);
float finalAlpha = max(
0.13 * minorGridIntensity * fadeFactor,
0.28 * majorGridIntensity * fadeFactor);
const float2 worldDeriv = max(fwidth(worldPos2D), float2(1e-6, 1e-6));
const float xAxisAlpha = AxisLineAA(worldPos2D.y, worldDeriv.y) * fadeFactor;
const float zAxisAlpha = AxisLineAA(worldPos2D.x, worldDeriv.x) * fadeFactor;
const float axisAlpha = max(xAxisAlpha, zAxisAlpha);
finalAlpha = max(finalAlpha, 0.34 * saturate(axisAlpha));
if (finalAlpha < 1e-3) {
discard;
}
PSOutput output;
output.color = float4(finalColor, finalAlpha);
output.depth = depth;
return output;
}
)";
Math::Bounds ComputeBounds(const std::vector<StaticMeshVertex>& vertices) {
if (vertices.empty()) {
return Math::Bounds();
@@ -1138,25 +615,6 @@ Mesh* BuildMeshResource(
return mesh;
}
void AddBuiltinShaderStageVariant(
Shader& shader,
const Containers::String& passName,
ShaderType stage,
ShaderLanguage language,
ShaderBackend backend,
const char* sourceCode,
const char* entryPoint,
const char* profile) {
ShaderStageVariant variant = {};
variant.stage = stage;
variant.language = language;
variant.backend = backend;
variant.sourceCode = Containers::String(sourceCode);
variant.entryPoint = Containers::String(entryPoint);
variant.profile = Containers::String(profile);
shader.AddPassVariant(passName, variant);
}
size_t CalculateBuiltinShaderMemorySize(const Shader& shader) {
size_t memorySize = sizeof(Shader) + shader.GetName().Length() + shader.GetPath().Length();
for (const ShaderPass& pass : shader.GetPasses()) {
@@ -1177,235 +635,19 @@ size_t CalculateBuiltinShaderMemorySize(const Shader& shader) {
}
Shader* BuildBuiltinForwardLitShader(const Containers::String& path) {
if (Shader* shader = TryLoadBuiltinShaderFromManifest(path)) {
return shader;
}
auto* shader = new Shader();
IResource::ConstructParams params;
params.name = Containers::String("Builtin Forward Lit");
params.path = path;
params.guid = ResourceGUID::Generate(path);
params.memorySize = 0;
shader->Initialize(params);
const Containers::String passName("ForwardLit");
shader->SetPassTag(passName, "LightMode", "ForwardBase");
AddBuiltinShaderStageVariant(
*shader,
passName,
ShaderType::Vertex,
ShaderLanguage::HLSL,
ShaderBackend::D3D12,
kBuiltinForwardHlsl,
"MainVS",
"vs_5_0");
AddBuiltinShaderStageVariant(
*shader,
passName,
ShaderType::Fragment,
ShaderLanguage::HLSL,
ShaderBackend::D3D12,
kBuiltinForwardHlsl,
"MainPS",
"ps_5_0");
AddBuiltinShaderStageVariant(
*shader,
passName,
ShaderType::Vertex,
ShaderLanguage::GLSL,
ShaderBackend::OpenGL,
kBuiltinForwardVertexShader,
"main",
"vs_4_30");
AddBuiltinShaderStageVariant(
*shader,
passName,
ShaderType::Fragment,
ShaderLanguage::GLSL,
ShaderBackend::OpenGL,
kBuiltinForwardFragmentShader,
"main",
"fs_4_30");
AddBuiltinShaderStageVariant(
*shader,
passName,
ShaderType::Vertex,
ShaderLanguage::GLSL,
ShaderBackend::Vulkan,
kBuiltinForwardVulkanVertexShader,
"main",
"vs_4_50");
AddBuiltinShaderStageVariant(
*shader,
passName,
ShaderType::Fragment,
ShaderLanguage::GLSL,
ShaderBackend::Vulkan,
kBuiltinForwardVulkanFragmentShader,
"main",
"fs_4_50");
shader->m_memorySize = CalculateBuiltinShaderMemorySize(*shader);
return shader;
return TryLoadBuiltinShaderFromManifest(path);
}
Shader* BuildBuiltinObjectIdShader(const Containers::String& path) {
if (Shader* shader = TryLoadBuiltinShaderFromManifest(path)) {
return shader;
}
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;
return TryLoadBuiltinShaderFromManifest(path);
}
Shader* BuildBuiltinInfiniteGridShader(const Containers::String& path) {
if (Shader* shader = TryLoadBuiltinShaderFromManifest(path)) {
return shader;
}
auto* shader = new Shader();
IResource::ConstructParams params;
params.name = Containers::String("Builtin Infinite Grid");
params.path = path;
params.guid = ResourceGUID::Generate(path);
params.memorySize = 0;
shader->Initialize(params);
const Containers::String passName("InfiniteGrid");
shader->SetPassTag(passName, "LightMode", "InfiniteGrid");
AddBuiltinShaderStageVariant(
*shader,
passName,
ShaderType::Vertex,
ShaderLanguage::HLSL,
ShaderBackend::D3D12,
kBuiltinInfiniteGridHlsl,
"MainVS",
"vs_5_0");
AddBuiltinShaderStageVariant(
*shader,
passName,
ShaderType::Fragment,
ShaderLanguage::HLSL,
ShaderBackend::D3D12,
kBuiltinInfiniteGridHlsl,
"MainPS",
"ps_5_0");
shader->m_memorySize = CalculateBuiltinShaderMemorySize(*shader);
return shader;
return TryLoadBuiltinShaderFromManifest(path);
}
Shader* BuildBuiltinObjectIdOutlineShader(const Containers::String& path) {
if (Shader* shader = TryLoadBuiltinShaderFromManifest(path)) {
return shader;
}
auto* shader = new Shader();
IResource::ConstructParams params;
params.name = Containers::String("Builtin Object Id Outline");
params.path = path;
params.guid = ResourceGUID::Generate(path);
params.memorySize = 0;
shader->Initialize(params);
const Containers::String passName("ObjectIdOutline");
shader->SetPassTag(passName, "LightMode", "ObjectIdOutline");
AddBuiltinShaderStageVariant(
*shader,
passName,
ShaderType::Vertex,
ShaderLanguage::HLSL,
ShaderBackend::D3D12,
kBuiltinObjectIdOutlineHlsl,
"MainVS",
"vs_5_0");
AddBuiltinShaderStageVariant(
*shader,
passName,
ShaderType::Fragment,
ShaderLanguage::HLSL,
ShaderBackend::D3D12,
kBuiltinObjectIdOutlineHlsl,
"MainPS",
"ps_5_0");
shader->m_memorySize = CalculateBuiltinShaderMemorySize(*shader);
return shader;
return TryLoadBuiltinShaderFromManifest(path);
}
Material* BuildDefaultPrimitiveMaterial(const Containers::String& path) {