Browse Source

add approximate option for spheres rendering

Alexander Rose 1 year ago
parent
commit
c000526cf8

+ 1 - 0
CHANGELOG.md

@@ -8,6 +8,7 @@ Note that since we don't clearly distinguish between a public and private interf
 
 - Fix display issue with SIFTS mapping
 - Properly switch-off fog
+- Add `approximate` option for spheres rendering
 
 ## [v3.37.1] - 2023-06-20
 

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

@@ -131,6 +131,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),
+        approximate: PD.Boolean(false, { ...BaseGeometry.ShadingCategory, description: 'Faster rendering, but has artifacts.' }),
         bumpFrequency: PD.Numeric(0, { min: 0, max: 10, step: 0.1 }, BaseGeometry.ShadingCategory),
         bumpAmplitude: PD.Numeric(1, { min: 0, max: 5, step: 0.1 }, BaseGeometry.ShadingCategory),
     };
@@ -214,6 +215,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),
+            dApproximate: ValueCell.create(props.approximate),
             uBumpFrequency: ValueCell.create(props.bumpFrequency),
             uBumpAmplitude: ValueCell.create(props.bumpAmplitude),
         };
@@ -233,6 +235,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.dApproximate, props.approximate);
         ValueCell.updateIfChanged(values.uBumpFrequency, props.bumpFrequency);
         ValueCell.updateIfChanged(values.uBumpAmplitude, props.bumpAmplitude);
     }

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

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

+ 21 - 7
src/mol-gl/shader/spheres.frag.ts

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2019-2022 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * Copyright (c) 2019-2023 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
  */
@@ -88,17 +88,31 @@ void main(void){
     vec3 cameraNormal;
     float fragmentDepth;
     bool clipped = false;
-    bool hit = SphereImpostor(modelPos, cameraPos, cameraNormal, interior, fragmentDepth);
-    if (!hit) discard;
 
-    if (fragmentDepth < 0.0) discard;
-    if (fragmentDepth > 1.0) discard;
+    #ifdef dApproximate
+        vec3 pointDir = -vPointViewPosition - vPoint;
+        if (dot(pointDir, pointDir) > vRadius * vRadius) discard;
+        cameraPos = -vPointViewPosition;
+        modelPos = vPoint;
+        fragmentDepth = gl_FragCoord.z;
+        #ifndef dIgnoreLight
+            pointDir.z += length(pointDir) - vRadius;
+            cameraNormal = -normalize(pointDir / vRadius);
+        #endif
+        interior = false;
+    #else
+        bool hit = SphereImpostor(modelPos, cameraPos, cameraNormal, interior, fragmentDepth);
+        if (!hit) discard;
+
+        if (fragmentDepth < 0.0) discard;
+        if (fragmentDepth > 1.0) discard;
+
+        gl_FragDepthEXT = fragmentDepth;
+    #endif
 
     vec3 vViewPosition = cameraPos;
     vec3 vModelPosition = modelPos;
 
-    gl_FragDepthEXT = fragmentDepth;
-
     #include clip_pixel
     #include assign_material_color