Преглед изворни кода

add clipPrimitive option to spheres geometry

- clip whole spheres instead of cutting them
Alexander Rose пре 1 година
родитељ
комит
e2e9e5f6fc

+ 1 - 0
CHANGELOG.md

@@ -11,6 +11,7 @@ Note that since we don't clearly distinguish between a public and private interf
 - Improve `distinctColors` function
     - Add `sort` and `sampleCountFactor` parameters
     - Fix clustering issues
+- Add `clipPrimitive` option to spheres geometry, clipping whole spheres instead of cutting them
 
 ## [v3.41.0] - 2023-10-15
 

+ 3 - 0
src/mol-geo/geometry/spheres/spheres.ts

@@ -150,6 +150,7 @@ export namespace Spheres {
         xrayShaded: PD.Select<boolean | 'inverted'>(false, [[false, 'Off'], [true, 'On'], ['inverted', 'Inverted']], BaseGeometry.ShadingCategory),
         transparentBackfaces: PD.Select('off', PD.arrayToOptions(['off', 'on', 'opaque']), BaseGeometry.ShadingCategory),
         solidInterior: PD.Boolean(true, BaseGeometry.ShadingCategory),
+        clipPrimitive: PD.Boolean(false, { ...BaseGeometry.ShadingCategory, description: 'Clip whole sphere instead of cutting it.' }),
         approximate: PD.Boolean(false, { ...BaseGeometry.ShadingCategory, description: 'Faster rendering, but has artifacts.' }),
         alphaThickness: PD.Numeric(0, { min: 0, max: 20, step: 1 }, { ...BaseGeometry.ShadingCategory, description: 'If not zero, adjusts alpha for radius.' }),
         bumpFrequency: PD.Numeric(0, { min: 0, max: 10, step: 0.1 }, BaseGeometry.ShadingCategory),
@@ -236,6 +237,7 @@ export namespace Spheres {
             dXrayShaded: ValueCell.create(props.xrayShaded === 'inverted' ? 'inverted' : props.xrayShaded === true ? 'on' : 'off'),
             dTransparentBackfaces: ValueCell.create(props.transparentBackfaces),
             dSolidInterior: ValueCell.create(props.solidInterior),
+            dClipPrimitive: ValueCell.create(props.clipPrimitive),
             dApproximate: ValueCell.create(props.approximate),
             uAlphaThickness: ValueCell.create(props.alphaThickness),
             uBumpFrequency: ValueCell.create(props.bumpFrequency),
@@ -260,6 +262,7 @@ export namespace Spheres {
         ValueCell.updateIfChanged(values.dXrayShaded, props.xrayShaded === 'inverted' ? 'inverted' : props.xrayShaded === true ? 'on' : 'off');
         ValueCell.updateIfChanged(values.dTransparentBackfaces, props.transparentBackfaces);
         ValueCell.updateIfChanged(values.dSolidInterior, props.solidInterior);
+        ValueCell.updateIfChanged(values.dClipPrimitive, props.clipPrimitive);
         ValueCell.updateIfChanged(values.dApproximate, props.approximate);
         ValueCell.updateIfChanged(values.uAlphaThickness, props.alphaThickness);
         ValueCell.updateIfChanged(values.uBumpFrequency, props.bumpFrequency);

+ 1 - 0
src/mol-gl/renderable/spheres.ts

@@ -24,6 +24,7 @@ export const SpheresSchema = {
     dXrayShaded: DefineSpec('string', ['off', 'on', 'inverted']),
     dTransparentBackfaces: DefineSpec('string', ['off', 'on', 'opaque']),
     dSolidInterior: DefineSpec('boolean'),
+    dClipPrimitive: DefineSpec('boolean'),
     dApproximate: DefineSpec('boolean'),
     uAlphaThickness: UniformSpec('f'),
     uBumpFrequency: UniformSpec('f', 'material'),

+ 4 - 3
src/mol-gl/shader/spheres.frag.ts

@@ -51,7 +51,7 @@ bool SphereImpostor(out vec3 modelPos, out vec3 cameraPos, out vec3 cameraNormal
 
     bool objectClipped = false;
 
-    #if defined(dClipVariant_pixel) && dClipObjectCount != 0
+    #if !defined(dClipPrimitive) && defined(dClipVariant_pixel) && dClipObjectCount != 0
         if (clipTest(vec4(modelPos, 0.0))) {
             objectClipped = true;
             fragmentDepth = -1.0;
@@ -85,7 +85,6 @@ bool SphereImpostor(out vec3 modelPos, out vec3 cameraPos, out vec3 cameraNormal
 void main(void){
     vec3 cameraNormal;
     float fragmentDepth;
-    bool clipped = false;
 
     #ifdef dApproximate
         vec3 pointDir = -vPointViewPosition - vPoint;
@@ -112,7 +111,9 @@ void main(void){
         vec3 vViewPosition = cameraPos;
     #endif
 
-    #include clip_pixel
+    #if !defined(dClipPrimitive) && defined(dClipVariant_pixel) && dClipObjectCount != 0
+        #include clip_pixel
+    #endif
     #include assign_material_color
 
     #if defined(dRenderVariant_pick)

+ 8 - 1
src/mol-gl/shader/spheres.vert.ts

@@ -110,6 +110,13 @@ void main(void){
         gl_Position.z = (uProjection * vec4(mvPosition.xyz, 1.0)).z;
     }
 
-    #include clip_instance
+    #if defined(dClipPrimitive) && !defined(dClipVariant_instance) && dClipObjectCount != 0
+        if (clipTest(vec4(vModelPosition.xyz, 0.0))) {
+            // move out of [ -w, +w ] to 'discard' in vert shader
+            gl_Position.z = 2.0 * gl_Position.w;
+        }
+    #else
+        #include clip_instance
+    #endif
 }
 `;