diff --git a/src/mol-canvas3d/passes/draw.ts b/src/mol-canvas3d/passes/draw.ts
index 3c72b628ba228a6d54d79da031bf33c30c81e571..65ebcee450ad0b4036dcdda273e344f0a282b029 100644
--- a/src/mol-canvas3d/passes/draw.ts
+++ b/src/mol-canvas3d/passes/draw.ts
@@ -62,8 +62,6 @@ export class DrawPass {
     private depthTextureVolumes: Texture
     private depthMerge: DepthMergeRenderable
 
-    private readonly dummyDepthTexture: Texture
-
     constructor(private webgl: WebGLContext, width: number, height: number) {
         const { extensions, resources } = webgl;
 
@@ -86,9 +84,6 @@ export class DrawPass {
             this.depthTextureVolumes.define(width, height);
         }
         this.depthMerge = getDepthMergeRenderable(webgl, this.depthTexturePrimitives, this.depthTextureVolumes, this.packedDepth);
-
-        this.dummyDepthTexture = resources.texture('image-depth', 'depth', 'ushort', 'nearest');
-        this.dummyDepthTexture.define(2, 2);
     }
 
     setSize(width: number, height: number) {
@@ -126,11 +121,6 @@ export class DrawPass {
 
         // console.log('toDrawingBuffer', toDrawingBuffer);
 
-        for (let i = 0; i < this.webgl.maxTextureImageUnits; i++) {
-            this.webgl.gl.activeTexture(this.webgl.gl.TEXTURE0 + i);
-            this.webgl.gl.bindTexture(this.webgl.gl.TEXTURE_2D, null);
-        }
-
         let renderTarget;
         if (toDrawingBuffer) {
             renderTarget = null;
@@ -149,7 +139,7 @@ export class DrawPass {
         }
 
         // render opaque color
-        renderer.render(renderTarget, scene.primitives, camera, 'color', true, transparentBackground, 1, this.dummyDepthTexture, false);
+        renderer.render(renderTarget, scene.primitives, camera, 'color', true, transparentBackground, 1, null, false);
 
         if (helper.debug.isEnabled) {
             helper.debug.syncVisibility();
diff --git a/src/mol-gl/renderer.ts b/src/mol-gl/renderer.ts
index 1fc80a22abe8f9b03487f2fe51f42377130542c9..524175141d6c1cd9acc5bacf6aca04f245ef610b 100644
--- a/src/mol-gl/renderer.ts
+++ b/src/mol-gl/renderer.ts
@@ -19,13 +19,14 @@ import { Clipping } from '../mol-theme/clipping';
 import { stringToWords } from '../mol-util/string';
 import { Transparency } from '../mol-theme/transparency';
 import { degToRad } from '../mol-math/misc';
-import { Texture, Textures } from './webgl/texture';
+import { createNullTexture, Texture, Textures } from './webgl/texture';
 import { RenderTarget } from './webgl/render-target';
 import { QuadSchema, QuadValues } from './compute/util';
 
 import quad_vert from '../mol-gl/shader/quad.vert';
 import evaluate_wboit_frag from '../mol-gl/shader/evaluate-wboit.frag';
 import { ShaderCode } from './shader-code';
+import { arrayMapUpsert } from '../mol-util/array';
 
 export interface RendererStats {
     programCount: number
@@ -175,7 +176,10 @@ namespace Renderer {
         const drawingBufferSize = Vec2.create(gl.drawingBufferWidth, gl.drawingBufferHeight);
         const bgColor = Color.toVec3Normalized(Vec3(), p.backgroundColor);
 
-        const sharedTexturesList: Textures = [];
+        const nullDepthTexture = createNullTexture(gl, 'image-depth');
+        const sharedTexturesList: Textures = [
+            ['tDepth', nullDepthTexture]
+        ];
 
         const enableWboit = textureFloat && colorBufferFloat && depthTexture && drawBuffers;
 
@@ -266,7 +270,7 @@ namespace Renderer {
 
         let globalUniformsNeedUpdate = true;
 
-        const renderObject = (r: Renderable<RenderableValues & BaseValues>, variant: GraphicsRenderVariant, sharedTexturesList?: Textures) => {
+        const renderObject = (r: Renderable<RenderableValues & BaseValues>, variant: GraphicsRenderVariant) => {
             if (!r.state.visible || (!r.state.pickable && variant[0] === 'p')) {
                 return;
             }
@@ -348,10 +352,7 @@ namespace Renderer {
         };
 
         const render = (renderTarget: RenderTarget | null, group: Scene.Group, camera: ICamera, variant: GraphicsRenderVariant, clear: boolean, transparentBackground: boolean, drawingBufferScale: number, depthTexture: Texture | null, renderTransparent: boolean) => {
-            let localSharedTexturesList = sharedTexturesList;
-            if (depthTexture) {
-                localSharedTexturesList = [...localSharedTexturesList, ['tDepth', depthTexture]];
-            }
+            arrayMapUpsert(sharedTexturesList, 'tDepth', depthTexture || nullDepthTexture);
 
             ValueCell.update(globalUniforms.uModel, group.view);
             ValueCell.update(globalUniforms.uView, camera.view);
@@ -425,7 +426,7 @@ namespace Renderer {
                         for (let i = 0, il = renderables.length; i < il; ++i) {
                             const r = renderables[i];
                             if (r.values.uAlpha.ref.value === 1 && r.values.transparencyAverage.ref.value !== 1 && r.values?.dRenderMode?.ref.value !== 'volume') {
-                                renderObject(r, variant, localSharedTexturesList);
+                                renderObject(r, variant);
                             }
                         }
                     } else {
@@ -445,7 +446,7 @@ namespace Renderer {
                         for (let i = 0, il = renderables.length; i < il; ++i) {
                             const r = renderables[i];
                             if (r.values.uAlpha.ref.value < 1 || r.values.transparencyAverage.ref.value !== 0) {
-                                renderObject(r, variant, localSharedTexturesList);
+                                renderObject(r, variant);
                             }
                         }
 
@@ -470,7 +471,7 @@ namespace Renderer {
                     for (let i = 0, il = renderables.length; i < il; ++i) {
                         const r = renderables[i];
                         if (r.state.opaque) {
-                            renderObject(r, variant, localSharedTexturesList);
+                            renderObject(r, variant);
                         }
                     }
 
@@ -479,13 +480,13 @@ namespace Renderer {
                     for (let i = 0, il = renderables.length; i < il; ++i) {
                         const r = renderables[i];
                         if (!r.state.opaque && r.state.writeDepth) {
-                            renderObject(r, variant, localSharedTexturesList);
+                            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, localSharedTexturesList);
+                            renderObject(r, variant);
                         }
                     }
                 }
@@ -493,7 +494,7 @@ namespace Renderer {
                 if (!renderTransparent) {
                     for (let i = 0, il = renderables.length; i < il; ++i) {
                         if (!renderables[i].state.colorOnly) {
-                            renderObject(renderables[i], variant, localSharedTexturesList);
+                            renderObject(renderables[i], variant);
                         }
                     }
                 }
diff --git a/src/mol-gl/webgl/program.ts b/src/mol-gl/webgl/program.ts
index 0fdfc6c2b83e4a3c81785412c0ed0ffc67c8de2e..fcf40dca8c20951fa830531758181285c44c0f57 100644
--- a/src/mol-gl/webgl/program.ts
+++ b/src/mol-gl/webgl/program.ts
@@ -205,8 +205,6 @@ export function createProgram(gl: GLRenderingContext, state: WebGLState, extensi
                 const [k, texture] = textures[i];
                 const l = locations[k];
                 if (l !== null && l !== undefined) {
-                    // TODO if the order and count of textures in a material can be made invariant
-                    //      bind needs to be called only when the material changes
                     texture.bind((i + startingTargetUnit) as TextureId);
                     uniformSetters[k](gl, l, (i + startingTargetUnit) as TextureId);
                 }
diff --git a/src/mol-gl/webgl/texture.ts b/src/mol-gl/webgl/texture.ts
index 3ccd3093cec7727c13e42966478edd75f2ba64a7..11eb2404657c148591954952e9145eaafc8824e0 100644
--- a/src/mol-gl/webgl/texture.ts
+++ b/src/mol-gl/webgl/texture.ts
@@ -312,4 +312,37 @@ export function createTextures(ctx: WebGLContext, schema: RenderableSchema, valu
         }
     });
     return textures;
+}
+
+//
+
+export function createNullTexture(gl: GLRenderingContext, kind: TextureKind): Texture {
+    const target = getTarget(gl, kind);
+    return {
+        id: getNextTextureId(),
+        target,
+        format: 0,
+        internalFormat: 0,
+        type: 0,
+
+        getWidth: () => 0,
+        getHeight: () => 0,
+        getDepth: () => 0,
+
+        define: () => {},
+        load: () => {},
+        bind: (id: TextureId) => {
+            gl.activeTexture(gl.TEXTURE0 + id);
+            gl.bindTexture(target, null);
+        },
+        unbind: (id: TextureId) => {
+            gl.activeTexture(gl.TEXTURE0 + id);
+            gl.bindTexture(target, null);
+        },
+        attachFramebuffer: () => {},
+        detachFramebuffer: () => {},
+
+        reset: () => {},
+        destroy: () => {},
+    };
 }
\ No newline at end of file
diff --git a/src/mol-util/array.ts b/src/mol-util/array.ts
index 16b1ded0ab0905bab17f89e2b2c6b297c557cdc3..7a3931e568551c19c646423a467b7fe1dc7ca5b6 100644
--- a/src/mol-util/array.ts
+++ b/src/mol-util/array.ts
@@ -122,4 +122,14 @@ export function arrayIsIdentity(xs: ArrayLike<number>) {
         if (xs[i] !== i) return false;
     }
     return true;
-}
\ No newline at end of file
+}
+
+export function arrayMapUpsert<T>(xs: [string, T][], key: string, value: T) {
+    for (let i = 0, il = xs.length; i < il; ++i) {
+        if (xs[i][0] === key) {
+            xs[i][1] = value;
+            return;
+        }
+    }
+    xs.push([key, value]);
+}