Mesh exploder

New 'Exploded' visualisation mode in BufferViewer with new exploder controls
hidden when not in 'Exploded' mode.

Change 'solidShading' and 'solidShadeMode' to 'visualisation' and
'visualisationMode'.

Hide the 'highlightVerts' widget when using 'Exploded' vis for both
real-estate and practical implementation reasons.
This commit is contained in:
Dan Hawson
2023-12-09 11:40:30 +00:00
committed by Baldur Karlsson
parent da3e2366ac
commit 442b48bb77
23 changed files with 634 additions and 197 deletions
+4 -3
View File
@@ -172,14 +172,15 @@ vec3 CalcCubeCoord(vec2 uv, int face)
#endif
// first few match SolidShade enum
// first few match Visualisation enum
#define MESHDISPLAY_SOLID 0x1
#define MESHDISPLAY_FACELIT 0x2
#define MESHDISPLAY_SECONDARY 0x3
#define MESHDISPLAY_MESHLET 0x4
#define MESHDISPLAY_EXPLODE 0x4
#define MESHDISPLAY_MESHLET 0x5
// extra values below
#define MESHDISPLAY_SECONDARY_ALPHA 0x5
#define MESHDISPLAY_SECONDARY_ALPHA 0x6
#define MAX_NUM_MESHLETS (512 * 1024)
+8 -1
View File
@@ -35,12 +35,19 @@ BINDING(0) uniform MeshUBOData
mat4 mvp;
mat4 invProj;
vec4 color;
int displayFormat;
uint homogenousInput;
vec2 pointSpriteSize;
uint rawoutput;
uint flipY;
vec2 padding;
float vtxExploderSNorm;
float exploderScale;
vec3 exploderCentre;
float padding;
uvec4 meshletColours[12];
}
INST_NAME(Mesh);
+6
View File
@@ -60,6 +60,12 @@ void main(void)
color_out = vec4(Mesh.color.xyz * abs(dot(lightDir, NORM_NAME.xyz)), 1);
}
else if(type == MESHDISPLAY_EXPLODE)
{
vec3 lightDir = normalize(vec3(0, -0.3f, -1));
color_out = vec4(SECONDARY_NAME.xyz * abs(dot(lightDir, NORM_NAME.xyz)), 1);
}
else // if(type == MESHDISPLAY_SOLID)
{
color_out = vec4(Mesh.color.xyz, 1);
+68 -1
View File
@@ -36,6 +36,70 @@
#define SECONDARY_TYPE vec4
#endif
// This function is mostly duplicated between 'mesh.hlsl' and 'mesh.vert'.
// Without a convenient shared common source, changes to one should be
// reflected in the other.
void vtxExploder(in int vtxID, inout vec3 pos, inout vec3 secondary)
{
if(Mesh.exploderScale > 0.0f)
{
float nonLinearVtxExplodeScale = 4.0f * Mesh.exploderScale * Mesh.vtxExploderSNorm *
Mesh.vtxExploderSNorm * Mesh.vtxExploderSNorm;
// A vertex might be coincident with our 'exploderCentre' so that, when normalized,
// can give us INFs/NaNs that, even if multiplied by a zero 'exploderScale', can
// leave us with bad numbers (as seems to be the case with glsl/vulkan, but not hlsl).
// Still, we should make this case safe for when we have a non-zero 'exploderScale' -
vec3 offset = pos - Mesh.exploderCentre;
float offsetDistSquared = dot(offset, offset);
vec3 safeExplodeDir = offset * inversesqrt(max(offsetDistSquared, FLT_EPSILON));
float displacement =
nonLinearVtxExplodeScale * ((float((vtxID >> 1) & 0xf) / 15.0f) * 1.5f - 0.5f);
pos += (safeExplodeDir * displacement);
// For the exploder visualisation, colour verts based on vertex ID, which we
// store in secondary.
//
// Interpolate a colour gradient from 0.0 to 1.0 and back to 0.0 for vertex IDs
// 0 to 16 to 32 respectively -
// 1 - | .`.
// | .` `.
// | .` | `.
// 0.5-| .` `.
// | .` | `. .
// |.` `. .`
// 0.0-+-----------+-----------+--- vtx IDs
// 0 16 32
float vtxIDMod32Div16 = float(vtxID % 32) / 16.0f; // 0: 0.0 16: 1.0 31: 1.94
float descending = floor(vtxIDMod32Div16); // 0..15: 0.0 16..31: 1.0
float gradientVal = abs(vtxIDMod32Div16 - (2.0f * descending)); // 0.0..1.0
// Use a hopefully fairly intuitive temperature gradient scheme to help visualise
// contiguous/nearby sequences of vertices, which should also show up breaks in
// colour where verts aren't shared between adjacent primitives.
const vec3 gradientColours[5] =
vec3[](vec3(0.004f, 0.002f, 0.025f), // 0.0..0.25: Dark blue
vec3(0.305f, 0.001f, 0.337f), // 0.25..0.5: Purple
vec3(0.665f, 0.033f, 0.133f), // 0.5..0.75: Purple orange
vec3(1.000f, 0.468f, 0.000f), // 0.75..1.0: Orange
vec3(1.000f, 1.000f, 1.000f) // 1.0: White
);
uint gradientSectionStartIdx = uint(gradientVal * 4.0f);
uint gradientSectionEndIdx = min(gradientSectionStartIdx + 1u, 4u);
vec3 gradSectionStartCol = gradientColours[gradientSectionStartIdx];
vec3 gradSectionEndCol = gradientColours[gradientSectionEndIdx];
float sectionLerp = gradientVal - float(gradientSectionStartIdx) * 0.25f;
vec3 gradCol = mix(gradientColours[gradientSectionStartIdx],
gradientColours[gradientSectionEndIdx], sectionLerp);
secondary = gradCol;
}
}
IO_LOCATION(0) in POSITION_TYPE vsin_position;
IO_LOCATION(1) in SECONDARY_TYPE vsin_secondary;
@@ -111,6 +175,9 @@ void main(void)
vec2[](vec2(-1.0f, -1.0f), vec2(-1.0f, 1.0f), vec2(1.0f, -1.0f), vec2(1.0f, 1.0f));
vec4 pos = vec4(vsin_position);
vec4 secondary = vec4(vsin_secondary);
vtxExploder(VERTEX_ID, pos.xyz, secondary.xyz);
if(Mesh.homogenousInput == 0u)
{
pos = vec4(pos.xyz, 1);
@@ -124,7 +191,7 @@ void main(void)
gl_Position = Mesh.mvp * pos;
gl_Position.xy += Mesh.pointSpriteSize.xy * 0.01f * psprite[VERTEX_ID % 4] * gl_Position.w;
vsout_secondary = vec4(vsin_secondary);
vsout_secondary = vec4(secondary);
vsout_norm = vec4(0, 0, 1, 1);
#ifdef VULKAN
+9 -5
View File
@@ -107,12 +107,15 @@ cbuffer MeshVertexCBuffer REG(b0)
float2 SpriteSize;
uint homogenousInput;
uint vertMeshDisplayFormat;
float vtxExploderSNorm;
float3 exploderCentre;
float exploderScale; // Non-zero values imply use of the exploder visualisation.
uint vertMeshDisplayFormat;
uint meshletOffset;
uint meshletCount;
uint padding1;
uint padding2;
uint4 meshletColours[12];
};
@@ -250,14 +253,15 @@ cbuffer DebugSampleOperation REG(b0)
#define RESTYPE_DEPTH_STENCIL_MS 0x7
#define RESTYPE_TEX2D_MS 0x9
// first few match SolidShade enum
// first few match Visualisation enum
#define MESHDISPLAY_SOLID 0x1
#define MESHDISPLAY_FACELIT 0x2
#define MESHDISPLAY_SECONDARY 0x3
#define MESHDISPLAY_MESHLET 0x4
#define MESHDISPLAY_EXPLODE 0x4
#define MESHDISPLAY_MESHLET 0x5
// extra values below
#define MESHDISPLAY_SECONDARY_ALPHA 0x5
#define MESHDISPLAY_SECONDARY_ALPHA 0x6
#define MAX_NUM_MESHLETS (512 * 1024)
+71
View File
@@ -37,6 +37,70 @@ struct meshA2V
float4 secondary : sec;
};
// This function is mostly duplicated between 'mesh.hlsl' and 'mesh.vert'.
// Without a convenient shared common source, changes to one should be
// reflected in the other.
void vtxExploder(in uint vtxID, inout float3 pos, inout float3 secondary)
{
if(exploderScale > 0.0f)
{
float nonLinearVtxExplodeScale =
4.0f * exploderScale * vtxExploderSNorm * vtxExploderSNorm * vtxExploderSNorm;
// A vertex might be coincident with our 'exploderCentre' so that, when normalized,
// can give us INFs/NaNs that, even if multiplied by a zero 'exploderScale', can
// leave us with bad numbers (as seems to be the case with glsl/vulkan, but not hlsl).
// Still, we should make this case safe for when we have a non-zero 'exploderScale' -
float3 offset = pos - exploderCentre;
float offsetDistSquared = dot(offset, offset);
float3 safeExplodeDir = offset * rsqrt(max(offsetDistSquared, FLT_EPSILON));
float displacement =
nonLinearVtxExplodeScale * ((float((vtxID >> 1u) & 0xfu) / 15.0f) * 1.5f - 0.5f);
pos += (safeExplodeDir * displacement);
// For the exploder visualisation, colour verts based on vertex ID, which we
// store in secondary.
//
// Interpolate a colour gradient from 0.0 to 1.0 and back to 0.0 for vertex IDs
// 0 to 16 to 32 respectively -
// 1 - | .`.
// | .` `.
// | .` | `.
// 0.5-| .` `.
// | .` | `. .
// |.` `. .`
// 0.0-+-----------+-----------+--- vtx IDs
// 0 16 32
float vtxIDMod32Div16 = (float)(vtxID % 32u) / 16.0f; // 0: 0.0 16: 1.0 31: 1.94
float descending = floor(vtxIDMod32Div16); // 0..15: 0.0 16..31: 1.0
float gradientVal = abs(vtxIDMod32Div16 - (2.0f * descending)); // 0.0..1.0
// Use a hopefully fairly intuitive temperature gradient scheme to help visualise
// contiguous/nearby sequences of vertices, which should also show up breaks in
// colour where verts aren't shared between adjacent primitives.
const float3 gradientColours[5] = {
float3(0.004f, 0.002f, 0.025f), // 0.0..0.25: Dark blue
float3(0.305f, 0.001f, 0.337f), // 0.25..0.5: Purple
float3(0.665f, 0.033f, 0.133f), // 0.5..0.75: Purple orange
float3(1.000f, 0.468f, 0.000f), // 0.75..1.0: Orange
float3(1.000f, 1.000f, 1.000f) // 1.0: White
};
uint gradientSectionStartIdx = (uint)(gradientVal * 4.0f);
uint gradientSectionEndIdx = min(gradientSectionStartIdx + 1u, 4u);
float3 gradSectionStartCol = gradientColours[gradientSectionStartIdx];
float3 gradSectionEndCol = gradientColours[gradientSectionEndIdx];
float sectionLerp = gradientVal - (float)gradientSectionStartIdx * 0.25f;
float3 gradCol = lerp(gradientColours[gradientSectionStartIdx],
gradientColours[gradientSectionEndIdx], sectionLerp);
secondary = gradCol;
}
}
StructuredBuffer<uint4> meshletSizesBuf : register(t0);
float4 unpackUnorm4x8(uint value)
@@ -118,6 +182,7 @@ meshV2F RENDERDOC_MeshVS(meshA2V IN, uint vid : SV_VertexID)
float2(1.0f, 1.0f)};
float4 pos = IN.pos;
vtxExploder(vid, pos.xyz, IN.secondary.xyz);
if(homogenousInput == 0u)
{
@@ -214,6 +279,12 @@ float4 RENDERDOC_MeshPS(meshV2F IN)
return float4(MeshColour.xyz * abs(dot(lightDir, IN.norm)), 1);
}
else if(type == MESHDISPLAY_EXPLODE)
{
float3 lightDir = normalize(float3(0, -0.3f, -1));
return float4(IN.secondary.xyz * abs(dot(lightDir, IN.norm)), 1);
}
else // if(type == MESHDISPLAY_SOLID)
return float4(MeshColour.xyz, 1);
}