refactor: route builtin outline pass through shader assets
This commit is contained in:
@@ -26,6 +26,7 @@ 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* kBuiltinObjectIdOutlineShaderPath = "builtin://shaders/object-id-outline";
|
||||
constexpr const char* kBuiltinInfiniteGridShaderPath = "builtin://shaders/infinite-grid";
|
||||
constexpr const char* kBuiltinDefaultPrimitiveTexturePath = "builtin://textures/default-primitive-albedo";
|
||||
constexpr float kPi = 3.14159265358979323846f;
|
||||
@@ -309,6 +310,109 @@ void main() {
|
||||
}
|
||||
)";
|
||||
|
||||
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;
|
||||
@@ -1125,6 +1229,41 @@ Shader* BuildBuiltinInfiniteGridShader(const Containers::String& path) {
|
||||
return shader;
|
||||
}
|
||||
|
||||
Shader* BuildBuiltinObjectIdOutlineShader(const Containers::String& path) {
|
||||
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;
|
||||
}
|
||||
|
||||
Material* BuildDefaultPrimitiveMaterial(const Containers::String& path) {
|
||||
auto* material = new Material();
|
||||
IResource::ConstructParams params;
|
||||
@@ -1231,6 +1370,10 @@ Containers::String GetBuiltinObjectIdShaderPath() {
|
||||
return Containers::String(kBuiltinObjectIdShaderPath);
|
||||
}
|
||||
|
||||
Containers::String GetBuiltinObjectIdOutlineShaderPath() {
|
||||
return Containers::String(kBuiltinObjectIdOutlineShaderPath);
|
||||
}
|
||||
|
||||
Containers::String GetBuiltinInfiniteGridShaderPath() {
|
||||
return Containers::String(kBuiltinInfiniteGridShaderPath);
|
||||
}
|
||||
@@ -1327,6 +1470,8 @@ LoadResult CreateBuiltinShaderResource(const Containers::String& path) {
|
||||
shader = BuildBuiltinForwardLitShader(path);
|
||||
} else if (path == GetBuiltinObjectIdShaderPath()) {
|
||||
shader = BuildBuiltinObjectIdShader(path);
|
||||
} else if (path == GetBuiltinObjectIdOutlineShaderPath()) {
|
||||
shader = BuildBuiltinObjectIdOutlineShader(path);
|
||||
} else if (path == GetBuiltinInfiniteGridShaderPath()) {
|
||||
shader = BuildBuiltinInfiniteGridShader(path);
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user