Browse Source

Add option to set minimum alpha value for outlines to be shown

Alice Russell 2 years ago
parent
commit
9217e58845

+ 3 - 0
src/mol-canvas3d/passes/draw.ts

@@ -145,6 +145,7 @@ export class DrawPass {
             if (PostprocessingPass.isOutlineEnabled(postprocessingProps)) {
                 this.depthTargetTransparent.bind();
                 renderer.clearDepth(true);
+                renderer.setOutlineAlphaThreshold(PostprocessingPass.getOutlineMinimumOpacity(postprocessingProps));
                 if (scene.opacityAverage < 1) {
                     renderer.renderDepthTransparent(scene.primitives, camera, this.depthTextureOpaque);
                 }
@@ -199,6 +200,7 @@ export class DrawPass {
             if (PostprocessingPass.isOutlineEnabled(postprocessingProps)) {
                 this.depthTargetTransparent.bind();
                 renderer.clearDepth(true);
+                renderer.setOutlineAlphaThreshold(PostprocessingPass.getOutlineMinimumOpacity(postprocessingProps));
                 if (scene.opacityAverage < 1) {
                     renderer.renderDepthTransparent(scene.primitives, camera, this.depthTextureOpaque);
                 }
@@ -263,6 +265,7 @@ export class DrawPass {
                 if (PostprocessingPass.isOutlineEnabled(postprocessingProps)) {
                     this.depthTargetTransparent.bind();
                     renderer.clearDepth(true);
+                    renderer.setOutlineAlphaThreshold(PostprocessingPass.getOutlineMinimumOpacity(postprocessingProps));
                     if (scene.opacityAverage < 1) {
                         renderer.renderDepthTransparent(scene.primitives, camera, this.depthTextureOpaque);
                     }

+ 5 - 0
src/mol-canvas3d/passes/postprocessing.ts

@@ -279,6 +279,7 @@ export const PostprocessingParams = {
             scale: PD.Numeric(1, { min: 1, max: 5, step: 1 }),
             threshold: PD.Numeric(0.33, { min: 0.01, max: 1, step: 0.01 }),
             color: PD.Color(Color(0x000000)),
+            minimumOpacity: PD.Optional(PD.Numeric(0.0, { min: 0.0, max: 1.0, step: 0.01 }, { description: 'The minimum opacity value needed for an object to be have an outline'})),
         }),
         off: PD.Group({})
     }, { cycle: true, description: 'Draw outline around 3D objects' }),
@@ -300,6 +301,10 @@ export class PostprocessingPass {
         return props.outline.name === 'on';
     }
 
+    static getOutlineMinimumOpacity(props: PostprocessingProps) {
+        return props.outline.name === 'on' ? props.outline.params.minimumOpacity ?? 0.0 : 0.0
+    }
+
     readonly target: RenderTarget;
 
     private readonly outlinesTarget: RenderTarget;

+ 7 - 1
src/mol-gl/renderer.ts

@@ -80,6 +80,7 @@ interface Renderer {
     setTransparentBackground: (value: boolean) => void
     setDrawingBufferSize: (width: number, height: number) => void
     setPixelRatio: (value: number) => void
+    setOutlineAlphaThreshold: (value: number) => void
 
     dispose: () => void
 }
@@ -186,6 +187,8 @@ namespace Renderer {
         const ambientColor = Vec3();
         Vec3.scale(ambientColor, Color.toArrayNormalized(p.ambientColor, ambientColor, 0), p.ambientIntensity);
 
+        let outlineAlphaThreshold = 0.0;
+
         const globalUniforms: GlobalUniformValues = {
             uModel: ValueCell.create(Mat4.identity()),
             uView: ValueCell.create(view),
@@ -432,7 +435,7 @@ namespace Renderer {
             const { renderables } = group;
             for (let i = 0, il = renderables.length; i < il; ++i) {
                 const r = renderables[i];
-                if (!r.state.opaque || r.values.transparencyAverage.ref.value > 0 || r.values.dXrayShaded?.ref.value) {
+                if ((!r.state.opaque && r.values.alpha.ref.value > outlineAlphaThreshold) || r.values.transparencyAverage.ref.value > 0 || r.values.dXrayShaded?.ref.value) {
                     renderObject(r, 'depth', Flag.None);
                 }
             }
@@ -827,6 +830,9 @@ namespace Renderer {
                     instancedDrawCount: stats.instancedDrawCount,
                 };
             },
+            setOutlineAlphaThreshold: (value: number) => {
+                outlineAlphaThreshold = value;
+            },
             dispose: () => {
                 // TODO
             }