From 60305bee0a063951576aab3794c5a6505d3fa9ba Mon Sep 17 00:00:00 2001 From: Michael Saunders Date: Tue, 22 Jul 2025 11:30:36 -0700 Subject: [PATCH 1/2] Extend shader compiler define syntax to allow name=value instead of just valueless defines --- data/shaders/clip.vert | 17 +++++++++++++++-- examples/state/vsgclip/vsgclip.cpp | 11 +++++++++++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/data/shaders/clip.vert b/data/shaders/clip.vert index 41d52dfd..f2cbace9 100644 --- a/data/shaders/clip.vert +++ b/data/shaders/clip.vert @@ -1,5 +1,6 @@ #version 450 #extension GL_ARB_separate_shader_objects : enable +#pragma import_defines (NUM_CLIPS) layout(push_constant) uniform PushConstants { mat4 projection; @@ -19,7 +20,9 @@ layout(location = 1) out vec2 fragTexCoord; out gl_PerVertex { vec4 gl_Position; - float gl_ClipDistance[1]; + #if NUM_CLIPS > 0 + float gl_ClipDistance[NUM_CLIPS]; + #endif //float gl_CullDistance[1]; }; @@ -36,6 +39,16 @@ void main() { vec4 eye_Position = pc.modelview * vec4(inPosition, 1.0); - gl_ClipDistance[0] = (length(eye_Position.xyz - clipSettings.sphere.xyz) - clipSettings.sphere.w); + #if NUM_CLIPS > 0 + for (uint cOffset = 0; cOffset < NUM_CLIPS; ++cOffset) { + if (cOffset == 0) { + // clip volume inside the sphere using eye coordinates + gl_ClipDistance[cOffset] = (length(eye_Position.xyz - clipSettings.sphere.xyz) - clipSettings.sphere.w); + } else if (cOffset == 1) { + // simple clip on world coordinate X less than zero + gl_ClipDistance[cOffset] = inPosition.x; + } + } + #endif // gl_CullDistance[0] = (length(inPosition - clipSettings.sphere.xyz) - 3.0); } diff --git a/examples/state/vsgclip/vsgclip.cpp b/examples/state/vsgclip/vsgclip.cpp index 4377d925..c55b76ec 100644 --- a/examples/state/vsgclip/vsgclip.cpp +++ b/examples/state/vsgclip/vsgclip.cpp @@ -130,6 +130,13 @@ int main(int argc, char** argv) auto numFrames = arguments.value(-1, "-f"); + auto numClips = arguments.value(1, "-n"); + if (numClips < 1 || numClips > 2) + { + std::cout << "Choose between 1 and 2 clips. The first is a sphere the second is the X plane." << std::endl; + return 1; + } + if (arguments.errors()) return arguments.writeErrorMessages(std::cerr); if (argc <= 1) @@ -160,6 +167,10 @@ int main(int argc, char** argv) return 1; } + // specify the number of clips to perform; gl_ClipDistance array is sized by NUM_CLIPS + vertexShader->module->hints = vsg::ShaderCompileSettings::create(); + vertexShader->module->hints->defines.insert("NUM_CLIPS="+std::to_string(numClips)); + // create the viewer and assign window(s) to it auto viewer = vsg::Viewer::create(); From 69313d829c7ddf3fe2f6599240a610190f129188 Mon Sep 17 00:00:00 2001 From: Michael Saunders Date: Tue, 22 Jul 2025 12:05:05 -0700 Subject: [PATCH 2/2] Allow for disabling of clipping --- examples/state/vsgclip/vsgclip.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/state/vsgclip/vsgclip.cpp b/examples/state/vsgclip/vsgclip.cpp index c55b76ec..29fdf64c 100644 --- a/examples/state/vsgclip/vsgclip.cpp +++ b/examples/state/vsgclip/vsgclip.cpp @@ -131,9 +131,9 @@ int main(int argc, char** argv) auto numFrames = arguments.value(-1, "-f"); auto numClips = arguments.value(1, "-n"); - if (numClips < 1 || numClips > 2) + if (numClips < 0 || numClips > 2) { - std::cout << "Choose between 1 and 2 clips. The first is a sphere the second is the X plane." << std::endl; + std::cout << "Choose between 0 and 2 clips. If n is zero clipping is disabled. If n is 1 a clipping sphere is enabled in eye space, and if n is 2, world coordinate values less than X=0 are clipped in addition to the clipping sphere." << std::endl; return 1; }