refactor: externalize builtin object id and grid shader assets
This commit is contained in:
@@ -0,0 +1,132 @@
|
||||
// XC_BUILTIN_INFINITE_GRID_D3D12_PS
|
||||
cbuffer GridConstants : register(b0) {
|
||||
float4x4 gViewProjectionMatrix;
|
||||
float4 gCameraPositionAndScale;
|
||||
float4 gCameraRightAndFade;
|
||||
float4 gCameraUpAndTanHalfFov;
|
||||
float4 gCameraForwardAndAspect;
|
||||
float4 gViewportNearFar;
|
||||
float4 gGridTransition;
|
||||
};
|
||||
|
||||
struct VSOutput {
|
||||
float4 position : SV_POSITION;
|
||||
};
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"name": "Builtin Infinite Grid",
|
||||
"passes": [
|
||||
{
|
||||
"name": "InfiniteGrid",
|
||||
"tags": {
|
||||
"LightMode": "InfiniteGrid"
|
||||
},
|
||||
"variants": [
|
||||
{
|
||||
"stage": "Vertex",
|
||||
"backend": "D3D12",
|
||||
"language": "HLSL",
|
||||
"source": "infinite-grid.vs.hlsl",
|
||||
"entryPoint": "MainVS",
|
||||
"profile": "vs_5_0"
|
||||
},
|
||||
{
|
||||
"stage": "Fragment",
|
||||
"backend": "D3D12",
|
||||
"language": "HLSL",
|
||||
"source": "infinite-grid.ps.hlsl",
|
||||
"entryPoint": "MainPS",
|
||||
"profile": "ps_5_0"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
// XC_BUILTIN_INFINITE_GRID_D3D12_VS
|
||||
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;
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
// XC_BUILTIN_OBJECT_ID_OUTLINE_D3D12_PS
|
||||
cbuffer OutlineConstants : register(b0) {
|
||||
float4 gViewportSizeAndTexelSize;
|
||||
float4 gOutlineColor;
|
||||
float4 gSelectedInfo;
|
||||
float4 gSelectedObjectColors[256];
|
||||
};
|
||||
|
||||
Texture2D gObjectIdTexture : register(t0);
|
||||
|
||||
struct VSOutput {
|
||||
float4 position : SV_POSITION;
|
||||
};
|
||||
|
||||
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);
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"name": "Builtin Object Id Outline",
|
||||
"passes": [
|
||||
{
|
||||
"name": "ObjectIdOutline",
|
||||
"tags": {
|
||||
"LightMode": "ObjectIdOutline"
|
||||
},
|
||||
"variants": [
|
||||
{
|
||||
"stage": "Vertex",
|
||||
"backend": "D3D12",
|
||||
"language": "HLSL",
|
||||
"source": "object-id-outline.vs.hlsl",
|
||||
"entryPoint": "MainVS",
|
||||
"profile": "vs_5_0"
|
||||
},
|
||||
{
|
||||
"stage": "Fragment",
|
||||
"backend": "D3D12",
|
||||
"language": "HLSL",
|
||||
"source": "object-id-outline.ps.hlsl",
|
||||
"entryPoint": "MainPS",
|
||||
"profile": "ps_5_0"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
// XC_BUILTIN_OBJECT_ID_OUTLINE_D3D12_VS
|
||||
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;
|
||||
}
|
||||
14
engine/assets/builtin/shaders/object-id/object-id.frag.glsl
Normal file
14
engine/assets/builtin/shaders/object-id/object-id.frag.glsl
Normal file
@@ -0,0 +1,14 @@
|
||||
// XC_BUILTIN_OBJECT_ID_OPENGL_PS
|
||||
#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;
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
// XC_BUILTIN_OBJECT_ID_VULKAN_PS
|
||||
#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;
|
||||
}
|
||||
15
engine/assets/builtin/shaders/object-id/object-id.ps.hlsl
Normal file
15
engine/assets/builtin/shaders/object-id/object-id.ps.hlsl
Normal file
@@ -0,0 +1,15 @@
|
||||
// XC_BUILTIN_OBJECT_ID_D3D12_PS
|
||||
cbuffer PerObjectConstants : register(b0) {
|
||||
float4x4 gProjectionMatrix;
|
||||
float4x4 gViewMatrix;
|
||||
float4x4 gModelMatrix;
|
||||
float4 gObjectIdColor;
|
||||
};
|
||||
|
||||
struct PSInput {
|
||||
float4 position : SV_POSITION;
|
||||
};
|
||||
|
||||
float4 MainPS(PSInput input) : SV_TARGET {
|
||||
return gObjectIdColor;
|
||||
}
|
||||
53
engine/assets/builtin/shaders/object-id/object-id.shader
Normal file
53
engine/assets/builtin/shaders/object-id/object-id.shader
Normal file
@@ -0,0 +1,53 @@
|
||||
{
|
||||
"name": "Builtin Object Id",
|
||||
"passes": [
|
||||
{
|
||||
"name": "ObjectId",
|
||||
"tags": {
|
||||
"LightMode": "ObjectId"
|
||||
},
|
||||
"variants": [
|
||||
{
|
||||
"stage": "Vertex",
|
||||
"backend": "D3D12",
|
||||
"language": "HLSL",
|
||||
"source": "object-id.vs.hlsl",
|
||||
"entryPoint": "MainVS",
|
||||
"profile": "vs_5_0"
|
||||
},
|
||||
{
|
||||
"stage": "Fragment",
|
||||
"backend": "D3D12",
|
||||
"language": "HLSL",
|
||||
"source": "object-id.ps.hlsl",
|
||||
"entryPoint": "MainPS",
|
||||
"profile": "ps_5_0"
|
||||
},
|
||||
{
|
||||
"stage": "Vertex",
|
||||
"backend": "OpenGL",
|
||||
"language": "GLSL",
|
||||
"source": "object-id.vert.glsl"
|
||||
},
|
||||
{
|
||||
"stage": "Fragment",
|
||||
"backend": "OpenGL",
|
||||
"language": "GLSL",
|
||||
"source": "object-id.frag.glsl"
|
||||
},
|
||||
{
|
||||
"stage": "Vertex",
|
||||
"backend": "Vulkan",
|
||||
"language": "GLSL",
|
||||
"source": "object-id.vert.vk.glsl"
|
||||
},
|
||||
{
|
||||
"stage": "Fragment",
|
||||
"backend": "Vulkan",
|
||||
"language": "GLSL",
|
||||
"source": "object-id.frag.vk.glsl"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
16
engine/assets/builtin/shaders/object-id/object-id.vert.glsl
Normal file
16
engine/assets/builtin/shaders/object-id/object-id.vert.glsl
Normal file
@@ -0,0 +1,16 @@
|
||||
// XC_BUILTIN_OBJECT_ID_OPENGL_VS
|
||||
#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;
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
// XC_BUILTIN_OBJECT_ID_VULKAN_VS
|
||||
#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;
|
||||
}
|
||||
23
engine/assets/builtin/shaders/object-id/object-id.vs.hlsl
Normal file
23
engine/assets/builtin/shaders/object-id/object-id.vs.hlsl
Normal file
@@ -0,0 +1,23 @@
|
||||
// XC_BUILTIN_OBJECT_ID_D3D12_VS
|
||||
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;
|
||||
}
|
||||
@@ -43,6 +43,12 @@ size_t CalculateBuiltinShaderMemorySize(const Shader& shader);
|
||||
|
||||
constexpr const char* kBuiltinForwardLitShaderManifestRelativePath =
|
||||
"engine/assets/builtin/shaders/forward-lit/forward-lit.shader";
|
||||
constexpr const char* kBuiltinObjectIdShaderManifestRelativePath =
|
||||
"engine/assets/builtin/shaders/object-id/object-id.shader";
|
||||
constexpr const char* kBuiltinObjectIdOutlineShaderManifestRelativePath =
|
||||
"engine/assets/builtin/shaders/object-id-outline/object-id-outline.shader";
|
||||
constexpr const char* kBuiltinInfiniteGridShaderManifestRelativePath =
|
||||
"engine/assets/builtin/shaders/infinite-grid/infinite-grid.shader";
|
||||
|
||||
Containers::String NormalizeBuiltinAssetPath(const std::filesystem::path& path) {
|
||||
return Containers::String(path.lexically_normal().generic_string().c_str());
|
||||
@@ -79,8 +85,9 @@ bool TryResolveBuiltinAssetPathFromAnchor(
|
||||
return false;
|
||||
}
|
||||
|
||||
bool TryResolveBuiltinForwardLitShaderManifestPath(Containers::String& outPath) {
|
||||
const std::filesystem::path relativePath(kBuiltinForwardLitShaderManifestRelativePath);
|
||||
bool TryResolveBuiltinShaderManifestPath(
|
||||
const std::filesystem::path& relativePath,
|
||||
Containers::String& outPath) {
|
||||
std::filesystem::path resolvedPath;
|
||||
std::error_code ec;
|
||||
|
||||
@@ -104,6 +111,34 @@ bool TryResolveBuiltinForwardLitShaderManifestPath(Containers::String& outPath)
|
||||
return false;
|
||||
}
|
||||
|
||||
const char* GetBuiltinShaderManifestRelativePath(const Containers::String& builtinShaderPath) {
|
||||
if (builtinShaderPath == Containers::String(kBuiltinForwardLitShaderPath)) {
|
||||
return kBuiltinForwardLitShaderManifestRelativePath;
|
||||
}
|
||||
if (builtinShaderPath == Containers::String(kBuiltinObjectIdShaderPath)) {
|
||||
return kBuiltinObjectIdShaderManifestRelativePath;
|
||||
}
|
||||
if (builtinShaderPath == Containers::String(kBuiltinObjectIdOutlineShaderPath)) {
|
||||
return kBuiltinObjectIdOutlineShaderManifestRelativePath;
|
||||
}
|
||||
if (builtinShaderPath == Containers::String(kBuiltinInfiniteGridShaderPath)) {
|
||||
return kBuiltinInfiniteGridShaderManifestRelativePath;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool TryResolveBuiltinShaderManifestPath(
|
||||
const Containers::String& builtinShaderPath,
|
||||
Containers::String& outPath) {
|
||||
const char* relativePath = GetBuiltinShaderManifestRelativePath(builtinShaderPath);
|
||||
if (relativePath == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return TryResolveBuiltinShaderManifestPath(std::filesystem::path(relativePath), outPath);
|
||||
}
|
||||
|
||||
Shader* LoadBuiltinShaderFromManifest(
|
||||
const Containers::String& builtinPath,
|
||||
const Containers::String& manifestPath) {
|
||||
@@ -120,6 +155,15 @@ Shader* LoadBuiltinShaderFromManifest(
|
||||
return shader;
|
||||
}
|
||||
|
||||
Shader* TryLoadBuiltinShaderFromManifest(const Containers::String& builtinPath) {
|
||||
Containers::String manifestPath;
|
||||
if (!TryResolveBuiltinShaderManifestPath(builtinPath, manifestPath)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return LoadBuiltinShaderFromManifest(builtinPath, manifestPath);
|
||||
}
|
||||
|
||||
const char kBuiltinForwardHlsl[] = R"(
|
||||
Texture2D gBaseColorTexture : register(t1);
|
||||
SamplerState gLinearSampler : register(s1);
|
||||
@@ -1133,12 +1177,9 @@ size_t CalculateBuiltinShaderMemorySize(const Shader& shader) {
|
||||
}
|
||||
|
||||
Shader* BuildBuiltinForwardLitShader(const Containers::String& path) {
|
||||
Containers::String manifestPath;
|
||||
if (TryResolveBuiltinForwardLitShaderManifestPath(manifestPath)) {
|
||||
if (Shader* shader = LoadBuiltinShaderFromManifest(path, manifestPath)) {
|
||||
if (Shader* shader = TryLoadBuiltinShaderFromManifest(path)) {
|
||||
return shader;
|
||||
}
|
||||
}
|
||||
|
||||
auto* shader = new Shader();
|
||||
IResource::ConstructParams params;
|
||||
@@ -1213,6 +1254,10 @@ Shader* BuildBuiltinForwardLitShader(const Containers::String& 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");
|
||||
@@ -1286,6 +1331,10 @@ Shader* BuildBuiltinObjectIdShader(const Containers::String& 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");
|
||||
@@ -1321,6 +1370,10 @@ Shader* BuildBuiltinInfiniteGridShader(const Containers::String& 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");
|
||||
|
||||
@@ -312,6 +312,27 @@ TEST(ShaderLoader, LoadBuiltinObjectIdShaderBuildsBackendVariants) {
|
||||
EXPECT_NE(shader->FindVariant("ObjectId", ShaderType::Vertex, ShaderBackend::Vulkan), nullptr);
|
||||
EXPECT_NE(shader->FindVariant("ObjectId", ShaderType::Fragment, ShaderBackend::Vulkan), nullptr);
|
||||
|
||||
const ShaderStageVariant* d3d12Vertex = shader->FindVariant(
|
||||
"ObjectId",
|
||||
ShaderType::Vertex,
|
||||
ShaderBackend::D3D12);
|
||||
ASSERT_NE(d3d12Vertex, nullptr);
|
||||
EXPECT_NE(std::string(d3d12Vertex->sourceCode.CStr()).find("XC_BUILTIN_OBJECT_ID_D3D12_VS"), std::string::npos);
|
||||
|
||||
const ShaderStageVariant* openglFragment = shader->FindVariant(
|
||||
"ObjectId",
|
||||
ShaderType::Fragment,
|
||||
ShaderBackend::OpenGL);
|
||||
ASSERT_NE(openglFragment, nullptr);
|
||||
EXPECT_NE(std::string(openglFragment->sourceCode.CStr()).find("XC_BUILTIN_OBJECT_ID_OPENGL_PS"), std::string::npos);
|
||||
|
||||
const ShaderStageVariant* vulkanFragment = shader->FindVariant(
|
||||
"ObjectId",
|
||||
ShaderType::Fragment,
|
||||
ShaderBackend::Vulkan);
|
||||
ASSERT_NE(vulkanFragment, nullptr);
|
||||
EXPECT_NE(std::string(vulkanFragment->sourceCode.CStr()).find("XC_BUILTIN_OBJECT_ID_VULKAN_PS"), std::string::npos);
|
||||
|
||||
delete shader;
|
||||
}
|
||||
|
||||
@@ -337,6 +358,13 @@ TEST(ShaderLoader, LoadBuiltinInfiniteGridShaderBuildsD3D12Variants) {
|
||||
EXPECT_EQ(shader->FindVariant("InfiniteGrid", ShaderType::Vertex, ShaderBackend::OpenGL), nullptr);
|
||||
EXPECT_EQ(shader->FindVariant("InfiniteGrid", ShaderType::Fragment, ShaderBackend::OpenGL), nullptr);
|
||||
|
||||
const ShaderStageVariant* d3d12Fragment = shader->FindVariant(
|
||||
"InfiniteGrid",
|
||||
ShaderType::Fragment,
|
||||
ShaderBackend::D3D12);
|
||||
ASSERT_NE(d3d12Fragment, nullptr);
|
||||
EXPECT_NE(std::string(d3d12Fragment->sourceCode.CStr()).find("XC_BUILTIN_INFINITE_GRID_D3D12_PS"), std::string::npos);
|
||||
|
||||
delete shader;
|
||||
}
|
||||
|
||||
@@ -362,6 +390,15 @@ TEST(ShaderLoader, LoadBuiltinObjectIdOutlineShaderBuildsD3D12Variants) {
|
||||
EXPECT_EQ(shader->FindVariant("ObjectIdOutline", ShaderType::Vertex, ShaderBackend::OpenGL), nullptr);
|
||||
EXPECT_EQ(shader->FindVariant("ObjectIdOutline", ShaderType::Fragment, ShaderBackend::OpenGL), nullptr);
|
||||
|
||||
const ShaderStageVariant* d3d12Fragment = shader->FindVariant(
|
||||
"ObjectIdOutline",
|
||||
ShaderType::Fragment,
|
||||
ShaderBackend::D3D12);
|
||||
ASSERT_NE(d3d12Fragment, nullptr);
|
||||
EXPECT_NE(
|
||||
std::string(d3d12Fragment->sourceCode.CStr()).find("XC_BUILTIN_OBJECT_ID_OUTLINE_D3D12_PS"),
|
||||
std::string::npos);
|
||||
|
||||
delete shader;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user