From 04c690e8f9b95c0f29fee04e24f8b1d3890037bc Mon Sep 17 00:00:00 2001
From: Alexander Rose <alexander.rose@weirdbyte.de>
Date: Wed, 22 Apr 2020 16:00:38 -0700
Subject: [PATCH] add .writeDepth to renderable state

- renders transparent with writeDepth=true before writeDepth=true
---
 src/mol-canvas3d/helper/bounding-sphere-helper.ts |  2 +-
 src/mol-geo/geometry/base.ts                      |  5 ++++-
 src/mol-gl/_spec/renderer.spec.ts                 |  3 ++-
 src/mol-gl/renderable.ts                          |  1 +
 src/mol-gl/renderer.ts                            | 15 ++++++++++-----
 src/mol-gl/scene.ts                               |  6 ++++--
 6 files changed, 22 insertions(+), 10 deletions(-)

diff --git a/src/mol-canvas3d/helper/bounding-sphere-helper.ts b/src/mol-canvas3d/helper/bounding-sphere-helper.ts
index 57540217a..1bcc024c7 100644
--- a/src/mol-canvas3d/helper/bounding-sphere-helper.ts
+++ b/src/mol-canvas3d/helper/bounding-sphere-helper.ts
@@ -159,5 +159,5 @@ const instanceMaterialId = getNextMaterialId();
 
 function createBoundingSphereRenderObject(mesh: Mesh, color: Color, materialId: number, transform?: TransformData) {
     const values = Mesh.Utils.createValuesSimple(mesh, { alpha: 0.1, doubleSided: false }, color, 1, transform);
-    return createRenderObject('mesh', values, { visible: true, alphaFactor: 1, pickable: false, opaque: false }, materialId);
+    return createRenderObject('mesh', values, { visible: true, alphaFactor: 1, pickable: false, opaque: false, writeDepth: false }, materialId);
 }
\ No newline at end of file
diff --git a/src/mol-geo/geometry/base.ts b/src/mol-geo/geometry/base.ts
index 6433278a9..bd1961733 100644
--- a/src/mol-geo/geometry/base.ts
+++ b/src/mol-geo/geometry/base.ts
@@ -72,15 +72,18 @@ export namespace BaseGeometry {
     }
 
     export function createRenderableState(props: Partial<PD.Values<Params>> = {}): RenderableState {
+        const opaque = props.alpha === undefined ? true : props.alpha === 1;
         return {
             visible: true,
             alphaFactor: 1,
             pickable: true,
-            opaque: props.alpha === undefined ? true : props.alpha === 1
+            opaque,
+            writeDepth: opaque,
         };
     }
 
     export function updateRenderableState(state: RenderableState, props: PD.Values<Params>) {
         state.opaque = props.alpha * state.alphaFactor >= 1;
+        state.writeDepth = state.opaque;
     }
 }
\ No newline at end of file
diff --git a/src/mol-gl/_spec/renderer.spec.ts b/src/mol-gl/_spec/renderer.spec.ts
index 8861f6214..716364b2d 100644
--- a/src/mol-gl/_spec/renderer.spec.ts
+++ b/src/mol-gl/_spec/renderer.spec.ts
@@ -86,7 +86,8 @@ function createPoints() {
         visible: true,
         alphaFactor: 1,
         pickable: true,
-        opaque: true
+        opaque: true,
+        writeDepth: true
     };
 
     return createRenderObject('points', values, state, -1);
diff --git a/src/mol-gl/renderable.ts b/src/mol-gl/renderable.ts
index 12639b8dd..a2b95c61b 100644
--- a/src/mol-gl/renderable.ts
+++ b/src/mol-gl/renderable.ts
@@ -18,6 +18,7 @@ export type RenderableState = {
     alphaFactor: number
     pickable: boolean
     opaque: boolean
+    writeDepth: boolean,
 }
 
 export interface Renderable<T extends RenderableValues> {
diff --git a/src/mol-gl/renderer.ts b/src/mol-gl/renderer.ts
index 334251f7f..321174a7c 100644
--- a/src/mol-gl/renderer.ts
+++ b/src/mol-gl/renderer.ts
@@ -212,6 +212,10 @@ namespace Renderer {
                     state.cullFace(gl.BACK);
                 }
 
+                if (variant === 'color') {
+                    state.depthMask(r.state.writeDepth);
+                }
+
                 r.render(variant);
             }
         };
@@ -245,11 +249,11 @@ namespace Renderer {
 
             state.disable(gl.SCISSOR_TEST);
             state.disable(gl.BLEND);
-            state.depthMask(true);
             state.colorMask(true, true, true, true);
             state.enable(gl.DEPTH_TEST);
 
             if (clear) {
+                state.depthMask(true);
                 if (variant === 'color') {
                     state.clearColor(bgColor[0], bgColor[1], bgColor[2], transparentBackground ? 0 : 1);
                 } else {
@@ -268,10 +272,11 @@ namespace Renderer {
                 state.enable(gl.BLEND);
                 for (let i = 0, il = renderables.length; i < il; ++i) {
                     const r = renderables[i];
-                    if (!r.state.opaque) {
-                        state.depthMask(false);
-                        renderObject(r, variant);
-                    }
+                    if (!r.state.opaque && r.state.writeDepth) renderObject(r, variant);
+                }
+                for (let i = 0, il = renderables.length; i < il; ++i) {
+                    const r = renderables[i];
+                    if (!r.state.opaque && !r.state.writeDepth) renderObject(r, variant);
                 }
             } else { // picking & depth
                 for (let i = 0, il = renderables.length; i < il; ++i) {
diff --git a/src/mol-gl/scene.ts b/src/mol-gl/scene.ts
index 2aa4bec6a..e24891e5f 100644
--- a/src/mol-gl/scene.ts
+++ b/src/mol-gl/scene.ts
@@ -50,9 +50,11 @@ function renderableSort(a: Renderable<RenderableValues & BaseValues>, b: Rendera
     const materialIdB = b.materialId;
 
     if (drawProgramIdA !== drawProgramIdB) {
-        return drawProgramIdA - drawProgramIdB; // sort by program id to minimize gl state changes
+        // sort by program id to minimize gl state changes
+        return drawProgramIdA - drawProgramIdB;
     } else if (materialIdA !== materialIdB) {
-        return materialIdA - materialIdB; // sort by material id to minimize gl state changes
+        // sort by material id to minimize gl state changes
+        return materialIdA - materialIdB;
     } else {
         return a.id - b.id;
     }
-- 
GitLab