90 lines
2.4 KiB
HLSL
90 lines
2.4 KiB
HLSL
// XC_EDITOR_SCENE_VIEW_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);
|
|
}
|