diff --git a/CHANGELOG.md b/CHANGELOG.md
index f68cac2f00e2a0b32a0afeeb5e9f3316d6a5d9a3..3226c2d309d8cc72f09a38e7879468fe8c8e42c5 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,6 +6,7 @@ Note that since we don't clearly distinguish between a public and private interf
 
 ## [Unreleased]
 
+- Add an `includeTransparent` parameter to hide/show outlines of components that are transparent
 - Fix 'once' for animations of systems with many frames
 - Better guard against issue (black fringes) with bumpiness in impostors
 - Improve impostor shaders
diff --git a/src/apps/docking-viewer/viewport.tsx b/src/apps/docking-viewer/viewport.tsx
index ba5ce4598a9920a917064968ad97f754706cad07..d1c4ff85ab2c940349d9a7dcbec2fa3a8f0d113c 100644
--- a/src/apps/docking-viewer/viewport.tsx
+++ b/src/apps/docking-viewer/viewport.tsx
@@ -55,6 +55,7 @@ function occlusionStyle(plugin: PluginContext) {
                 scale: 1.0,
                 threshold: 0.33,
                 color: Color(0x0000),
+                includeTransparent: true,
             } },
             shadow: { name: 'off', params: {} },
         }
diff --git a/src/examples/lighting/index.ts b/src/examples/lighting/index.ts
index a71bff56aa4c0d39b8c03f6317bd7864b7b0485a..0cc1048ef7843c78080a383bd8927ea3ba88a2a4 100644
--- a/src/examples/lighting/index.ts
+++ b/src/examples/lighting/index.ts
@@ -25,7 +25,7 @@ const Canvas3DPresets = {
         canvas3d: <Preset>{
             postprocessing: {
                 occlusion: { name: 'on', params: { samples: 32, radius: 6, bias: 1.4, blurKernelSize: 15, resolutionScale: 1 } },
-                outline: { name: 'on', params: { scale: 1, threshold: 0.33, color: Color(0x000000) } },
+                outline: { name: 'on', params: { scale: 1, threshold: 0.33, color: Color(0x000000), includeTransparent: true, } },
                 shadow: { name: 'off', params: {} },
             },
             renderer: {
diff --git a/src/extensions/cellpack/model.ts b/src/extensions/cellpack/model.ts
index 9c62408af02efabdaaa3bf78a4b9e058892bfa9b..91ea9c33315343732112fe22b80829545b5edc90 100644
--- a/src/extensions/cellpack/model.ts
+++ b/src/extensions/cellpack/model.ts
@@ -621,6 +621,7 @@ export const LoadCellPackModel = StateAction.build({
                         scale: 1,
                         threshold: 0.33,
                         color: ColorNames.black,
+                        includeTransparent: true,
                     }
                 }
             }
diff --git a/src/mol-canvas3d/passes/draw.ts b/src/mol-canvas3d/passes/draw.ts
index 1f6c5549bc2169e74b09f6246446930781db242b..2f8942215ebd170c0ea13252f7550a79b9ba27fb 100644
--- a/src/mol-canvas3d/passes/draw.ts
+++ b/src/mol-canvas3d/passes/draw.ts
@@ -142,7 +142,7 @@ export class DrawPass {
         }
 
         if (PostprocessingPass.isEnabled(postprocessingProps)) {
-            if (PostprocessingPass.isOutlineEnabled(postprocessingProps)) {
+            if (PostprocessingPass.isTransparentOutlineEnabled(postprocessingProps)) {
                 this.depthTargetTransparent.bind();
                 renderer.clearDepth(true);
                 if (scene.opacityAverage < 1) {
@@ -196,7 +196,7 @@ export class DrawPass {
         }
 
         if (PostprocessingPass.isEnabled(postprocessingProps)) {
-            if (PostprocessingPass.isOutlineEnabled(postprocessingProps)) {
+            if (PostprocessingPass.isTransparentOutlineEnabled(postprocessingProps)) {
                 this.depthTargetTransparent.bind();
                 renderer.clearDepth(true);
                 if (scene.opacityAverage < 1) {
@@ -260,7 +260,7 @@ export class DrawPass {
                     this.colorTarget.depthRenderbuffer?.detachFramebuffer(this.postprocessing.target.framebuffer);
                 }
 
-                if (PostprocessingPass.isOutlineEnabled(postprocessingProps)) {
+                if (PostprocessingPass.isTransparentOutlineEnabled(postprocessingProps)) {
                     this.depthTargetTransparent.bind();
                     renderer.clearDepth(true);
                     if (scene.opacityAverage < 1) {
diff --git a/src/mol-canvas3d/passes/postprocessing.ts b/src/mol-canvas3d/passes/postprocessing.ts
index b963c66d44ce977a443d0b89601fcabbf26f8f63..1a1401642b2a14055e068ea86d5780d962a832ef 100644
--- a/src/mol-canvas3d/passes/postprocessing.ts
+++ b/src/mol-canvas3d/passes/postprocessing.ts
@@ -45,10 +45,12 @@ const OutlinesSchema = {
     uFar: UniformSpec('f'),
 
     uMaxPossibleViewZDiff: UniformSpec('f'),
+
+    dTransparentOutline: DefineSpec('boolean'),
 };
 type OutlinesRenderable = ComputeRenderable<Values<typeof OutlinesSchema>>
 
-function getOutlinesRenderable(ctx: WebGLContext, depthTextureOpaque: Texture, depthTextureTransparent: Texture): OutlinesRenderable {
+function getOutlinesRenderable(ctx: WebGLContext, depthTextureOpaque: Texture, depthTextureTransparent: Texture, transparentOutline: boolean): OutlinesRenderable {
     const width = depthTextureOpaque.getWidth();
     const height = depthTextureOpaque.getHeight();
 
@@ -63,6 +65,8 @@ function getOutlinesRenderable(ctx: WebGLContext, depthTextureOpaque: Texture, d
         uFar: ValueCell.create(10000),
 
         uMaxPossibleViewZDiff: ValueCell.create(0.5),
+
+        dTransparentOutline: ValueCell.create(transparentOutline),
     };
 
     const schema = { ...OutlinesSchema };
@@ -288,10 +292,13 @@ const PostprocessingSchema = {
     dOutlineEnable: DefineSpec('boolean'),
     dOutlineScale: DefineSpec('number'),
     uOutlineThreshold: UniformSpec('f'),
+
+    dTransparentOutline: DefineSpec('boolean'),
 };
 type PostprocessingRenderable = ComputeRenderable<Values<typeof PostprocessingSchema>>
 
-function getPostprocessingRenderable(ctx: WebGLContext, colorTexture: Texture, depthTextureOpaque: Texture, depthTextureTransparent: Texture, shadowsTexture: Texture, outlinesTexture: Texture, ssaoDepthTexture: Texture): PostprocessingRenderable {
+
+function getPostprocessingRenderable(ctx: WebGLContext, colorTexture: Texture, depthTextureOpaque: Texture, depthTextureTransparent: Texture, shadowsTexture: Texture, outlinesTexture: Texture, ssaoDepthTexture: Texture, transparentOutline: boolean): PostprocessingRenderable {
     const values: Values<typeof PostprocessingSchema> = {
         ...QuadValues,
         tSsaoDepth: ValueCell.create(ssaoDepthTexture),
@@ -321,6 +328,8 @@ function getPostprocessingRenderable(ctx: WebGLContext, colorTexture: Texture, d
         dOutlineEnable: ValueCell.create(false),
         dOutlineScale: ValueCell.create(1),
         uOutlineThreshold: ValueCell.create(0.33),
+
+        dTransparentOutline: ValueCell.create(transparentOutline),
     };
 
     const schema = { ...PostprocessingSchema };
@@ -355,6 +364,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)),
+            includeTransparent: PD.Boolean(true, { description: 'Whether to show outline for transparent objects' }),
         }),
         off: PD.Group({})
     }, { cycle: true, description: 'Draw outline around 3D objects' }),
@@ -373,8 +383,8 @@ export class PostprocessingPass {
         return props.occlusion.name === 'on' || props.shadow.name === 'on' || props.outline.name === 'on' || props.background.variant.name !== 'off';
     }
 
-    static isOutlineEnabled(props: PostprocessingProps) {
-        return props.outline.name === 'on';
+    static isTransparentOutlineEnabled(props: PostprocessingProps) {
+        return props.outline.name === 'on' && props.outline.params.includeTransparent;
     }
 
     readonly target: RenderTarget;
@@ -428,7 +438,7 @@ export class PostprocessingPass {
         this.target = webgl.createRenderTarget(width, height, false, 'uint8', 'linear');
 
         this.outlinesTarget = webgl.createRenderTarget(width, height, false);
-        this.outlinesRenderable = getOutlinesRenderable(webgl, depthTextureOpaque, depthTextureTransparent);
+        this.outlinesRenderable = getOutlinesRenderable(webgl, depthTextureOpaque, depthTextureTransparent, true);
 
         this.shadowsTarget = webgl.createRenderTarget(width, height, false);
         this.shadowsRenderable = getShadowsRenderable(webgl, depthTextureOpaque);
@@ -456,7 +466,7 @@ export class PostprocessingPass {
         this.ssaoRenderable = getSsaoRenderable(webgl, this.downsampleFactor === 1 ? depthTextureOpaque : this.downsampledDepthTarget.texture);
         this.ssaoBlurFirstPassRenderable = getSsaoBlurRenderable(webgl, this.ssaoDepthTexture, 'horizontal');
         this.ssaoBlurSecondPassRenderable = getSsaoBlurRenderable(webgl, this.ssaoDepthBlurProxyTexture, 'vertical');
-        this.renderable = getPostprocessingRenderable(webgl, colorTarget.texture, depthTextureOpaque, depthTextureTransparent, this.shadowsTarget.texture, this.outlinesTarget.texture, this.ssaoDepthTexture);
+        this.renderable = getPostprocessingRenderable(webgl, colorTarget.texture, depthTextureOpaque, depthTextureTransparent, this.shadowsTarget.texture, this.outlinesTarget.texture, this.ssaoDepthTexture, true);
 
         this.background = new BackgroundPass(webgl, assetManager, width, height);
     }
@@ -494,6 +504,7 @@ export class PostprocessingPass {
         let needsUpdateMain = false;
         let needsUpdateSsao = false;
         let needsUpdateSsaoBlur = false;
+        let needsUpdateOutlines = false;
 
         const orthographic = camera.state.mode === 'orthographic' ? 1 : 0;
         const outlinesEnabled = props.outline.name === 'on';
@@ -615,7 +626,8 @@ export class PostprocessingPass {
         }
 
         if (props.outline.name === 'on') {
-            let { threshold } = props.outline.params;
+            let { threshold, includeTransparent } = props.outline.params;
+            const transparentOutline = includeTransparent ?? true;
             // orthographic needs lower threshold
             if (camera.state.mode === 'orthographic') threshold /= 5;
             const factor = Math.pow(1000, threshold) / 1000;
@@ -626,12 +638,16 @@ export class PostprocessingPass {
             ValueCell.updateIfChanged(this.outlinesRenderable.values.uNear, camera.near);
             ValueCell.updateIfChanged(this.outlinesRenderable.values.uFar, camera.far);
             ValueCell.updateIfChanged(this.outlinesRenderable.values.uMaxPossibleViewZDiff, maxPossibleViewZDiff);
+            if (this.renderable.values.dTransparentOutline.ref.value !== transparentOutline) { needsUpdateOutlines = true; }
+            ValueCell.updateIfChanged(this.outlinesRenderable.values.dTransparentOutline, transparentOutline);
 
             ValueCell.update(this.renderable.values.uOutlineColor, Color.toVec3Normalized(this.renderable.values.uOutlineColor.ref.value, props.outline.params.color));
 
             ValueCell.updateIfChanged(this.renderable.values.uMaxPossibleViewZDiff, maxPossibleViewZDiff);
             if (this.renderable.values.dOutlineScale.ref.value !== outlineScale) { needsUpdateMain = true; }
             ValueCell.updateIfChanged(this.renderable.values.dOutlineScale, outlineScale);
+            if (this.renderable.values.dTransparentOutline.ref.value !== transparentOutline) { needsUpdateMain = true; }
+            ValueCell.updateIfChanged(this.renderable.values.dTransparentOutline, transparentOutline);
         }
 
         ValueCell.updateIfChanged(this.renderable.values.uFar, camera.far);
@@ -650,6 +666,10 @@ export class PostprocessingPass {
         if (this.renderable.values.dOcclusionEnable.ref.value !== occlusionEnabled) { needsUpdateMain = true; }
         ValueCell.updateIfChanged(this.renderable.values.dOcclusionEnable, occlusionEnabled);
 
+        if (needsUpdateOutlines) {
+            this.outlinesRenderable.update();
+        }
+
         if (needsUpdateShadows) {
             this.shadowsRenderable.update();
         }
diff --git a/src/mol-gl/shader/outlines.frag.ts b/src/mol-gl/shader/outlines.frag.ts
index e2cb6ec226ee07fca037ae216842dd26da0289af..6c55edc06788f7471fe21d8fd3c3a3b92362913d 100644
--- a/src/mol-gl/shader/outlines.frag.ts
+++ b/src/mol-gl/shader/outlines.frag.ts
@@ -38,7 +38,11 @@ float getDepthOpaque(const in vec2 coords) {
 }
 
 float getDepthTransparent(const in vec2 coords) {
-    return unpackRGBAToDepth(texture2D(tDepthTransparent, coords));
+    #ifdef dTransparentOutline
+        return unpackRGBAToDepth(texture2D(tDepthTransparent, coords));
+    #else
+        return 1.0;
+    #endif
 }
 
 bool isBackground(const in float depth) {
diff --git a/src/mol-gl/shader/postprocessing.frag.ts b/src/mol-gl/shader/postprocessing.frag.ts
index d41cb9449bea753a2ea3d4f35421acd938d9272d..80e9712225c6589c8e7a39eca283a7f075be7f02 100644
--- a/src/mol-gl/shader/postprocessing.frag.ts
+++ b/src/mol-gl/shader/postprocessing.frag.ts
@@ -51,7 +51,11 @@ float getDepthOpaque(const in vec2 coords) {
 }
 
 float getDepthTransparent(const in vec2 coords) {
-    return unpackRGBAToDepth(texture2D(tDepthTransparent, coords));
+    #ifdef dTransparentOutline
+        return unpackRGBAToDepth(texture2D(tDepthTransparent, coords));
+    #else
+        return 1.0;
+    #endif
 }
 
 bool isBackground(const in float depth) {
diff --git a/src/mol-plugin-ui/structure/quick-styles.tsx b/src/mol-plugin-ui/structure/quick-styles.tsx
index ef3078b037793844447e996145b719dd4b85586b..27bda32a3ba4376210c13b00bc3345ef35bca922 100644
--- a/src/mol-plugin-ui/structure/quick-styles.tsx
+++ b/src/mol-plugin-ui/structure/quick-styles.tsx
@@ -56,7 +56,7 @@ export class QuickStyles extends PurePluginUIComponent {
                 postprocessing: {
                     outline: {
                         name: 'on',
-                        params: { scale: 1, color: Color(0x000000), threshold: 0.25 }
+                        params: { scale: 1, color: Color(0x000000), threshold: 0.25, includeTransparent: true }
                     },
                     occlusion: {
                         name: 'on',
@@ -79,7 +79,7 @@ export class QuickStyles extends PurePluginUIComponent {
                         name: 'on',
                         params: pp.outline.name === 'on'
                             ? pp.outline.params
-                            : { scale: 1, color: Color(0x000000), threshold: 0.33 }
+                            : { scale: 1, color: Color(0x000000), threshold: 0.33, includeTransparent: true }
                     },
                     occlusion: {
                         name: 'on',